LLVM  8.0.1
WebAssemblyExceptionInfo.cpp
Go to the documentation of this file.
1 //===--- WebAssemblyExceptionInfo.cpp - Exception Infomation --------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief This file implements WebAssemblyException information analysis.
12 ///
13 //===----------------------------------------------------------------------===//
14 
17 #include "WebAssemblyUtilities.h"
21 
22 using namespace llvm;
23 
24 #define DEBUG_TYPE "wasm-exception-info"
25 
27 
29  "WebAssembly Exception Information", true, true)
33  "WebAssembly Exception Information", true, true)
34 
35 bool WebAssemblyExceptionInfo::runOnMachineFunction(MachineFunction &MF) {
36  LLVM_DEBUG(dbgs() << "********** Exception Info Calculation **********\n"
37  "********** Function: "
38  << MF.getName() << '\n');
39  releaseMemory();
40  auto &MDT = getAnalysis<MachineDominatorTree>();
41  auto &MDF = getAnalysis<MachineDominanceFrontier>();
42  recalculate(MDT, MDF);
43  return false;
44 }
45 
48  // Postorder traversal of the dominator tree.
50  for (auto DomNode : post_order(&MDT)) {
51  MachineBasicBlock *EHPad = DomNode->getBlock();
52  if (!EHPad->isEHPad())
53  continue;
54  // We group catch & catch-all terminate pads together, so skip the second
55  // one
57  continue;
58  auto *WE = new WebAssemblyException(EHPad);
59  discoverAndMapException(WE, MDT, MDF);
60  Exceptions.push_back(WE);
61  }
62 
63  // Add BBs to exceptions
64  for (auto DomNode : post_order(&MDT)) {
65  MachineBasicBlock *MBB = DomNode->getBlock();
67  for (; WE; WE = WE->getParentException())
68  WE->addBlock(MBB);
69  }
70 
71  // Add subexceptions to exceptions
72  for (auto *WE : Exceptions) {
73  if (WE->getParentException())
74  WE->getParentException()->getSubExceptions().push_back(WE);
75  else
77  }
78 
79  // For convenience, Blocks and SubExceptions are inserted in postorder.
80  // Reverse the lists.
81  for (auto *WE : Exceptions) {
82  WE->reverseBlock();
83  std::reverse(WE->getSubExceptions().begin(), WE->getSubExceptions().end());
84  }
85 }
86 
88  BBMap.clear();
89  DeleteContainerPointers(TopLevelExceptions);
90  TopLevelExceptions.clear();
91 }
92 
94  AU.setPreservesAll();
98 }
99 
100 void WebAssemblyExceptionInfo::discoverAndMapException(
102  const MachineDominanceFrontier &MDF) {
103  unsigned NumBlocks = 0;
104  unsigned NumSubExceptions = 0;
105 
106  // Map blocks that belong to a catchpad / cleanuppad
107  MachineBasicBlock *EHPad = WE->getEHPad();
108 
109  // We group catch & catch-all terminate pads together within an exception
110  if (WebAssembly::isCatchTerminatePad(*EHPad)) {
111  assert(EHPad->succ_size() == 1 &&
112  "Catch terminate pad has more than one successors");
113  changeExceptionFor(EHPad, WE);
114  changeExceptionFor(*(EHPad->succ_begin()), WE);
115  return;
116  }
117 
119  WL.push_back(EHPad);
120  while (!WL.empty()) {
121  MachineBasicBlock *MBB = WL.pop_back_val();
122 
123  // Find its outermost discovered exception. If this is a discovered block,
124  // check if it is already discovered to be a subexception of this exception.
125  WebAssemblyException *SubE = getOutermostException(MBB);
126  if (SubE) {
127  if (SubE != WE) {
128  // Discover a subexception of this exception.
129  SubE->setParentException(WE);
130  ++NumSubExceptions;
131  NumBlocks += SubE->getBlocksVector().capacity();
132  // All blocks that belong to this subexception have been already
133  // discovered. Skip all of them. Add the subexception's landing pad's
134  // dominance frontier to the worklist.
135  for (auto &Frontier : MDF.find(SubE->getEHPad())->second)
136  if (MDT.dominates(EHPad, Frontier))
137  WL.push_back(Frontier);
138  }
139  continue;
140  }
141 
142  // This is an undiscovered block. Map it to the current exception.
143  changeExceptionFor(MBB, WE);
144  ++NumBlocks;
145 
146  // Add successors dominated by the current BB to the worklist.
147  for (auto *Succ : MBB->successors())
148  if (MDT.dominates(EHPad, Succ))
149  WL.push_back(Succ);
150  }
151 
152  WE->getSubExceptions().reserve(NumSubExceptions);
153  WE->reserveBlocks(NumBlocks);
154 }
155 
157 WebAssemblyExceptionInfo::getOutermostException(MachineBasicBlock *MBB) const {
159  if (WE) {
160  while (WebAssemblyException *Parent = WE->getParentException())
161  WE = Parent;
162  }
163  return WE;
164 }
165 
166 void WebAssemblyException::print(raw_ostream &OS, unsigned Depth) const {
167  OS.indent(Depth * 2) << "Exception at depth " << getExceptionDepth()
168  << " containing: ";
169 
170  for (unsigned I = 0; I < getBlocks().size(); ++I) {
171  MachineBasicBlock *MBB = getBlocks()[I];
172  if (I)
173  OS << ", ";
174  OS << "%bb." << MBB->getNumber();
175  if (const auto *BB = MBB->getBasicBlock())
176  if (BB->hasName())
177  OS << "." << BB->getName();
178 
179  if (getEHPad() == MBB)
180  OS << " (landing-pad)";
181  }
182  OS << "\n";
183 
184  for (auto &SubE : SubExceptions)
185  SubE->print(OS, Depth + 2);
186 }
187 
188 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
190 #endif
191 
193  WE.print(OS);
194  return OS;
195 }
196 
198  for (auto *WE : TopLevelExceptions)
199  WE->print(OS);
200 }
void DeleteContainerPointers(Container &C)
For a container of pointers, deletes the pointers and then clears the container.
Definition: STLExtras.h:1149
This class represents lattice values for constants.
Definition: AllocatorList.h:24
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
void print(raw_ostream &OS, unsigned Depth=0) const
void print(raw_ostream &OS, const Module *M=nullptr) const override
print - Print out the internal state of the pass.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert &#39;NumSpaces&#39; spaces.
unsigned second
#define DEBUG_TYPE
iterator_range< succ_iterator > successors()
void recalculate(MachineDominatorTree &MDT, const MachineDominanceFrontier &MDF)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:51
WebAssembly Exception true
std::vector< MachineBasicBlock * > & getBlocksVector()
#define LLVM_DUMP_METHOD
Definition: Compiler.h:74
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
Definition: STLExtras.h:267
void addBlock(MachineBasicBlock *MBB)
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they&#39;re not in a MachineFuncti...
This file implements WebAssemblyException information analysis.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
This file contains the declaration of the WebAssembly-specific utility functions. ...
void changeExceptionFor(MachineBasicBlock *MBB, WebAssemblyException *WE)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
This file provides WebAssembly-specific target descriptions.
MachineBasicBlock * getEHPad() const
Represent the analysis usage information of a pass.
iterator_range< po_iterator< T > > post_order(const T &G)
void addTopLevelException(WebAssemblyException *WE)
INITIALIZE_PASS_BEGIN(WebAssemblyExceptionInfo, DEBUG_TYPE, "WebAssembly Exception Information", true, true) INITIALIZE_PASS_END(WebAssemblyExceptionInfo
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
WebAssemblyException * getExceptionFor(const MachineBasicBlock *MBB) const
iterator find(MachineBasicBlock *B)
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
void setParentException(WebAssemblyException *WE)
bool isCatchTerminatePad(const MachineBasicBlock &MBB)
Returns if the given BB is a single BB terminate pad which starts with a &#39;catch&#39; instruction.
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:381
WebAssemblyException * getParentException() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
void setPreservesAll()
Set by analyses that do not transform their input at all.
unsigned succ_size() const
bool isEHPad() const
Returns true if the block is a landing pad.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:56
#define I(x, y, z)
Definition: MD5.cpp:58
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
WebAssembly Exception Information
const std::vector< WebAssemblyException * > & getSubExceptions() const
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
Definition: APInt.h:2039
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
#define LLVM_DEBUG(X)
Definition: Debug.h:123
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool isCatchAllTerminatePad(const MachineBasicBlock &MBB)
Returns if the given BB is a single BB terminate pad which starts with a &#39;catch_all&#39; insrtruction...