1f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===-- WebAssemblyOptimizeReturned.cpp - Optimize "returned" attributes --===//
2f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
3f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//                     The LLVM Compiler Infrastructure
4f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
5f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source
6f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// License. See LICENSE.TXT for details.
7f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
8f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===----------------------------------------------------------------------===//
9f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar///
10f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// \file
11f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// \brief Optimize calls with "returned" attributes for WebAssembly.
12f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar///
13f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===----------------------------------------------------------------------===//
14f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
15f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "WebAssembly.h"
16f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/IR/Dominators.h"
17f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/IR/InstVisitor.h"
18f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Support/Debug.h"
19f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Support/raw_ostream.h"
20f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarusing namespace llvm;
21f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
22f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#define DEBUG_TYPE "wasm-optimize-returned"
23f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
24f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace {
25f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarclass OptimizeReturned final : public FunctionPass,
26f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                               public InstVisitor<OptimizeReturned> {
27f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const char *getPassName() const override {
28f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return "WebAssembly Optimize Returned";
29f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
30f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
31f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void getAnalysisUsage(AnalysisUsage &AU) const override {
32f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    AU.setPreservesCFG();
33f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    AU.addRequired<DominatorTreeWrapperPass>();
34f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    AU.addPreserved<DominatorTreeWrapperPass>();
35f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    FunctionPass::getAnalysisUsage(AU);
36f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
37f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
38f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool runOnFunction(Function &F) override;
39f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
40f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DominatorTree *DT;
41f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
42f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarpublic:
43f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  static char ID;
44f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  OptimizeReturned() : FunctionPass(ID), DT(nullptr) {}
45f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
46f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void visitCallSite(CallSite CS);
47f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar};
48f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} // End anonymous namespace
49f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
50f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarchar OptimizeReturned::ID = 0;
51f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarFunctionPass *llvm::createWebAssemblyOptimizeReturned() {
52f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return new OptimizeReturned();
53f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
54f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
55f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid OptimizeReturned::visitCallSite(CallSite CS) {
56f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = 0, e = CS.getNumArgOperands(); i < e; ++i)
57f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (CS.paramHasAttr(1 + i, Attribute::Returned)) {
58f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Instruction *Inst = CS.getInstruction();
59f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Value *Arg = CS.getArgOperand(i);
60f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Ignore constants, globals, undef, etc.
61f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (isa<Constant>(Arg))
62f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
63f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Like replaceDominatedUsesWith but using Instruction/Use dominance.
64f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      for (auto UI = Arg->use_begin(), UE = Arg->use_end(); UI != UE;) {
65f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Use &U = *UI++;
66f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        if (DT->dominates(Inst, U))
67f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          U.set(Inst);
68f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
69f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
70f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
71f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
72f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool OptimizeReturned::runOnFunction(Function &F) {
73f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
74f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  visit(F);
75f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
76f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
77