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" 19using namespace llvm; 20 21#define DEBUG_TYPE "wasm-optimize-returned" 22 23namespace { 24class 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 41public: 42 static char ID; 43 OptimizeReturned() : FunctionPass(ID) {} 44 45 void visitCallSite(CallSite CS); 46}; 47} // End anonymous namespace 48 49char OptimizeReturned::ID = 0; 50INITIALIZE_PASS(OptimizeReturned, DEBUG_TYPE, 51 "Optimize calls with \"returned\" attributes for WebAssembly", 52 false, false) 53 54FunctionPass *llvm::createWebAssemblyOptimizeReturned() { 55 return new OptimizeReturned(); 56} 57 58void 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 Arg->replaceUsesWithIf(Inst, 68 [&](Use &U) { return DT->dominates(Inst, U); }); 69 } 70} 71 72bool OptimizeReturned::runOnFunction(Function &F) { 73 LLVM_DEBUG(dbgs() << "********** Optimize returned Attributes **********\n" 74 "********** Function: " 75 << F.getName() << '\n'); 76 77 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 78 visit(F); 79 return true; 80} 81