WebAssemblyOptimizeReturned.cpp revision 314564
1292915Sdim//===-- WebAssemblyOptimizeReturned.cpp - Optimize "returned" attributes --===// 2292915Sdim// 3292915Sdim// The LLVM Compiler Infrastructure 4292915Sdim// 5292915Sdim// This file is distributed under the University of Illinois Open Source 6292915Sdim// License. See LICENSE.TXT for details. 7292915Sdim// 8292915Sdim//===----------------------------------------------------------------------===// 9292915Sdim/// 10292915Sdim/// \file 11292915Sdim/// \brief Optimize calls with "returned" attributes for WebAssembly. 12292915Sdim/// 13292915Sdim//===----------------------------------------------------------------------===// 14292915Sdim 15292915Sdim#include "WebAssembly.h" 16292915Sdim#include "llvm/IR/Dominators.h" 17292915Sdim#include "llvm/IR/InstVisitor.h" 18292915Sdim#include "llvm/Support/Debug.h" 19292915Sdim#include "llvm/Support/raw_ostream.h" 20292915Sdimusing namespace llvm; 21292915Sdim 22292915Sdim#define DEBUG_TYPE "wasm-optimize-returned" 23292915Sdim 24292915Sdimnamespace { 25292915Sdimclass OptimizeReturned final : public FunctionPass, 26292915Sdim public InstVisitor<OptimizeReturned> { 27314564Sdim StringRef getPassName() const override { 28292915Sdim return "WebAssembly Optimize Returned"; 29292915Sdim } 30292915Sdim 31292915Sdim void getAnalysisUsage(AnalysisUsage &AU) const override { 32292915Sdim AU.setPreservesCFG(); 33292915Sdim AU.addRequired<DominatorTreeWrapperPass>(); 34292915Sdim AU.addPreserved<DominatorTreeWrapperPass>(); 35292915Sdim FunctionPass::getAnalysisUsage(AU); 36292915Sdim } 37292915Sdim 38292915Sdim bool runOnFunction(Function &F) override; 39292915Sdim 40292915Sdim DominatorTree *DT; 41292915Sdim 42292915Sdimpublic: 43292915Sdim static char ID; 44292915Sdim OptimizeReturned() : FunctionPass(ID), DT(nullptr) {} 45292915Sdim 46292915Sdim void visitCallSite(CallSite CS); 47292915Sdim}; 48292915Sdim} // End anonymous namespace 49292915Sdim 50292915Sdimchar OptimizeReturned::ID = 0; 51292915SdimFunctionPass *llvm::createWebAssemblyOptimizeReturned() { 52292915Sdim return new OptimizeReturned(); 53292915Sdim} 54292915Sdim 55292915Sdimvoid OptimizeReturned::visitCallSite(CallSite CS) { 56292915Sdim for (unsigned i = 0, e = CS.getNumArgOperands(); i < e; ++i) 57292915Sdim if (CS.paramHasAttr(1 + i, Attribute::Returned)) { 58292915Sdim Instruction *Inst = CS.getInstruction(); 59292915Sdim Value *Arg = CS.getArgOperand(i); 60292915Sdim // Ignore constants, globals, undef, etc. 61292915Sdim if (isa<Constant>(Arg)) 62292915Sdim continue; 63292915Sdim // Like replaceDominatedUsesWith but using Instruction/Use dominance. 64292915Sdim for (auto UI = Arg->use_begin(), UE = Arg->use_end(); UI != UE;) { 65292915Sdim Use &U = *UI++; 66292915Sdim if (DT->dominates(Inst, U)) 67292915Sdim U.set(Inst); 68292915Sdim } 69292915Sdim } 70292915Sdim} 71292915Sdim 72292915Sdimbool OptimizeReturned::runOnFunction(Function &F) { 73292915Sdim DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 74292915Sdim visit(F); 75292915Sdim return true; 76292915Sdim} 77