1292915Sdim//===-- WebAssemblyOptimizeReturned.cpp - Optimize "returned" attributes --===// 2292915Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6292915Sdim// 7292915Sdim//===----------------------------------------------------------------------===// 8292915Sdim/// 9292915Sdim/// \file 10341825Sdim/// Optimize calls with "returned" attributes for WebAssembly. 11292915Sdim/// 12292915Sdim//===----------------------------------------------------------------------===// 13292915Sdim 14292915Sdim#include "WebAssembly.h" 15292915Sdim#include "llvm/IR/Dominators.h" 16292915Sdim#include "llvm/IR/InstVisitor.h" 17292915Sdim#include "llvm/Support/Debug.h" 18292915Sdim#include "llvm/Support/raw_ostream.h" 19292915Sdimusing namespace llvm; 20292915Sdim 21292915Sdim#define DEBUG_TYPE "wasm-optimize-returned" 22292915Sdim 23292915Sdimnamespace { 24292915Sdimclass OptimizeReturned final : public FunctionPass, 25292915Sdim public InstVisitor<OptimizeReturned> { 26314564Sdim StringRef getPassName() const override { 27292915Sdim return "WebAssembly Optimize Returned"; 28292915Sdim } 29292915Sdim 30292915Sdim void getAnalysisUsage(AnalysisUsage &AU) const override { 31292915Sdim AU.setPreservesCFG(); 32292915Sdim AU.addRequired<DominatorTreeWrapperPass>(); 33292915Sdim AU.addPreserved<DominatorTreeWrapperPass>(); 34292915Sdim FunctionPass::getAnalysisUsage(AU); 35292915Sdim } 36292915Sdim 37292915Sdim bool runOnFunction(Function &F) override; 38292915Sdim 39353358Sdim DominatorTree *DT = nullptr; 40292915Sdim 41292915Sdimpublic: 42292915Sdim static char ID; 43353358Sdim OptimizeReturned() : FunctionPass(ID) {} 44292915Sdim 45292915Sdim void visitCallSite(CallSite CS); 46292915Sdim}; 47292915Sdim} // End anonymous namespace 48292915Sdim 49292915Sdimchar OptimizeReturned::ID = 0; 50341825SdimINITIALIZE_PASS(OptimizeReturned, DEBUG_TYPE, 51341825Sdim "Optimize calls with \"returned\" attributes for WebAssembly", 52341825Sdim false, false) 53341825Sdim 54292915SdimFunctionPass *llvm::createWebAssemblyOptimizeReturned() { 55292915Sdim return new OptimizeReturned(); 56292915Sdim} 57292915Sdim 58292915Sdimvoid OptimizeReturned::visitCallSite(CallSite CS) { 59353358Sdim for (unsigned I = 0, E = CS.getNumArgOperands(); I < E; ++I) 60353358Sdim if (CS.paramHasAttr(I, Attribute::Returned)) { 61292915Sdim Instruction *Inst = CS.getInstruction(); 62353358Sdim Value *Arg = CS.getArgOperand(I); 63292915Sdim // Ignore constants, globals, undef, etc. 64292915Sdim if (isa<Constant>(Arg)) 65292915Sdim continue; 66292915Sdim // Like replaceDominatedUsesWith but using Instruction/Use dominance. 67360784Sdim Arg->replaceUsesWithIf(Inst, 68360784Sdim [&](Use &U) { return DT->dominates(Inst, U); }); 69292915Sdim } 70292915Sdim} 71292915Sdim 72292915Sdimbool OptimizeReturned::runOnFunction(Function &F) { 73344779Sdim LLVM_DEBUG(dbgs() << "********** Optimize returned Attributes **********\n" 74344779Sdim "********** Function: " 75344779Sdim << F.getName() << '\n'); 76344779Sdim 77292915Sdim DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 78292915Sdim visit(F); 79292915Sdim return true; 80292915Sdim} 81