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" 20using namespace llvm; 21 22#define DEBUG_TYPE "wasm-optimize-returned" 23 24namespace { 25class OptimizeReturned final : public FunctionPass, 26 public InstVisitor<OptimizeReturned> { 27 const char *getPassName() const override { 28 return "WebAssembly Optimize Returned"; 29 } 30 31 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 42public: 43 static char ID; 44 OptimizeReturned() : FunctionPass(ID), DT(nullptr) {} 45 46 void visitCallSite(CallSite CS); 47}; 48} // End anonymous namespace 49 50char OptimizeReturned::ID = 0; 51FunctionPass *llvm::createWebAssemblyOptimizeReturned() { 52 return new OptimizeReturned(); 53} 54 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 72bool OptimizeReturned::runOnFunction(Function &F) { 73 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 74 visit(F); 75 return true; 76} 77