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