LLVM  14.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/InitializePasses.h"
22 #include "llvm/MC/MCAsmInfo.h"
24 
25 using namespace llvm;
26 
27 #define DEBUG_TYPE "wasm-exception-info"
28 
30 
32  "WebAssembly Exception Information", true, true)
36  "WebAssembly Exception Information", true, true)
37 
38 bool WebAssemblyExceptionInfo::runOnMachineFunction(MachineFunction &MF) {
39  LLVM_DEBUG(dbgs() << "********** Exception Info Calculation **********\n"
40  "********** Function: "
41  << MF.getName() << '\n');
42  releaseMemory();
43  if (MF.getTarget().getMCAsmInfo()->getExceptionHandlingType() !=
45  !MF.getFunction().hasPersonalityFn())
46  return false;
47  auto &MDT = getAnalysis<MachineDominatorTree>();
48  auto &MDF = getAnalysis<MachineDominanceFrontier>();
49  recalculate(MF, MDT, MDF);
50  LLVM_DEBUG(dump());
51  return false;
52 }
53 
54 // Check if Dst is reachable from Src using BFS. Search only within BBs
55 // dominated by Header.
57  const MachineBasicBlock *Dst,
58  const MachineBasicBlock *Header,
59  const MachineDominatorTree &MDT) {
60  assert(MDT.dominates(Header, Dst));
63  WL.push_back(Src);
64 
65  while (!WL.empty()) {
66  const auto *MBB = WL.pop_back_val();
67  if (MBB == Dst)
68  return true;
69  Visited.insert(MBB);
70  for (auto *Succ : MBB->successors())
71  if (!Visited.count(Succ) && MDT.dominates(Header, Succ))
72  WL.push_back(Succ);
73  }
74  return false;
75 }
76 
79  const MachineDominanceFrontier &MDF) {
80  // Postorder traversal of the dominator tree.
82  for (auto DomNode : post_order(&MDT)) {
83  MachineBasicBlock *EHPad = DomNode->getBlock();
84  if (!EHPad->isEHPad())
85  continue;
86  auto WE = std::make_unique<WebAssemblyException>(EHPad);
87  discoverAndMapException(WE.get(), MDT, MDF);
88  Exceptions.push_back(std::move(WE));
89  }
90 
91  // WasmEHFuncInfo contains a map of <catchpad, its next unwind destination>,
92  // which means, if an exception is not caught by the catchpad, it should end
93  // up in the next unwind destination stored in this data structure. (It is
94  // written as catchswitch's 'unwind' destination in ll files.) The below is an
95  // intuitive example of their relationship in C++ code:
96  // try {
97  // try {
98  // } catch (int) { // catchpad
99  // ... // this catch (int) { ... } is grouped as an exception
100  // }
101  // } catch (...) { // next unwind destination
102  // }
103  // (The example is try-catches for illustration purpose, but the unwind
104  // destination can be also a cleanuppad generated by destructor calls.) So the
105  // unwind destination is in the outside of the catchpad's exception.
106  //
107  // We group exceptions in this analysis simply by including all BBs dominated
108  // by an EH pad. But in case the EH pad's unwind destination does not have any
109  // children outside of the exception, that unwind destination ends up also
110  // being dominated by the EH pad and included in the exception, which is not
111  // semantically correct, because it unwinds/rethrows into an inner scope.
112  //
113  // Here we extract those unwind destinations from their (incorrect) parent
114  // exception. Note that the unwind destinations may not be an immediate
115  // children of the parent exception, so we have to traverse the parent chain.
116  //
117  // We should traverse BBs in the preorder of the dominator tree, because
118  // otherwise the result can be incorrect. For example, when there are three
119  // exceptions A, B, and C and A > B > C (> is subexception relationship here),
120  // and A's unwind destination is B and B's is C. When we visit B before A, we
121  // end up extracting C only out of B but not out of A.
122  const auto *EHInfo = MF.getWasmEHFuncInfo();
124  UnwindWEVec;
125  for (auto *DomNode : depth_first(&MDT)) {
126  MachineBasicBlock *EHPad = DomNode->getBlock();
127  if (!EHPad->isEHPad())
128  continue;
129  if (!EHInfo->hasUnwindDest(EHPad))
130  continue;
131  auto *UnwindDest = EHInfo->getUnwindDest(EHPad);
132  auto *SrcWE = getExceptionFor(EHPad);
133  auto *DstWE = getExceptionFor(UnwindDest);
134  if (SrcWE->contains(DstWE)) {
135  UnwindWEVec.push_back(std::make_pair(SrcWE, DstWE));
136  LLVM_DEBUG(dbgs() << "Unwind destination ExceptionInfo fix:\n "
137  << DstWE->getEHPad()->getNumber() << "."
138  << DstWE->getEHPad()->getName()
139  << "'s exception is taken out of "
140  << SrcWE->getEHPad()->getNumber() << "."
141  << SrcWE->getEHPad()->getName() << "'s exception\n");
142  DstWE->setParentException(SrcWE->getParentException());
143  }
144  }
145 
146  // After fixing subexception relationship between unwind destinations above,
147  // there can still be remaining discrepancies.
148  //
149  // For example, suppose Exception A is dominated by EHPad A and Exception B is
150  // dominated by EHPad B. EHPad A's unwind destination is EHPad B, but because
151  // EHPad B is dominated by EHPad A, the initial grouping makes Exception B a
152  // subexception of Exception A, and we fix it by taking Exception B out of
153  // Exception A above. But there can still be remaining BBs within Exception A
154  // that are reachable from Exception B. These BBs semantically don't belong
155  // to Exception A and were not a part of this 'catch' clause or cleanup code
156  // in the original code, but they just happened to be grouped within Exception
157  // A because they were dominated by EHPad A. We fix this case by taking those
158  // BBs out of the incorrect exception and all its subexceptions that it
159  // belongs to.
160  //
161  // 1. First, we take out remaining incorrect subexceptions. This part is
162  // easier, because we haven't added BBs to exceptions yet, we only need to
163  // change parent exception pointer.
164  for (auto *DomNode : depth_first(&MDT)) {
165  MachineBasicBlock *EHPad = DomNode->getBlock();
166  if (!EHPad->isEHPad())
167  continue;
168  auto *WE = getExceptionFor(EHPad);
169 
170  // For each source EHPad -> unwind destination EHPad
171  for (auto &P : UnwindWEVec) {
172  auto *SrcWE = P.first;
173  auto *DstWE = P.second;
174  // If WE (the current EH pad's exception) is still contained in SrcWE but
175  // reachable from DstWE that was taken out of SrcWE above, we have to take
176  // out WE out of SrcWE too.
177  if (WE != SrcWE && SrcWE->contains(WE) && !DstWE->contains(WE) &&
178  isReachableAmongDominated(DstWE->getEHPad(), EHPad, SrcWE->getEHPad(),
179  MDT)) {
180  LLVM_DEBUG(dbgs() << "Remaining reachable ExceptionInfo fix:\n "
181  << WE->getEHPad()->getNumber() << "."
182  << WE->getEHPad()->getName()
183  << "'s exception is taken out of "
184  << SrcWE->getEHPad()->getNumber() << "."
185  << SrcWE->getEHPad()->getName() << "'s exception\n");
186  WE->setParentException(SrcWE->getParentException());
187  }
188  }
189  }
190 
191  // Add BBs to exceptions' block set. This is a preparation to take out
192  // remaining incorect BBs from exceptions, because we need to iterate over BBs
193  // for each exception.
194  for (auto *DomNode : post_order(&MDT)) {
195  MachineBasicBlock *MBB = DomNode->getBlock();
197  for (; WE; WE = WE->getParentException())
198  WE->addToBlocksSet(MBB);
199  }
200 
201  // 2. We take out remaining individual BBs out. Now we have added BBs to each
202  // exceptions' BlockSet, when we take a BB out of an exception, we need to fix
203  // those sets too.
204  for (auto &P : UnwindWEVec) {
205  auto *SrcWE = P.first;
206  auto *DstWE = P.second;
207 
208  for (auto *MBB : SrcWE->getBlocksSet()) {
209  if (MBB->isEHPad()) {
210  assert(!isReachableAmongDominated(DstWE->getEHPad(), MBB,
211  SrcWE->getEHPad(), MDT) &&
212  "We already handled EH pads above");
213  continue;
214  }
215  if (isReachableAmongDominated(DstWE->getEHPad(), MBB, SrcWE->getEHPad(),
216  MDT)) {
217  LLVM_DEBUG(dbgs() << "Remainder BB: " << MBB->getNumber() << "."
218  << MBB->getName() << " is\n");
220  while (InnerWE != SrcWE) {
221  LLVM_DEBUG(dbgs()
222  << " removed from " << InnerWE->getEHPad()->getNumber()
223  << "." << InnerWE->getEHPad()->getName()
224  << "'s exception\n");
225  InnerWE->removeFromBlocksSet(MBB);
226  InnerWE = InnerWE->getParentException();
227  }
228  SrcWE->removeFromBlocksSet(MBB);
229  LLVM_DEBUG(dbgs() << " removed from " << SrcWE->getEHPad()->getNumber()
230  << "." << SrcWE->getEHPad()->getName()
231  << "'s exception\n");
232  changeExceptionFor(MBB, SrcWE->getParentException());
233  if (SrcWE->getParentException())
234  SrcWE->getParentException()->addToBlocksSet(MBB);
235  }
236  }
237  }
238 
239  // Add BBs to exceptions' block vector
240  for (auto DomNode : post_order(&MDT)) {
241  MachineBasicBlock *MBB = DomNode->getBlock();
243  for (; WE; WE = WE->getParentException())
244  WE->addToBlocksVector(MBB);
245  }
246 
247  SmallVector<WebAssemblyException*, 8> ExceptionPointers;
248  ExceptionPointers.reserve(Exceptions.size());
249 
250  // Add subexceptions to exceptions
251  for (auto &WE : Exceptions) {
252  ExceptionPointers.push_back(WE.get());
253  if (WE->getParentException())
254  WE->getParentException()->getSubExceptions().push_back(std::move(WE));
255  else
257  }
258 
259  // For convenience, Blocks and SubExceptions are inserted in postorder.
260  // Reverse the lists.
261  for (auto *WE : ExceptionPointers) {
262  WE->reverseBlock();
263  std::reverse(WE->getSubExceptions().begin(), WE->getSubExceptions().end());
264  }
265 }
266 
268  BBMap.clear();
269  TopLevelExceptions.clear();
270 }
271 
273  AU.setPreservesAll();
277 }
278 
279 void WebAssemblyExceptionInfo::discoverAndMapException(
281  const MachineDominanceFrontier &MDF) {
282  unsigned NumBlocks = 0;
283  unsigned NumSubExceptions = 0;
284 
285  // Map blocks that belong to a catchpad / cleanuppad
286  MachineBasicBlock *EHPad = WE->getEHPad();
288  WL.push_back(EHPad);
289  while (!WL.empty()) {
291 
292  // Find its outermost discovered exception. If this is a discovered block,
293  // check if it is already discovered to be a subexception of this exception.
294  WebAssemblyException *SubE = getOutermostException(MBB);
295  if (SubE) {
296  if (SubE != WE) {
297  // Discover a subexception of this exception.
298  SubE->setParentException(WE);
299  ++NumSubExceptions;
300  NumBlocks += SubE->getBlocksVector().capacity();
301  // All blocks that belong to this subexception have been already
302  // discovered. Skip all of them. Add the subexception's landing pad's
303  // dominance frontier to the worklist.
304  for (auto &Frontier : MDF.find(SubE->getEHPad())->second)
305  if (MDT.dominates(EHPad, Frontier))
306  WL.push_back(Frontier);
307  }
308  continue;
309  }
310 
311  // This is an undiscovered block. Map it to the current exception.
312  changeExceptionFor(MBB, WE);
313  ++NumBlocks;
314 
315  // Add successors dominated by the current BB to the worklist.
316  for (auto *Succ : MBB->successors())
317  if (MDT.dominates(EHPad, Succ))
318  WL.push_back(Succ);
319  }
320 
321  WE->getSubExceptions().reserve(NumSubExceptions);
322  WE->reserveBlocks(NumBlocks);
323 }
324 
326 WebAssemblyExceptionInfo::getOutermostException(MachineBasicBlock *MBB) const {
328  if (WE) {
329  while (WebAssemblyException *Parent = WE->getParentException())
330  WE = Parent;
331  }
332  return WE;
333 }
334 
335 void WebAssemblyException::print(raw_ostream &OS, unsigned Depth) const {
336  OS.indent(Depth * 2) << "Exception at depth " << getExceptionDepth()
337  << " containing: ";
338 
339  for (unsigned I = 0; I < getBlocks().size(); ++I) {
341  if (I)
342  OS << ", ";
343  OS << "%bb." << MBB->getNumber();
344  if (const auto *BB = MBB->getBasicBlock())
345  if (BB->hasName())
346  OS << "." << BB->getName();
347 
348  if (getEHPad() == MBB)
349  OS << " (landing-pad)";
350  }
351  OS << "\n";
352 
353  for (auto &SubE : SubExceptions)
354  SubE->print(OS, Depth + 2);
355 }
356 
357 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
359 #endif
360 
362  WE.print(OS);
363  return OS;
364 }
365 
367  for (auto &WE : TopLevelExceptions)
368  WE->print(OS);
369 }
llvm::WebAssemblyException::getExceptionDepth
unsigned getExceptionDepth() const
Definition: WebAssemblyExceptionInfo.h:109
LLVM_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:491
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::WebAssemblyExceptionInfo::recalculate
void recalculate(MachineFunction &MF, MachineDominatorTree &MDT, const MachineDominanceFrontier &MDF)
Definition: WebAssemblyExceptionInfo.cpp:77
llvm::MachineBasicBlock::getBasicBlock
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
Definition: MachineBasicBlock.h:202
P
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
Definition: README-SSE.txt:411
llvm::WebAssemblyException::print
void print(raw_ostream &OS, unsigned Depth=0) const
Definition: WebAssemblyExceptionInfo.cpp:335
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::WebAssemblyException::getParentException
WebAssemblyException * getParentException() const
Definition: WebAssemblyExceptionInfo.h:57
llvm::Depth
@ Depth
Definition: SIMachineScheduler.h:36
llvm::reverse
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
Definition: STLExtras.h:333
llvm::WebAssemblyExceptionInfo::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: WebAssemblyExceptionInfo.cpp:272
llvm::SmallPtrSet< const MachineBasicBlock *, 8 >
llvm::MachineDominanceFrontier::find
iterator find(MachineBasicBlock *B)
Definition: MachineDominanceFrontier.h:68
llvm::dump
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Definition: SparseBitVector.h:876
llvm::MachineDominatorTree::dominates
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
Definition: MachineDominators.h:109
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:635
llvm::WebAssemblyException
Definition: WebAssemblyExceptionInfo.h:42
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:102
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
DEBUG_TYPE
#define DEBUG_TYPE
Definition: WebAssemblyExceptionInfo.cpp:27
llvm::WebAssemblyException::addToBlocksSet
void addToBlocksSet(MachineBasicBlock *MBB)
Definition: WebAssemblyExceptionInfo.h:71
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
TargetMachine.h
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::WebAssemblyExceptionInfo::ID
static char ID
Definition: WebAssemblyExceptionInfo.h:134
llvm::ExceptionHandling::Wasm
@ Wasm
WebAssembly Exception Handling.
isReachableAmongDominated
static bool isReachableAmongDominated(const MachineBasicBlock *Src, const MachineBasicBlock *Dst, const MachineBasicBlock *Header, const MachineDominatorTree &MDT)
Definition: WebAssemblyExceptionInfo.cpp:56
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::operator<<
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:230
llvm::MachineFunction::getWasmEHFuncInfo
const WasmEHFuncInfo * getWasmEHFuncInfo() const
getWasmEHFuncInfo - Return information about how the current function uses Wasm exception handling.
Definition: MachineFunction.h:664
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
WebAssemblyUtilities.h
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
WebAssemblyMCTargetDesc.h
true
WebAssembly Exception true
Definition: WebAssemblyExceptionInfo.cpp:36
llvm::WebAssemblyException::getEHPad
MachineBasicBlock * getEHPad() const
Definition: WebAssemblyExceptionInfo.h:55
Information
WebAssembly Exception Information
Definition: WebAssemblyExceptionInfo.cpp:36
llvm::WebAssemblyException::getSubExceptions
const std::vector< std::unique_ptr< WebAssemblyException > > & getSubExceptions() const
Definition: WebAssemblyExceptionInfo.h:90
llvm::WebAssemblyException::removeFromBlocksSet
void removeFromBlocksSet(MachineBasicBlock *MBB)
Definition: WebAssemblyExceptionInfo.h:72
llvm::MachineDominanceFrontier
Definition: MachineDominanceFrontier.h:20
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
move
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
Definition: README.txt:546
llvm::WebAssemblyExceptionInfo
Definition: WebAssemblyExceptionInfo.h:123
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::WebAssemblyExceptionInfo::changeExceptionFor
void changeExceptionFor(const MachineBasicBlock *MBB, WebAssemblyException *WE)
Definition: WebAssemblyExceptionInfo.h:157
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::WebAssemblyExceptionInfo::releaseMemory
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:267
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::WebAssemblyExceptionInfo::addTopLevelException
void addTopLevelException(std::unique_ptr< WebAssemblyException > WE)
Definition: WebAssemblyExceptionInfo.h:166
llvm::SmallPtrSetImpl::count
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:382
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::MachineBasicBlock::getNumber
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
Definition: MachineBasicBlock.h:1056
MCAsmInfo.h
llvm::WebAssemblyException::setParentException
void setParentException(WebAssemblyException *WE)
Definition: WebAssemblyExceptionInfo.h:58
llvm::MachineBasicBlock::successors
iterator_range< succ_iterator > successors()
Definition: MachineBasicBlock.h:355
llvm::MachineBasicBlock::isEHPad
bool isEHPad() const
Returns true if the block is a landing pad.
Definition: MachineBasicBlock.h:526
llvm::WebAssemblyExceptionInfo::getExceptionFor
WebAssemblyException * getExceptionFor(const MachineBasicBlock *MBB) const
Definition: WebAssemblyExceptionInfo.h:153
llvm::depth_first
iterator_range< df_iterator< T > > depth_first(const T &G)
Definition: DepthFirstIterator.h:229
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::AnalysisUsage::setPreservesAll
void setPreservesAll()
Set by analyses that do not transform their input at all.
Definition: PassAnalysisSupport.h:130
WasmEHFuncInfo.h
MachineDominanceFrontier.h
llvm::WebAssemblyException::dump
void dump() const
Definition: WebAssemblyExceptionInfo.cpp:358
llvm::post_order
iterator_range< po_iterator< T > > post_order(const T &G)
Definition: PostOrderIterator.h:188
llvm::WebAssemblyException::getBlocksVector
std::vector< MachineBasicBlock * > & getBlocksVector()
Definition: WebAssemblyExceptionInfo.h:86
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(WebAssemblyExceptionInfo, DEBUG_TYPE, "WebAssembly Exception Information", true, true) INITIALIZE_PASS_END(WebAssemblyExceptionInfo
PostOrderIterator.h
llvm::raw_ostream::indent
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
Definition: raw_ostream.cpp:497
llvm::WebAssemblyException::reserveBlocks
void reserveBlocks(unsigned Size)
Definition: WebAssemblyExceptionInfo.h:103
BB
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
Definition: README.txt:39
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
llvm::WebAssemblyException::addToBlocksVector
void addToBlocksVector(MachineBasicBlock *MBB)
Definition: WebAssemblyExceptionInfo.h:73
llvm::MachineDominatorTree
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
Definition: MachineDominators.h:45
llvm::WebAssemblyException::getBlocks
ArrayRef< MachineBasicBlock * > getBlocks() const
Definition: WebAssemblyExceptionInfo.h:78
llvm::SmallVectorImpl::reserve
void reserve(size_type N)
Definition: SmallVector.h:624
llvm::WebAssemblyExceptionInfo::print
void print(raw_ostream &OS, const Module *M=nullptr) const override
print - Print out the internal state of the pass.
Definition: WebAssemblyExceptionInfo.cpp:366
WebAssemblyExceptionInfo.h
This file implements WebAssemblyException information analysis.
InitializePasses.h
llvm::MachineBasicBlock::getName
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
Definition: MachineBasicBlock.cpp:314
MachineDominators.h
llvm::SmallPtrSetImpl::insert
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:364