LLVM  12.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 
16 #include "WebAssemblyUtilities.h"
20 #include "llvm/InitializePasses.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  auto WE = std::make_unique<WebAssemblyException>(EHPad);
55  discoverAndMapException(WE.get(), MDT, MDF);
56  Exceptions.push_back(std::move(WE));
57  }
58 
59  // Add BBs to exceptions
60  for (auto DomNode : post_order(&MDT)) {
61  MachineBasicBlock *MBB = DomNode->getBlock();
63  for (; WE; WE = WE->getParentException())
64  WE->addBlock(MBB);
65  }
66 
67  SmallVector<WebAssemblyException*, 8> ExceptionPointers;
68  ExceptionPointers.reserve(Exceptions.size());
69 
70  // Add subexceptions to exceptions
71  for (auto &WE : Exceptions) {
72  ExceptionPointers.push_back(WE.get());
73  if (WE->getParentException())
74  WE->getParentException()->getSubExceptions().push_back(std::move(WE));
75  else
76  addTopLevelException(std::move(WE));
77  }
78 
79  // For convenience, Blocks and SubExceptions are inserted in postorder.
80  // Reverse the lists.
81  for (auto *WE : ExceptionPointers) {
82  WE->reverseBlock();
83  std::reverse(WE->getSubExceptions().begin(), WE->getSubExceptions().end());
84  }
85 }
86 
88  BBMap.clear();
89  TopLevelExceptions.clear();
90 }
91 
93  AU.setPreservesAll();
97 }
98 
99 void WebAssemblyExceptionInfo::discoverAndMapException(
101  const MachineDominanceFrontier &MDF) {
102  unsigned NumBlocks = 0;
103  unsigned NumSubExceptions = 0;
104 
105  // Map blocks that belong to a catchpad / cleanuppad
106  MachineBasicBlock *EHPad = WE->getEHPad();
108  WL.push_back(EHPad);
109  while (!WL.empty()) {
111 
112  // Find its outermost discovered exception. If this is a discovered block,
113  // check if it is already discovered to be a subexception of this exception.
114  WebAssemblyException *SubE = getOutermostException(MBB);
115  if (SubE) {
116  if (SubE != WE) {
117  // Discover a subexception of this exception.
118  SubE->setParentException(WE);
119  ++NumSubExceptions;
120  NumBlocks += SubE->getBlocksVector().capacity();
121  // All blocks that belong to this subexception have been already
122  // discovered. Skip all of them. Add the subexception's landing pad's
123  // dominance frontier to the worklist.
124  for (auto &Frontier : MDF.find(SubE->getEHPad())->second)
125  if (MDT.dominates(EHPad, Frontier))
126  WL.push_back(Frontier);
127  }
128  continue;
129  }
130 
131  // This is an undiscovered block. Map it to the current exception.
132  changeExceptionFor(MBB, WE);
133  ++NumBlocks;
134 
135  // Add successors dominated by the current BB to the worklist.
136  for (auto *Succ : MBB->successors())
137  if (MDT.dominates(EHPad, Succ))
138  WL.push_back(Succ);
139  }
140 
141  WE->getSubExceptions().reserve(NumSubExceptions);
142  WE->reserveBlocks(NumBlocks);
143 }
144 
146 WebAssemblyExceptionInfo::getOutermostException(MachineBasicBlock *MBB) const {
148  if (WE) {
149  while (WebAssemblyException *Parent = WE->getParentException())
150  WE = Parent;
151  }
152  return WE;
153 }
154 
155 void WebAssemblyException::print(raw_ostream &OS, unsigned Depth) const {
156  OS.indent(Depth * 2) << "Exception at depth " << getExceptionDepth()
157  << " containing: ";
158 
159  for (unsigned I = 0; I < getBlocks().size(); ++I) {
160  MachineBasicBlock *MBB = getBlocks()[I];
161  if (I)
162  OS << ", ";
163  OS << "%bb." << MBB->getNumber();
164  if (const auto *BB = MBB->getBasicBlock())
165  if (BB->hasName())
166  OS << "." << BB->getName();
167 
168  if (getEHPad() == MBB)
169  OS << " (landing-pad)";
170  }
171  OS << "\n";
172 
173  for (auto &SubE : SubExceptions)
174  SubE->print(OS, Depth + 2);
175 }
176 
177 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
179 #endif
180 
182  WE.print(OS);
183  return OS;
184 }
185 
187  for (auto &WE : TopLevelExceptions)
188  WE->print(OS);
189 }
const std::vector< std::unique_ptr< WebAssemblyException > > & getSubExceptions() const
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:508
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:67
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.
void reserve(size_type N)
Definition: SmallVector.h:415
#define DEBUG_TYPE
iterator_range< succ_iterator > successors()
MachineBasicBlock & MBB
void recalculate(MachineDominatorTree &MDT, const MachineDominanceFrontier &MDF)
AnalysisUsage & addRequired()
WebAssembly Exception true
std::vector< MachineBasicBlock * > & getBlocksVector()
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)
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:883
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
void setParentException(WebAssemblyException *WE)
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:420
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.
void addTopLevelException(std::unique_ptr< WebAssemblyException > WE)
bool isEHPad() const
Returns true if the block is a landing pad.
#define I(x, y, z)
Definition: MD5.cpp:59
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
WebAssembly Exception Information
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
Definition: APInt.h:2099
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
Definition: STLExtras.h:341
#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...
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)