LLVM 24.0.0git
WebAssemblyExceptionInfo.cpp
Go to the documentation of this file.
1//===--- WebAssemblyExceptionInfo.cpp - Exception Information -------------===//
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"
23#include "llvm/IR/Module.h"
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
42 LLVM_DEBUG(dbgs() << "********** Exception Info Calculation **********\n"
43 "********** Function: "
44 << MF.getName() << '\n');
45 if (!MF.getFunction().hasPersonalityFn() ||
46 MF.getFunction().getParent()->getExceptionModel() !=
48 return;
49 MachineDominatorTree &MDT = GetMDT();
50 MachineDominanceFrontier &MDF = GetMDF();
51 WEI.recalculate(MF, MDT, MDF);
52}
53
55 MachineFunction &MF) {
58 WasmExceptionInfo, MF,
59 [&]() -> MachineDominatorTree & {
61 },
62 [&]() -> MachineDominanceFrontier & {
64 });
65 return false;
66}
67
73 WEI, MF,
74 [&]() -> MachineDominatorTree & {
76 },
77 [&]() -> MachineDominanceFrontier & {
79 });
80 return WEI;
81}
82
83AnalysisKey WebAssemblyExceptionAnalysis::Key;
84
87 const MachineDominanceFrontier &MDF) {
88 // Postorder traversal of the dominator tree.
90 for (auto *DomNode : post_order(&MDT)) {
91 MachineBasicBlock *EHPad = DomNode->getBlock();
92 if (!EHPad->isEHPad())
93 continue;
94 auto WE = std::make_unique<WebAssemblyException>(EHPad);
95 discoverAndMapException(WE.get(), MDT, MDF);
96 Exceptions.push_back(std::move(WE));
97 }
98
99 // Add BBs to exceptions' block set. This is a preparation to take out
100 // remaining incorrect BBs from exceptions, because we need to iterate over
101 // BBs for each exception.
102 for (auto *DomNode : post_order(&MDT)) {
103 MachineBasicBlock *MBB = DomNode->getBlock();
105 for (; WE; WE = WE->getParentException())
106 WE->addToBlocksSet(MBB);
107 }
108
109 // Add BBs to exceptions' block vector
110 for (auto *DomNode : post_order(&MDT)) {
111 MachineBasicBlock *MBB = DomNode->getBlock();
113 for (; WE; WE = WE->getParentException())
115 }
116
118 ExceptionPointers.reserve(Exceptions.size());
119
120 // Add subexceptions to exceptions
121 for (auto &WE : Exceptions) {
122 ExceptionPointers.push_back(WE.get());
123 if (WE->getParentException())
124 WE->getParentException()->getSubExceptions().push_back(std::move(WE));
125 else
126 addTopLevelException(std::move(WE));
127 }
128
129 // For convenience, Blocks and SubExceptions are inserted in postorder.
130 // Reverse the lists.
131 for (auto *WE : ExceptionPointers) {
132 WE->reverseBlock();
133 std::reverse(WE->getSubExceptions().begin(), WE->getSubExceptions().end());
134 }
135}
136
138 BBMap.clear();
139 TopLevelExceptions.clear();
140}
141
149
150void WebAssemblyExceptionInfo::discoverAndMapException(
152 const MachineDominanceFrontier &MDF) {
153 unsigned NumBlocks = 0;
154 unsigned NumSubExceptions = 0;
155
156 // Map blocks that belong to a catchpad / cleanuppad
157 MachineBasicBlock *EHPad = WE->getEHPad();
159 WL.push_back(EHPad);
160 while (!WL.empty()) {
162
163 // Find its outermost discovered exception. If this is a discovered block,
164 // check if it is already discovered to be a subexception of this exception.
165 WebAssemblyException *SubE = getOutermostException(MBB);
166 if (SubE) {
167 if (SubE != WE) {
168 // Discover a subexception of this exception.
169 SubE->setParentException(WE);
170 ++NumSubExceptions;
171 NumBlocks += SubE->getBlocksVector().capacity();
172 // All blocks that belong to this subexception have been already
173 // discovered. Skip all of them. Add the subexception's landing pad's
174 // dominance frontier to the worklist.
175 for (auto &Frontier : MDF.find(SubE->getEHPad())->second)
176 if (MDT.dominates(EHPad, Frontier))
177 WL.push_back(Frontier);
178 }
179 continue;
180 }
181
182 // This is an undiscovered block. Map it to the current exception.
184 ++NumBlocks;
185
186 // Add successors dominated by the current BB to the worklist.
187 for (auto *Succ : MBB->successors())
188 if (MDT.dominates(EHPad, Succ))
189 WL.push_back(Succ);
190 }
191
192 WE->getSubExceptions().reserve(NumSubExceptions);
193 WE->reserveBlocks(NumBlocks);
194}
195
197WebAssemblyExceptionInfo::getOutermostException(MachineBasicBlock *MBB) const {
198 WebAssemblyException *WE = getExceptionFor(MBB);
199 if (WE) {
200 while (WebAssemblyException *Parent = WE->getParentException())
201 WE = Parent;
202 }
203 return WE;
204}
205
207 OS.indent(Depth * 2) << "Exception at depth " << getExceptionDepth()
208 << " containing: ";
209
210 for (unsigned I = 0; I < getBlocks().size(); ++I) {
212 if (I)
213 OS << ", ";
214 OS << "%bb." << MBB->getNumber();
215 if (const auto *BB = MBB->getBasicBlock())
216 if (BB->hasName())
217 OS << "." << BB->getName();
218
219 if (getEHPad() == MBB)
220 OS << " (landing-pad)";
221 }
222 OS << "\n";
223
224 for (auto &SubE : SubExceptions)
225 SubE->print(OS, Depth + 2);
226}
227
228#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
230#endif
231
233 WE.print(OS);
234 return OS;
235}
236
238 for (auto &WE : TopLevelExceptions)
239 WE->print(OS);
240}
241
243 MachineFunction &MF, const PreservedAnalyses &PA,
244 MachineFunctionAnalysisManager::Invalidator &) {
245 // Check whether the analysis, all analyses on machine functions, or the
246 // machine function's CFG have been preserved.
248 return !PAC.preserved() &&
249 !PAC.preservedSet<AllAnalysesOn<MachineFunction>>() &&
250 !PAC.preservedSet<CFGAnalyses>();
251}
MachineBasicBlock & MBB
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:686
#define DEBUG_TYPE
Module.h This file contains the declarations for the Module class.
#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:68
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.
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)
@ Wasm
WebAssembly Exception Handling.
Definition CodeGen.h:61
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29