Line data Source code
1 : //===-- WebAssemblyOptimizeReturned.cpp - Optimize "returned" attributes --===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : ///
10 : /// \file
11 : /// Optimize calls with "returned" attributes for WebAssembly.
12 : ///
13 : //===----------------------------------------------------------------------===//
14 :
15 : #include "WebAssembly.h"
16 : #include "llvm/IR/Dominators.h"
17 : #include "llvm/IR/InstVisitor.h"
18 : #include "llvm/Support/Debug.h"
19 : #include "llvm/Support/raw_ostream.h"
20 : using namespace llvm;
21 :
22 : #define DEBUG_TYPE "wasm-optimize-returned"
23 :
24 : namespace {
25 : class OptimizeReturned final : public FunctionPass,
26 : public InstVisitor<OptimizeReturned> {
27 0 : StringRef getPassName() const override {
28 0 : return "WebAssembly Optimize Returned";
29 : }
30 :
31 298 : void getAnalysisUsage(AnalysisUsage &AU) const override {
32 298 : AU.setPreservesCFG();
33 : AU.addRequired<DominatorTreeWrapperPass>();
34 : AU.addPreserved<DominatorTreeWrapperPass>();
35 298 : FunctionPass::getAnalysisUsage(AU);
36 298 : }
37 :
38 : bool runOnFunction(Function &F) override;
39 :
40 : DominatorTree *DT;
41 :
42 : public:
43 : static char ID;
44 596 : OptimizeReturned() : FunctionPass(ID), DT(nullptr) {}
45 :
46 : void visitCallSite(CallSite CS);
47 : };
48 : } // End anonymous namespace
49 :
50 : char OptimizeReturned::ID = 0;
51 199030 : INITIALIZE_PASS(OptimizeReturned, DEBUG_TYPE,
52 : "Optimize calls with \"returned\" attributes for WebAssembly",
53 : false, false)
54 :
55 298 : FunctionPass *llvm::createWebAssemblyOptimizeReturned() {
56 298 : return new OptimizeReturned();
57 : }
58 :
59 0 : void OptimizeReturned::visitCallSite(CallSite CS) {
60 0 : for (unsigned i = 0, e = CS.getNumArgOperands(); i < e; ++i)
61 0 : if (CS.paramHasAttr(i, Attribute::Returned)) {
62 : Instruction *Inst = CS.getInstruction();
63 0 : Value *Arg = CS.getArgOperand(i);
64 : // Ignore constants, globals, undef, etc.
65 0 : if (isa<Constant>(Arg))
66 : continue;
67 : // Like replaceDominatedUsesWith but using Instruction/Use dominance.
68 0 : for (auto UI = Arg->use_begin(), UE = Arg->use_end(); UI != UE;) {
69 : Use &U = *UI++;
70 0 : if (DT->dominates(Inst, U))
71 0 : U.set(Inst);
72 : }
73 : }
74 0 : }
75 :
76 3167 : bool OptimizeReturned::runOnFunction(Function &F) {
77 3167 : DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
78 : visit(F);
79 3167 : return true;
80 : }
|