181719f85SDan Gohman //===-- WebAssemblyOptimizeReturned.cpp - Optimize "returned" attributes --===//
281719f85SDan Gohman //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681719f85SDan Gohman //
781719f85SDan Gohman //===----------------------------------------------------------------------===//
881719f85SDan Gohman ///
981719f85SDan Gohman /// \file
105f8f34e4SAdrian Prantl /// Optimize calls with "returned" attributes for WebAssembly.
1181719f85SDan Gohman ///
1281719f85SDan Gohman //===----------------------------------------------------------------------===//
1381719f85SDan Gohman 
1481719f85SDan Gohman #include "WebAssembly.h"
1581719f85SDan Gohman #include "llvm/IR/Dominators.h"
1681719f85SDan Gohman #include "llvm/IR/InstVisitor.h"
1781719f85SDan Gohman #include "llvm/Support/Debug.h"
1881719f85SDan Gohman #include "llvm/Support/raw_ostream.h"
1981719f85SDan Gohman using namespace llvm;
2081719f85SDan Gohman 
2181719f85SDan Gohman #define DEBUG_TYPE "wasm-optimize-returned"
2281719f85SDan Gohman 
2381719f85SDan Gohman namespace {
2481719f85SDan Gohman class OptimizeReturned final : public FunctionPass,
2581719f85SDan Gohman                                public InstVisitor<OptimizeReturned> {
getPassName() const26117296c0SMehdi Amini   StringRef getPassName() const override {
2781719f85SDan Gohman     return "WebAssembly Optimize Returned";
2881719f85SDan Gohman   }
2981719f85SDan Gohman 
getAnalysisUsage(AnalysisUsage & AU) const3081719f85SDan Gohman   void getAnalysisUsage(AnalysisUsage &AU) const override {
3181719f85SDan Gohman     AU.setPreservesCFG();
3281719f85SDan Gohman     AU.addRequired<DominatorTreeWrapperPass>();
3381719f85SDan Gohman     AU.addPreserved<DominatorTreeWrapperPass>();
3481719f85SDan Gohman     FunctionPass::getAnalysisUsage(AU);
3581719f85SDan Gohman   }
3681719f85SDan Gohman 
3781719f85SDan Gohman   bool runOnFunction(Function &F) override;
3881719f85SDan Gohman 
3918c56a07SHeejin Ahn   DominatorTree *DT = nullptr;
4081719f85SDan Gohman 
4181719f85SDan Gohman public:
4281719f85SDan Gohman   static char ID;
OptimizeReturned()4318c56a07SHeejin Ahn   OptimizeReturned() : FunctionPass(ID) {}
4481719f85SDan Gohman 
454ecc8fb7SCraig Topper   void visitCallBase(CallBase &CB);
4681719f85SDan Gohman };
4781719f85SDan Gohman } // End anonymous namespace
4881719f85SDan Gohman 
4981719f85SDan Gohman char OptimizeReturned::ID = 0;
5040926451SJacob Gravelle INITIALIZE_PASS(OptimizeReturned, DEBUG_TYPE,
5140926451SJacob Gravelle                 "Optimize calls with \"returned\" attributes for WebAssembly",
5240926451SJacob Gravelle                 false, false)
5340926451SJacob Gravelle 
createWebAssemblyOptimizeReturned()5481719f85SDan Gohman FunctionPass *llvm::createWebAssemblyOptimizeReturned() {
5581719f85SDan Gohman   return new OptimizeReturned();
5681719f85SDan Gohman }
5781719f85SDan Gohman 
visitCallBase(CallBase & CB)584ecc8fb7SCraig Topper void OptimizeReturned::visitCallBase(CallBase &CB) {
59*c1e32b3fSKazu Hirata   for (unsigned I = 0, E = CB.arg_size(); I < E; ++I)
604ecc8fb7SCraig Topper     if (CB.paramHasAttr(I, Attribute::Returned)) {
614ecc8fb7SCraig Topper       Value *Arg = CB.getArgOperand(I);
62d85c3b1fSDan Gohman       // Ignore constants, globals, undef, etc.
63d85c3b1fSDan Gohman       if (isa<Constant>(Arg))
64d85c3b1fSDan Gohman         continue;
6581719f85SDan Gohman       // Like replaceDominatedUsesWith but using Instruction/Use dominance.
664ecc8fb7SCraig Topper       Arg->replaceUsesWithIf(&CB,
674ecc8fb7SCraig Topper                              [&](Use &U) { return DT->dominates(&CB, U); });
6881719f85SDan Gohman     }
6981719f85SDan Gohman }
7081719f85SDan Gohman 
runOnFunction(Function & F)7181719f85SDan Gohman bool OptimizeReturned::runOnFunction(Function &F) {
72569f0909SHeejin Ahn   LLVM_DEBUG(dbgs() << "********** Optimize returned Attributes **********\n"
73569f0909SHeejin Ahn                        "********** Function: "
74569f0909SHeejin Ahn                     << F.getName() << '\n');
75569f0909SHeejin Ahn 
7681719f85SDan Gohman   DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
7781719f85SDan Gohman   visit(F);
7881719f85SDan Gohman   return true;
7981719f85SDan Gohman }
80