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