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()51FunctionPass *llvm::createWebAssemblyOptimizeReturned() { 52 return new OptimizeReturned(); 53 } 54 visitCallSite(CallSite CS)55void 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)72bool OptimizeReturned::runOnFunction(Function &F) { 73 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 74 visit(F); 75 return true; 76 } 77