LLVM 24.0.0git
WebAssemblyExceptionInfo.cpp
Go to the documentation of this file.
1//===--- WebAssemblyExceptionInfo.cpp - Exception Infomation --------------===//
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/// \brief This file implements WebAssemblyException information analysis.
11///
12//===----------------------------------------------------------------------===//
13
21#include "llvm/IR/Analysis.h"
22#include "llvm/IR/Function.h"
24#include "llvm/MC/MCAsmInfo.h"
26
27using namespace llvm;
28
29#define DEBUG_TYPE "wasm-exception-info"
30
32
34 "WebAssembly Exception Information", true, true)
38 "WebAssembly Exception Information", true, true)
39
43 LLVM_DEBUG(dbgs() << "********** Exception Info Calculation **********\n"
44 "********** Function: "
45 << MF.getName() << '\n');
46 if (MF.getTarget().getMCAsmInfo().getExceptionHandlingType() !=
48 !MF.getFunction().hasPersonalityFn())
49 return;
50 MachineDominatorTree &MDT = GetMDT();
51 MachineDominanceFrontier &MDF = GetMDF();
52 WEI.recalculate(MF, MDT, MDF);
53}
54
56 MachineFunction &MF) {
59 WasmExceptionInfo, MF,
60 [&]() -> MachineDominatorTree & {
62 },
63 [&]() -> MachineDominanceFrontier & {
65 });
66 return false;
67}
68
74 WEI, MF,
75 [&]() -> MachineDominatorTree & {
77 },
78 [&]() -> MachineDominanceFrontier & {
80 });
81 return WEI;
82}
83
84AnalysisKey WebAssemblyExceptionAnalysis::Key;
85
88 const MachineDominanceFrontier &MDF) {
89 // Postorder traversal of the dominator tree.
91 for (auto *DomNode : post_order(&MDT)) {
92 MachineBasicBlock *EHPad = DomNode->getBlock();
93 if (!EHPad->isEHPad())
94 continue;
95 auto WE = std::make_unique<WebAssemblyException>(EHPad);
96 discoverAndMapException(WE.get(), MDT, MDF);
97 Exceptions.push_back(std::move(WE));
98 }
99
100 // Add BBs to exceptions' block set. This is a preparation to take out
101 // remaining incorect BBs from exceptions, because we need to iterate over BBs
102 // for each exception.
103 for (auto *DomNode : post_order(&MDT)) {
104 MachineBasicBlock *MBB = DomNode->getBlock();
106 for (; WE; WE = WE->getParentException())
107 WE->addToBlocksSet(MBB);
108 }
109
110 // Add BBs to exceptions' block vector
111 for (auto *DomNode : post_order(&MDT)) {
112 MachineBasicBlock *MBB = DomNode->getBlock();
114 for (; WE; WE = WE->getParentException())
116 }
117
119 ExceptionPointers.reserve(Exceptions.size());
120
121 // Add subexceptions to exceptions
122 for (auto &WE : Exceptions) {
123 ExceptionPointers.push_back(WE.get());
124 if (WE->getParentException())
125 WE->getParentException()->getSubExceptions().push_back(std::move(WE));
126 else
127 addTopLevelException(std::move(WE));
128 }
129
130 // For convenience, Blocks and SubExceptions are inserted in postorder.
131 // Reverse the lists.
132 for (auto *WE : ExceptionPointers) {
133 WE->reverseBlock();
134 std::reverse(WE->getSubExceptions().begin(), WE->getSubExceptions().end());
135 }
136}
137
139 BBMap.clear();
140 TopLevelExceptions.clear();
141}
142
150
151void WebAssemblyExceptionInfo::discoverAndMapException(
153 const MachineDominanceFrontier &MDF) {
154 unsigned NumBlocks = 0;
155 unsigned NumSubExceptions = 0;
156
157 // Map blocks that belong to a catchpad / cleanuppad
158 MachineBasicBlock *EHPad = WE->getEHPad();
160 WL.push_back(EHPad);
161 while (!WL.empty()) {
163
164 // Find its outermost discovered exception. If this is a discovered block,
165 // check if it is already discovered to be a subexception of this exception.
166 WebAssemblyException *SubE = getOutermostException(MBB);
167 if (SubE) {
168 if (SubE != WE) {
169 // Discover a subexception of this exception.
170 SubE->setParentException(WE);
171 ++NumSubExceptions;
172 NumBlocks += SubE->getBlocksVector().capacity();
173 // All blocks that belong to this subexception have been already
174 // discovered. Skip all of them. Add the subexception's landing pad's
175 // dominance frontier to the worklist.
176 for (auto &Frontier : MDF.find(SubE->getEHPad())->second)
177 if (MDT.dominates(EHPad, Frontier))
178 WL.push_back(Frontier);
179 }
180 continue;
181 }
182
183 // This is an undiscovered block. Map it to the current exception.
185 ++NumBlocks;
186
187 // Add successors dominated by the current BB to the worklist.
188 for (auto *Succ : MBB->successors())
189 if (MDT.dominates(EHPad, Succ))
190 WL.push_back(Succ);
191 }
192
193 WE->getSubExceptions().reserve(NumSubExceptions);
194 WE->reserveBlocks(NumBlocks);
195}
196
198WebAssemblyExceptionInfo::getOutermostException(MachineBasicBlock *MBB) const {
199 WebAssemblyException *WE = getExceptionFor(MBB);
200 if (WE) {
201 while (WebAssemblyException *Parent = WE->getParentException())
202 WE = Parent;
203 }
204 return WE;
205}
206
208 OS.indent(Depth * 2) << "Exception at depth " << getExceptionDepth()
209 << " containing: ";
210
211 for (unsigned I = 0; I < getBlocks().size(); ++I) {
213 if (I)
214 OS << ", ";
215 OS << "%bb." << MBB->getNumber();
216 if (const auto *BB = MBB->getBasicBlock())
217 if (BB->hasName())
218 OS << "." << BB->getName();
219
220 if (getEHPad() == MBB)
221 OS << " (landing-pad)";
222 }
223 OS << "\n";
224
225 for (auto &SubE : SubExceptions)
226 SubE->print(OS, Depth + 2);
227}
228
229#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
231#endif
232
234 WE.print(OS);
235 return OS;
236}
237
239 for (auto &WE : TopLevelExceptions)
240 WE->print(OS);
241}
242
244 MachineFunction &MF, const PreservedAnalyses &PA,
245 MachineFunctionAnalysisManager::Invalidator &) {
246 // Check whether the analysis, all analyses on machine functions, or the
247 // machine function's CFG have been preserved.
249 return !PAC.preserved() &&
250 !PAC.preservedSet<AllAnalysesOn<MachineFunction>>() &&
251 !PAC.preservedSet<CFGAnalyses>();
252}
MachineBasicBlock & MBB
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:672
#define DEBUG_TYPE
#define I(x, y, z)
Definition MD5.cpp:57
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
#define LLVM_DEBUG(...)
Definition Debug.h:119
WebAssembly Exception static true void computeWEI(WebAssemblyExceptionInfo &WEI, MachineFunction &MF, function_ref< MachineDominatorTree &()> GetMDT, function_ref< MachineDominanceFrontier &()> GetMDF)
This file implements WebAssemblyException information analysis.
This file contains the declaration of the WebAssembly-specific utility functions.
This templated class represents "all analyses that operate over <aparticular IR unit>" (e....
Definition Analysis.h:50
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
bool isEHPad() const
Returns true if the block is a landing pad.
iterator_range< succ_iterator > successors()
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
Definition Analysis.h:275
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
void changeExceptionFor(const MachineBasicBlock *MBB, WebAssemblyException *WE)
void addTopLevelException(std::unique_ptr< WebAssemblyException > WE)
void recalculate(MachineFunction &MF, MachineDominatorTree &MDT, const MachineDominanceFrontier &MDF)
void print(raw_ostream &OS, const Module *M) const
WebAssemblyException * getExceptionFor(const MachineBasicBlock *MBB) const
bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA, MachineFunctionAnalysisManager::Invalidator &)
void print(raw_ostream &OS, unsigned Depth=0) const
MachineBasicBlock * getEHPad() const
void addToBlocksSet(MachineBasicBlock *MBB)
const std::vector< std::unique_ptr< WebAssemblyException > > & getSubExceptions() const
ArrayRef< MachineBasicBlock * > getBlocks() const
std::vector< MachineBasicBlock * > & getBlocksVector()
WebAssemblyException * getParentException() const
void setParentException(WebAssemblyException *WE)
void addToBlocksVector(MachineBasicBlock *MBB)
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
Pass manager infrastructure for declaring and invalidating analyses.
This is an optimization pass for GlobalISel generic memory operations.
@ Wasm
WebAssembly Exception Handling.
Definition CodeGen.h:59
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
auto post_order(const T &G)
Post-order traversal of a graph.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29