29#define DEBUG_TYPE "wasm-exception-info"
34 "WebAssembly Exception Information",
true,
true)
41 LLVM_DEBUG(
dbgs() <<
"********** Exception Info Calculation **********\n"
42 "********** Function: "
43 << MF.getName() <<
'\n');
45 if (MF.getTarget().getMCAsmInfo()->getExceptionHandlingType() !=
46 ExceptionHandling::Wasm ||
47 !MF.getFunction().hasPersonalityFn())
49 auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
50 auto &MDF = getAnalysis<MachineDominanceFrontier>();
51 recalculate(MF, MDT, MDF);
88 auto WE = std::make_unique<WebAssemblyException>(EHPad);
89 discoverAndMapException(WE.get(), MDT, MDF);
132 if (!EHInfo->hasUnwindDest(EHPad))
134 auto *UnwindDest = EHInfo->getUnwindDest(EHPad);
137 if (SrcWE->contains(DstWE)) {
138 UnwindWEVec.
push_back(std::make_pair(SrcWE, DstWE));
140 << DstWE->getEHPad()->getNumber() <<
"."
141 << DstWE->getEHPad()->getName()
142 <<
"'s exception is taken out of "
143 << SrcWE->getEHPad()->getNumber() <<
"."
144 << SrcWE->getEHPad()->getName() <<
"'s exception\n");
145 DstWE->setParentException(SrcWE->getParentException());
174 for (
auto &
P : UnwindWEVec) {
175 auto *SrcWE =
P.first;
176 auto *DstWE =
P.second;
180 if (WE != SrcWE && SrcWE->contains(WE) && !DstWE->contains(WE) &&
184 << WE->getEHPad()->getNumber() <<
"."
185 << WE->getEHPad()->getName()
186 <<
"'s exception is taken out of "
187 << SrcWE->getEHPad()->getNumber() <<
"."
188 << SrcWE->getEHPad()->getName() <<
"'s exception\n");
189 WE->setParentException(SrcWE->getParentException());
207 for (
auto &
P : UnwindWEVec) {
208 auto *SrcWE =
P.first;
209 auto *DstWE =
P.second;
213 assert(!isReachableAmongDominated(DstWE->getEHPad(), MBB,
214 SrcWE->getEHPad(), MDT) &&
215 "We already handled EH pads above");
220 LLVM_DEBUG(dbgs() <<
"Remainder BB: " << MBB->getNumber() <<
"."
221 << MBB->getName() <<
" is\n");
222 WebAssemblyException *InnerWE = getExceptionFor(MBB);
223 while (InnerWE != SrcWE) {
225 <<
" removed from " << InnerWE->getEHPad()->getNumber()
226 <<
"." << InnerWE->getEHPad()->getName()
227 <<
"'s exception\n");
228 InnerWE->removeFromBlocksSet(MBB);
229 InnerWE = InnerWE->getParentException();
231 LLVM_DEBUG(
dbgs() <<
" removed from " << SrcWE->getEHPad()->getNumber()
232 <<
"." << SrcWE->getEHPad()->getName()
233 <<
"'s exception\n");
235 if (SrcWE->getParentException())
236 SrcWE->getParentException()->addToBlocksSet(
MBB);
252 ExceptionPointers.
reserve(Exceptions.size());
255 for (
auto &WE : Exceptions) {
260 addTopLevelException(std::move(WE));
265 for (
auto *WE : ExceptionPointers) {
273 TopLevelExceptions.clear();
283void WebAssemblyExceptionInfo::discoverAndMapException(
286 unsigned NumBlocks = 0;
287 unsigned NumSubExceptions = 0;
293 while (!WL.
empty()) {
308 for (
auto &Frontier : MDF.
find(SubE->
getEHPad())->second)
350 OS <<
"." << BB->getName();
353 OS <<
" (landing-pad)";
357 for (
auto &SubE : SubExceptions)
361#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
371 for (
auto &WE : TopLevelExceptions)
#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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
WebAssembly Exception Information
static bool isReachableAmongDominated(const MachineBasicBlock *Src, const MachineBasicBlock *Dst, const MachineBasicBlock *Header, const MachineDominatorTree &MDT)
WebAssembly Exception true
This file implements WebAssemblyException information analysis.
This file provides WebAssembly-specific target descriptions.
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...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
iterator_range< succ_iterator > successors()
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 MachineDomTreeNode *A, const MachineDomTreeNode *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.
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.
void changeExceptionFor(const MachineBasicBlock *MBB, WebAssemblyException *WE)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
void recalculate(MachineFunction &MF, MachineDominatorTree &MDT, const MachineDominanceFrontier &MDF)
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.
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
void reverseBlock(unsigned From=0)
void print(raw_ostream &OS, unsigned Depth=0) const
MachineBasicBlock * getEHPad() const
void addToBlocksSet(MachineBasicBlock *MBB)
void reserveBlocks(unsigned Size)
const std::vector< std::unique_ptr< WebAssemblyException > > & getSubExceptions() const
ArrayRef< MachineBasicBlock * > getBlocks() const
std::vector< MachineBasicBlock * > & getBlocksVector()
WebAssemblyException * getParentException() const
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)
iterator_range< po_iterator< T > > post_order(const T &G)
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)