WebAssemblyOptimizeReturned.cpp revision 360784
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