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 visitCallBase(CallBase &CB); 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::visitCallBase(CallBase &CB) { 59 for (unsigned I = 0, E = CB.arg_size(); I < E; ++I) 60 if (CB.paramHasAttr(I, Attribute::Returned)) { 61 Value *Arg = CB.getArgOperand(I); 62 // Ignore constants, globals, undef, etc. 63 if (isa<Constant>(Arg)) 64 continue; 65 // Like replaceDominatedUsesWith but using Instruction/Use dominance. 66 Arg->replaceUsesWithIf(&CB, 67 [&](Use &U) { return DT->dominates(&CB, U); }); 68 } 69 } 70 71 bool OptimizeReturned::runOnFunction(Function &F) { 72 LLVM_DEBUG(dbgs() << "********** Optimize returned Attributes **********\n" 73 "********** Function: " 74 << F.getName() << '\n'); 75 76 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 77 visit(F); 78 return true; 79 } 80