LLVM  10.0.0svn
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 
16 #include "WebAssemblyUtilities.h"
20 
21 using namespace llvm;
22 
23 #define DEBUG_TYPE "wasm-exception-info"
24 
26 
28  "WebAssembly Exception Information", true, true)
32  "WebAssembly Exception Information", true, true)
33 
34 bool WebAssemblyExceptionInfo::runOnMachineFunction(MachineFunction &MF) {
35  LLVM_DEBUG(dbgs() << "********** Exception Info Calculation **********\n"
36  "********** Function: "
37  << MF.getName() << '\n');
38  releaseMemory();
39  auto &MDT = getAnalysis<MachineDominatorTree>();
40  auto &MDF = getAnalysis<MachineDominanceFrontier>();
41  recalculate(MDT, MDF);
42  return false;
43 }
44 
47  // Postorder traversal of the dominator tree.
49  for (auto DomNode : post_order(&MDT)) {
50  MachineBasicBlock *EHPad = DomNode->getBlock();
51  if (!EHPad->isEHPad())
52  continue;
53  auto *WE = new WebAssemblyException(EHPad);
54  discoverAndMapException(WE, MDT, MDF);
55  Exceptions.push_back(WE);
56  }
57 
58  // Add BBs to exceptions
59  for (auto DomNode : post_order(&MDT)) {
60  MachineBasicBlock *MBB = DomNode->getBlock();
62  for (; WE; WE = WE->getParentException())
63  WE->addBlock(MBB);
64  }
65 
66  // Add subexceptions to exceptions
67  for (auto *WE : Exceptions) {
68  if (WE->getParentException())
69  WE->getParentException()->getSubExceptions().push_back(WE);
70  else
72  }
73 
74  // For convenience, Blocks and SubExceptions are inserted in postorder.
75  // Reverse the lists.
76  for (auto *WE : Exceptions) {
77  WE->reverseBlock();
78  std::reverse(WE->getSubExceptions().begin(), WE->getSubExceptions().end());
79  }
80 }
81 
83  BBMap.clear();
84  DeleteContainerPointers(TopLevelExceptions);
85  TopLevelExceptions.clear();
86 }
87 
89  AU.setPreservesAll();
93 }
94 
95 void WebAssemblyExceptionInfo::discoverAndMapException(
97  const MachineDominanceFrontier &MDF) {
98  unsigned NumBlocks = 0;
99  unsigned NumSubExceptions = 0;
100 
101  // Map blocks that belong to a catchpad / cleanuppad
102  MachineBasicBlock *EHPad = WE->getEHPad();
104  WL.push_back(EHPad);
105  while (!WL.empty()) {
106  MachineBasicBlock *MBB = WL.pop_back_val();
107 
108  // Find its outermost discovered exception. If this is a discovered block,
109  // check if it is already discovered to be a subexception of this exception.
110  WebAssemblyException *SubE = getOutermostException(MBB);
111  if (SubE) {
112  if (SubE != WE) {
113  // Discover a subexception of this exception.
114  SubE->setParentException(WE);
115  ++NumSubExceptions;
116  NumBlocks += SubE->getBlocksVector().capacity();
117  // All blocks that belong to this subexception have been already
118  // discovered. Skip all of them. Add the subexception's landing pad's
119  // dominance frontier to the worklist.
120  for (auto &Frontier : MDF.find(SubE->getEHPad())->second)
121  if (MDT.dominates(EHPad, Frontier))
122  WL.push_back(Frontier);
123  }
124  continue;
125  }
126 
127  // This is an undiscovered block. Map it to the current exception.
128  changeExceptionFor(MBB, WE);
129  ++NumBlocks;
130 
131  // Add successors dominated by the current BB to the worklist.
132  for (auto *Succ : MBB->successors())
133  if (MDT.dominates(EHPad, Succ))
134  WL.push_back(Succ);
135  }
136 
137  WE->getSubExceptions().reserve(NumSubExceptions);
138  WE->reserveBlocks(NumBlocks);
139 }
140 
142 WebAssemblyExceptionInfo::getOutermostException(MachineBasicBlock *MBB) const {
144  if (WE) {
145  while (WebAssemblyException *Parent = WE->getParentException())
146  WE = Parent;
147  }
148  return WE;
149 }
150 
151 void WebAssemblyException::print(raw_ostream &OS, unsigned Depth) const {
152  OS.indent(Depth * 2) << "Exception at depth " << getExceptionDepth()
153  << " containing: ";
154 
155  for (unsigned I = 0; I < getBlocks().size(); ++I) {
156  MachineBasicBlock *MBB = getBlocks()[I];
157  if (I)
158  OS << ", ";
159  OS << "%bb." << MBB->getNumber();
160  if (const auto *BB = MBB->getBasicBlock())
161  if (BB->hasName())
162  OS << "." << BB->getName();
163 
164  if (getEHPad() == MBB)
165  OS << " (landing-pad)";
166  }
167  OS << "\n";
168 
169  for (auto &SubE : SubExceptions)
170  SubE->print(OS, Depth + 2);
171 }
172 
173 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
175 #endif
176 
178  WE.print(OS);
179  return OS;
180 }
181 
183  for (auto *WE : TopLevelExceptions)
184  WE->print(OS);
185 }
void DeleteContainerPointers(Container &C)
For a container of pointers, deletes the pointers and then clears the container.
Definition: STLExtras.h:1140
This class represents lattice values for constants.
Definition: AllocatorList.h:23
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
Definition: Compiler.h:473
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:50
WebAssembly Exception true
std::vector< MachineBasicBlock * > & getBlocksVector()
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
Definition: STLExtras.h:273
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:837
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
void setParentException(WebAssemblyException *WE)
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:374
WebAssemblyException * getParentException() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
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.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:55
#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:2045
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
#define LLVM_DEBUG(X)
Definition: Debug.h:122
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...