Go to the documentation of this file.
28 #define DEBUG_TYPE "wasm-exception-info"
33 "WebAssembly Exception Information",
true,
true)
40 LLVM_DEBUG(
dbgs() <<
"********** Exception Info Calculation **********\n"
41 "********** Function: "
42 << MF.getName() <<
'\n');
44 if (MF.getTarget().getMCAsmInfo()->getExceptionHandlingType() !=
46 !MF.getFunction().hasPersonalityFn())
48 auto &MDT = getAnalysis<MachineDominatorTree>();
49 auto &MDF = getAnalysis<MachineDominanceFrontier>();
50 recalculate(MF, MDT, MDF);
87 auto WE = std::make_unique<WebAssemblyException>(EHPad);
88 discoverAndMapException(WE.get(), MDT, MDF);
130 if (!EHInfo->hasUnwindDest(EHPad))
132 auto *UnwindDest = EHInfo->getUnwindDest(EHPad);
135 if (SrcWE->contains(DstWE)) {
136 UnwindWEVec.push_back(std::make_pair(SrcWE, DstWE));
138 << DstWE->getEHPad()->getNumber() <<
"."
139 << DstWE->getEHPad()->getName()
140 <<
"'s exception is taken out of "
141 << SrcWE->getEHPad()->getNumber() <<
"."
142 << SrcWE->getEHPad()->getName() <<
"'s exception\n");
143 DstWE->setParentException(SrcWE->getParentException());
172 for (
auto &
P : UnwindWEVec) {
173 auto *SrcWE =
P.first;
174 auto *DstWE =
P.second;
178 if (WE != SrcWE && SrcWE->contains(WE) && !DstWE->contains(WE) &&
182 << WE->getEHPad()->getNumber() <<
"."
183 << WE->getEHPad()->getName()
184 <<
"'s exception is taken out of "
185 << SrcWE->getEHPad()->getNumber() <<
"."
186 << SrcWE->getEHPad()->getName() <<
"'s exception\n");
187 WE->setParentException(SrcWE->getParentException());
205 for (
auto &
P : UnwindWEVec) {
206 auto *SrcWE =
P.first;
207 auto *DstWE =
P.second;
209 for (
auto *
MBB : SrcWE->getBlocksSet()) {
212 SrcWE->getEHPad(), MDT) &&
213 "We already handled EH pads above");
221 while (InnerWE != SrcWE) {
225 <<
"'s exception\n");
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);
249 ExceptionPointers.
reserve(Exceptions.size());
252 for (
auto &WE : Exceptions) {
253 ExceptionPointers.push_back(WE.get());
254 if (WE->getParentException())
255 WE->getParentException()->getSubExceptions().push_back(
std::move(WE));
262 for (
auto *WE : ExceptionPointers) {
264 std::reverse(WE->getSubExceptions().begin(), WE->getSubExceptions().end());
270 TopLevelExceptions.clear();
280 void WebAssemblyExceptionInfo::discoverAndMapException(
283 unsigned NumBlocks = 0;
284 unsigned NumSubExceptions = 0;
290 while (!WL.empty()) {
305 for (
auto &Frontier : MDF.
find(SubE->
getEHPad())->second)
307 WL.push_back(Frontier);
347 OS <<
"." <<
BB->getName();
350 OS <<
" (landing-pad)";
354 for (
auto &SubE : SubExceptions)
358 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
368 for (
auto &WE : TopLevelExceptions)
unsigned getExceptionDepth() const
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This is an optimization pass for GlobalISel generic memory operations.
void recalculate(MachineFunction &MF, MachineDominatorTree &MDT, const MachineDominanceFrontier &MDF)
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
void print(raw_ostream &OS, unsigned Depth=0) const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
WebAssemblyException * getParentException() const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
iterator find(MachineBasicBlock *B)
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
void addToBlocksSet(MachineBasicBlock *MBB)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Represent the analysis usage information of a pass.
@ Wasm
WebAssembly Exception Handling.
static bool isReachableAmongDominated(const MachineBasicBlock *Src, const MachineBasicBlock *Dst, const MachineBasicBlock *Header, const MachineDominatorTree &MDT)
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
const WasmEHFuncInfo * getWasmEHFuncInfo() const
getWasmEHFuncInfo - Return information about how the current function uses Wasm exception handling.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
WebAssembly Exception true
MachineBasicBlock * getEHPad() const
WebAssembly Exception Information
const std::vector< std::unique_ptr< WebAssemblyException > > & getSubExceptions() const
void removeFromBlocksSet(MachineBasicBlock *MBB)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
void changeExceptionFor(const MachineBasicBlock *MBB, WebAssemblyException *WE)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
A Module instance is used to store all the information related to an LLVM module.
void addTopLevelException(std::unique_ptr< WebAssemblyException > WE)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
void setParentException(WebAssemblyException *WE)
iterator_range< succ_iterator > successors()
bool isEHPad() const
Returns true if the block is a landing pad.
WebAssemblyException * getExceptionFor(const MachineBasicBlock *MBB) const
iterator_range< df_iterator< T > > depth_first(const T &G)
void setPreservesAll()
Set by analyses that do not transform their input at all.
iterator_range< po_iterator< T > > post_order(const T &G)
std::vector< MachineBasicBlock * > & getBlocksVector()
INITIALIZE_PASS_BEGIN(WebAssemblyExceptionInfo, DEBUG_TYPE, "WebAssembly Exception Information", true, true) INITIALIZE_PASS_END(WebAssemblyExceptionInfo
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
auto reverse(ContainerTy &&C)
void reserveBlocks(unsigned Size)
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
AnalysisUsage & addRequired()
void addToBlocksVector(MachineBasicBlock *MBB)
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
ArrayRef< MachineBasicBlock * > getBlocks() const
void reserve(size_type N)
void print(raw_ostream &OS, const Module *M=nullptr) const override
print - Print out the internal state of the pass.
This file implements WebAssemblyException information analysis.
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.