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