LLVM: lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
25
26using namespace llvm;
27
28#define DEBUG_TYPE "wasm-exception-info"
29
31
33 "WebAssembly Exception Information", true, true)
37 "WebAssembly Exception Information", true, true)
38
40 LLVM_DEBUG(dbgs() << "********** Exception Info Calculation **********\n"
41 "********** Function: "
42 << MF.getName() << '\n');
44 if (MF.getTarget().getMCAsmInfo()->getExceptionHandlingType() !=
46 !MF.getFunction().hasPersonalityFn())
47 return false;
52 return false;
53}
54
55
56
65
66 while (!WL.empty()) {
68 if (MBB == Dst)
69 return true;
71 for (auto *Succ : MBB->successors())
72 if (!Visited.count(Succ) && MDT.dominates(Header, Succ))
74 }
75 return false;
76}
77
81
83 for (auto *DomNode : post_order(&MDT)) {
86 continue;
87 auto WE = std::make_unique(EHPad);
88 discoverAndMapException(WE.get(), MDT, MDF);
89 Exceptions.push_back(std::move(WE));
90 }
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
126 UnwindWEVec;
127 for (auto *DomNode : depth_first(&MDT)) {
130 continue;
131 if (!EHInfo->hasUnwindDest(EHPad))
132 continue;
133 auto *UnwindDest = EHInfo->getUnwindDest(EHPad);
136 if (SrcWE->contains(DstWE)) {
137 UnwindWEVec.push_back(std::make_pair(SrcWE, DstWE));
138 LLVM_DEBUG(dbgs() << "Unwind destination ExceptionInfo fix:\n "
139 << DstWE->getEHPad()->getNumber() << "."
140 << DstWE->getEHPad()->getName()
141 << "'s exception is taken out of "
142 << SrcWE->getEHPad()->getNumber() << "."
143 << SrcWE->getEHPad()->getName() << "'s exception\n");
144 DstWE->setParentException(SrcWE->getParentException());
145 }
146 }
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166 for (auto *DomNode : depth_first(&MDT)) {
169 continue;
171
172
173 for (auto &P : UnwindWEVec) {
174 auto *SrcWE = P.first;
175 auto *DstWE = P.second;
176
177
178
179 if (WE != SrcWE && SrcWE->contains(WE) && !DstWE->contains(WE) &&
181 MDT)) {
182 LLVM_DEBUG(dbgs() << "Remaining reachable ExceptionInfo fix:\n "
183 << WE->getEHPad()->getNumber() << "."
184 << WE->getEHPad()->getName()
185 << "'s exception is taken out of "
186 << SrcWE->getEHPad()->getNumber() << "."
187 << SrcWE->getEHPad()->getName() << "'s exception\n");
188 WE->setParentException(SrcWE->getParentException());
189 }
190 }
191 }
192
193
194
195
196 for (auto *DomNode : post_order(&MDT)) {
201 }
202
203
204
205
206 for (auto &P : UnwindWEVec) {
207 auto *SrcWE = P.first;
208 auto *DstWE = P.second;
209
211 if (MBB->isEHPad()) {
213 SrcWE->getEHPad(), MDT) &&
214 "We already handled EH pads above");
215 return false;
216 }
218 MDT)) {
220 << MBB->getName() << " is\n");
222 while (InnerWE != SrcWE) {
226 << "'s exception\n");
229 }
230 LLVM_DEBUG(dbgs() << " removed from " << SrcWE->getEHPad()->getNumber()
231 << "." << SrcWE->getEHPad()->getName()
232 << "'s exception\n");
234 if (SrcWE->getParentException())
235 SrcWE->getParentException()->addToBlocksSet(MBB);
236 return true;
237 }
238 return false;
239 });
240 }
241
242
243 for (auto *DomNode : post_order(&MDT)) {
248 }
249
251 ExceptionPointers.reserve(Exceptions.size());
252
253
254 for (auto &WE : Exceptions) {
255 ExceptionPointers.push_back(WE.get());
256 if (WE->getParentException())
257 WE->getParentException()->getSubExceptions().push_back(std::move(WE));
258 else
260 }
261
262
263
264 for (auto *WE : ExceptionPointers) {
265 WE->reverseBlock();
266 std::reverse(WE->getSubExceptions().begin(), WE->getSubExceptions().end());
267 }
268}
269
271 BBMap.clear();
272 TopLevelExceptions.clear();
273}
274
281
282void WebAssemblyExceptionInfo::discoverAndMapException(
285 unsigned NumBlocks = 0;
286 unsigned NumSubExceptions = 0;
287
288
292 while (!WL.empty()) {
294
295
296
298 if (SubE) {
299 if (SubE != WE) {
300
302 ++NumSubExceptions;
304
305
306
307 for (auto &Frontier : MDF.find(SubE->getEHPad())->second)
308 if (MDT.dominates(EHPad, Frontier))
310 }
311 continue;
312 }
313
314
316 ++NumBlocks;
317
318
322 }
323
326}
327
329WebAssemblyExceptionInfo::getOutermostException(MachineBasicBlock *MBB) const {
331 if (WE) {
333 WE = Parent;
334 }
335 return WE;
336}
337
340 << " containing: ";
341
342 for (unsigned I = 0; I < getBlocks().size(); ++I) {
344 if (I)
345 OS << ", ";
346 OS << "%bb." << MBB->getNumber();
347 if (const auto *BB = MBB->getBasicBlock())
348 if (BB->hasName())
349 OS << "." << BB->getName();
350
352 OS << " (landing-pad)";
353 }
354 OS << "\n";
355
356 for (auto &SubE : SubExceptions)
358}
359
360#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
362#endif
363
368
370 for (auto &WE : TopLevelExceptions)
372}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
static bool isReachableAmongDominated(const MachineBasicBlock *Src, const MachineBasicBlock *Dst, const MachineBasicBlock *Header, const MachineDominatorTree &MDT)
Definition WebAssemblyExceptionInfo.cpp:57
This file implements WebAssemblyException information analysis.
This file contains the declaration of the WebAssembly-specific utility functions.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
bool isEHPad() const
Returns true if the block is a landing pad.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
iterator_range< succ_iterator > successors()
LLVM_ABI StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
iterator find(MachineBasicBlock *B)
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.
const WasmEHFuncInfo * getWasmEHFuncInfo() const
getWasmEHFuncInfo - Return information about how the current function uses Wasm exception handling.
A Module instance is used to store all the information related to an LLVM module.
AnalysisType & getAnalysis() const
getAnalysis() - This function is used by subclasses to get to the analysis information ...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
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.
WebAssemblyExceptionInfo()
void changeExceptionFor(const MachineBasicBlock *MBB, WebAssemblyException *WE)
bool runOnMachineFunction(MachineFunction &) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition WebAssemblyExceptionInfo.cpp:39
void addTopLevelException(std::unique_ptr< WebAssemblyException > WE)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition WebAssemblyExceptionInfo.cpp:275
void recalculate(MachineFunction &MF, MachineDominatorTree &MDT, const MachineDominanceFrontier &MDF)
Definition WebAssemblyExceptionInfo.cpp:78
WebAssemblyException * getExceptionFor(const MachineBasicBlock *MBB) const
void print(raw_ostream &OS, const Module *M=nullptr) const override
print - Print out the internal state of the pass.
Definition WebAssemblyExceptionInfo.cpp:369
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
Definition WebAssemblyExceptionInfo.cpp:270
void print(raw_ostream &OS, unsigned Depth=0) const
Definition WebAssemblyExceptionInfo.cpp:338
MachineBasicBlock * getEHPad() const
void addToBlocksSet(MachineBasicBlock *MBB)
void dump() const
Definition WebAssemblyExceptionInfo.cpp:361
void reserveBlocks(unsigned Size)
const std::vector< std::unique_ptr< WebAssemblyException > > & getSubExceptions() const
ArrayRef< MachineBasicBlock * > getBlocks() const
std::vector< MachineBasicBlock * > & getBlocksVector()
WebAssemblyException * getParentException() const
void removeFromBlocksSet(MachineBasicBlock *MBB)
unsigned getExceptionDepth() const
void setParentException(WebAssemblyException *WE)
void addToBlocksVector(MachineBasicBlock *MBB)
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
@ Wasm
WebAssembly Exception Handling.
iterator_range< po_iterator< T > > post_order(const T &G)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
iterator_range< df_iterator< T > > depth_first(const T &G)