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.arg_size(); I < E; ++I) |
60 | if (CB.paramHasAttr(ArgNo: I, Kind: Attribute::Returned)) { |
61 | Value *Arg = CB.getArgOperand(i: I); |
62 | // Ignore constants, globals, undef, etc. |
63 | if (isa<Constant>(Val: Arg)) |
64 | continue; |
65 | // Like replaceDominatedUsesWith but using Instruction/Use dominance. |
66 | Arg->replaceUsesWithIf(New: &CB, |
67 | ShouldReplace: [&](Use &U) { return DT->dominates(Def: &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 | |