Home | History | Annotate | Download | only in WebAssembly
      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"
     20 using namespace llvm;
     21 
     22 #define DEBUG_TYPE "wasm-optimize-returned"
     23 
     24 namespace {
     25 class 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 
     42 public:
     43   static char ID;
     44   OptimizeReturned() : FunctionPass(ID), DT(nullptr) {}
     45 
     46   void visitCallSite(CallSite CS);
     47 };
     48 } // End anonymous namespace
     49 
     50 char OptimizeReturned::ID = 0;
     51 FunctionPass *llvm::createWebAssemblyOptimizeReturned() {
     52   return new OptimizeReturned();
     53 }
     54 
     55 void 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 
     72 bool OptimizeReturned::runOnFunction(Function &F) {
     73   DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
     74   visit(F);
     75   return true;
     76 }
     77