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