Home | History | Annotate | Line # | Download | only in WebAssembly
      1 //===-- WebAssemblyOptimizeReturned.cpp - Optimize "returned" attributes --===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 ///
      9 /// \file
     10 /// Optimize calls with "returned" attributes for WebAssembly.
     11 ///
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "WebAssembly.h"
     15 #include "llvm/IR/Dominators.h"
     16 #include "llvm/IR/InstVisitor.h"
     17 #include "llvm/Support/Debug.h"
     18 #include "llvm/Support/raw_ostream.h"
     19 using namespace llvm;
     20 
     21 #define DEBUG_TYPE "wasm-optimize-returned"
     22 
     23 namespace {
     24 class OptimizeReturned final : public FunctionPass,
     25                                public InstVisitor<OptimizeReturned> {
     26   StringRef getPassName() const override {
     27     return "WebAssembly Optimize Returned";
     28   }
     29 
     30   void getAnalysisUsage(AnalysisUsage &AU) const override {
     31     AU.setPreservesCFG();
     32     AU.addRequired<DominatorTreeWrapperPass>();
     33     AU.addPreserved<DominatorTreeWrapperPass>();
     34     FunctionPass::getAnalysisUsage(AU);
     35   }
     36 
     37   bool runOnFunction(Function &F) override;
     38 
     39   DominatorTree *DT = nullptr;
     40 
     41 public:
     42   static char ID;
     43   OptimizeReturned() : FunctionPass(ID) {}
     44 
     45   void visitCallBase(CallBase &CB);
     46 };
     47 } // End anonymous namespace
     48 
     49 char OptimizeReturned::ID = 0;
     50 INITIALIZE_PASS(OptimizeReturned, DEBUG_TYPE,
     51                 "Optimize calls with \"returned\" attributes for WebAssembly",
     52                 false, false)
     53 
     54 FunctionPass *llvm::createWebAssemblyOptimizeReturned() {
     55   return new OptimizeReturned();
     56 }
     57 
     58 void OptimizeReturned::visitCallBase(CallBase &CB) {
     59   for (unsigned I = 0, E = CB.getNumArgOperands(); I < E; ++I)
     60     if (CB.paramHasAttr(I, Attribute::Returned)) {
     61       Value *Arg = CB.getArgOperand(I);
     62       // Ignore constants, globals, undef, etc.
     63       if (isa<Constant>(Arg))
     64         continue;
     65       // Like replaceDominatedUsesWith but using Instruction/Use dominance.
     66       Arg->replaceUsesWithIf(&CB,
     67                              [&](Use &U) { return DT->dominates(&CB, U); });
     68     }
     69 }
     70 
     71 bool OptimizeReturned::runOnFunction(Function &F) {
     72   LLVM_DEBUG(dbgs() << "********** Optimize returned Attributes **********\n"
     73                        "********** Function: "
     74                     << F.getName() << '\n');
     75 
     76   DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
     77   visit(F);
     78   return true;
     79 }
     80