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> {
getPassName() const27 StringRef getPassName() const override {
28 return "WebAssembly Optimize Returned";
29 }
30
getAnalysisUsage(AnalysisUsage & AU) const31 void getAnalysisUsage(AnalysisUsage &AU) const override {
32 AU.setPreservesCFG();
33 AU.addRequired<DominatorTreeWrapperPass>();
34 AU.addPreserved<DominatorTreeWrapperPass>();
35 FunctionPass::getAnalysisUsage(AU);
36 }
37
38 bool runOnFunction(Function &F) override;
39
40 DominatorTree *DT;
41
42 public:
43 static char ID;
OptimizeReturned()44 OptimizeReturned() : FunctionPass(ID), DT(nullptr) {}
45
46 void visitCallSite(CallSite CS);
47 };
48 } // End anonymous namespace
49
50 char OptimizeReturned::ID = 0;
51 INITIALIZE_PASS(OptimizeReturned, DEBUG_TYPE,
52 "Optimize calls with \"returned\" attributes for WebAssembly",
53 false, false)
54
createWebAssemblyOptimizeReturned()55 FunctionPass *llvm::createWebAssemblyOptimizeReturned() {
56 return new OptimizeReturned();
57 }
58
visitCallSite(CallSite CS)59 void OptimizeReturned::visitCallSite(CallSite CS) {
60 for (unsigned i = 0, e = CS.getNumArgOperands(); i < e; ++i)
61 if (CS.paramHasAttr(i, Attribute::Returned)) {
62 Instruction *Inst = CS.getInstruction();
63 Value *Arg = CS.getArgOperand(i);
64 // Ignore constants, globals, undef, etc.
65 if (isa<Constant>(Arg))
66 continue;
67 // Like replaceDominatedUsesWith but using Instruction/Use dominance.
68 for (auto UI = Arg->use_begin(), UE = Arg->use_end(); UI != UE;) {
69 Use &U = *UI++;
70 if (DT->dominates(Inst, U))
71 U.set(Inst);
72 }
73 }
74 }
75
runOnFunction(Function & F)76 bool OptimizeReturned::runOnFunction(Function &F) {
77 LLVM_DEBUG(dbgs() << "********** Optimize returned Attributes **********\n"
78 "********** Function: "
79 << F.getName() << '\n');
80
81 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
82 visit(F);
83 return true;
84 }
85