• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /// \brief 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   const char *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;
createWebAssemblyOptimizeReturned()51 FunctionPass *llvm::createWebAssemblyOptimizeReturned() {
52   return new OptimizeReturned();
53 }
54 
visitCallSite(CallSite CS)55 void OptimizeReturned::visitCallSite(CallSite CS) {
56   for (unsigned i = 0, e = CS.getNumArgOperands(); i < e; ++i)
57     if (CS.paramHasAttr(1 + i, Attribute::Returned)) {
58       Instruction *Inst = CS.getInstruction();
59       Value *Arg = CS.getArgOperand(i);
60       // Ignore constants, globals, undef, etc.
61       if (isa<Constant>(Arg))
62         continue;
63       // Like replaceDominatedUsesWith but using Instruction/Use dominance.
64       for (auto UI = Arg->use_begin(), UE = Arg->use_end(); UI != UE;) {
65         Use &U = *UI++;
66         if (DT->dominates(Inst, U))
67           U.set(Inst);
68       }
69     }
70 }
71 
runOnFunction(Function & F)72 bool OptimizeReturned::runOnFunction(Function &F) {
73   DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
74   visit(F);
75   return true;
76 }
77