82 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// 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 visitCallBase(CallBase &CB);46};47} // End anonymous namespace48 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::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, [&](Use &U) {67 auto *I = cast<Instruction>(U.getUser());68 return !I->isLifetimeStartOrEnd() && DT->dominates(&CB, U);69 });70 }71}72 73bool OptimizeReturned::runOnFunction(Function &F) {74 LLVM_DEBUG(dbgs() << "********** Optimize returned Attributes **********\n"75 "********** Function: "76 << F.getName() << '\n');77 78 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();79 visit(F);80 return true;81}82