WebAssemblyOptimizeReturned.cpp revision 341825
1228753Smm//===-- WebAssemblyOptimizeReturned.cpp - Optimize "returned" attributes --===//
2228753Smm//
3228753Smm//                     The LLVM Compiler Infrastructure
4228753Smm//
5228753Smm// This file is distributed under the University of Illinois Open Source
6228753Smm// License. See LICENSE.TXT for details.
7228753Smm//
8228753Smm//===----------------------------------------------------------------------===//
9228753Smm///
10228753Smm/// \file
11228753Smm/// Optimize calls with "returned" attributes for WebAssembly.
12228753Smm///
13228753Smm//===----------------------------------------------------------------------===//
14228753Smm
15228753Smm#include "WebAssembly.h"
16228753Smm#include "llvm/IR/Dominators.h"
17228753Smm#include "llvm/IR/InstVisitor.h"
18228753Smm#include "llvm/Support/Debug.h"
19228753Smm#include "llvm/Support/raw_ostream.h"
20228753Smmusing namespace llvm;
21228753Smm
22228753Smm#define DEBUG_TYPE "wasm-optimize-returned"
23228753Smm
24228753Smmnamespace {
25228753Smmclass OptimizeReturned final : public FunctionPass,
26228753Smm                               public InstVisitor<OptimizeReturned> {
27228753Smm  StringRef getPassName() const override {
28228753Smm    return "WebAssembly Optimize Returned";
29228753Smm  }
30228753Smm
31228753Smm  void getAnalysisUsage(AnalysisUsage &AU) const override {
32228753Smm    AU.setPreservesCFG();
33228753Smm    AU.addRequired<DominatorTreeWrapperPass>();
34228753Smm    AU.addPreserved<DominatorTreeWrapperPass>();
35228753Smm    FunctionPass::getAnalysisUsage(AU);
36228753Smm  }
37228753Smm
38228753Smm  bool runOnFunction(Function &F) override;
39228753Smm
40228753Smm  DominatorTree *DT;
41228753Smm
42228753Smmpublic:
43228753Smm  static char ID;
44228753Smm  OptimizeReturned() : FunctionPass(ID), DT(nullptr) {}
45228753Smm
46228753Smm  void visitCallSite(CallSite CS);
47228753Smm};
48228753Smm} // End anonymous namespace
49228753Smm
50228753Smmchar OptimizeReturned::ID = 0;
51228753SmmINITIALIZE_PASS(OptimizeReturned, DEBUG_TYPE,
52228753Smm                "Optimize calls with \"returned\" attributes for WebAssembly",
53228753Smm                false, false)
54228753Smm
55228753SmmFunctionPass *llvm::createWebAssemblyOptimizeReturned() {
56228753Smm  return new OptimizeReturned();
57228753Smm}
58228753Smm
59228753Smmvoid OptimizeReturned::visitCallSite(CallSite CS) {
60228753Smm  for (unsigned i = 0, e = CS.getNumArgOperands(); i < e; ++i)
61228753Smm    if (CS.paramHasAttr(i, Attribute::Returned)) {
62228753Smm      Instruction *Inst = CS.getInstruction();
63228753Smm      Value *Arg = CS.getArgOperand(i);
64228753Smm      // Ignore constants, globals, undef, etc.
65228753Smm      if (isa<Constant>(Arg))
66228753Smm        continue;
67228753Smm      // Like replaceDominatedUsesWith but using Instruction/Use dominance.
68228753Smm      for (auto UI = Arg->use_begin(), UE = Arg->use_end(); UI != UE;) {
69228753Smm        Use &U = *UI++;
70228753Smm        if (DT->dominates(Inst, U))
71228753Smm          U.set(Inst);
72228753Smm      }
73228753Smm    }
74228753Smm}
75228753Smm
76228753Smmbool OptimizeReturned::runOnFunction(Function &F) {
77228753Smm  DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
78228753Smm  visit(F);
79228753Smm  return true;
80228753Smm}
81228753Smm