LLVM: lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

25

26using namespace llvm;

27

28#define DEBUG_TYPE "wasm-exception-info"

29

31

33 "WebAssembly Exception Information", true, true)

37 "WebAssembly Exception Information", true, true)

38

40 LLVM_DEBUG(dbgs() << "********** Exception Info Calculation **********\n"

41 "********** Function: "

42 << MF.getName() << '\n');

44 if (MF.getTarget().getMCAsmInfo()->getExceptionHandlingType() !=

46 !MF.getFunction().hasPersonalityFn())

47 return false;

52 return false;

53}

54

55

56

65

66 while (!WL.empty()) {

68 if (MBB == Dst)

69 return true;

71 for (auto *Succ : MBB->successors())

72 if (!Visited.count(Succ) && MDT.dominates(Header, Succ))

74 }

75 return false;

76}

77

81

83 for (auto *DomNode : post_order(&MDT)) {

86 continue;

87 auto WE = std::make_unique(EHPad);

88 discoverAndMapException(WE.get(), MDT, MDF);

89 Exceptions.push_back(std::move(WE));

90 }

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

126 UnwindWEVec;

127 for (auto *DomNode : depth_first(&MDT)) {

130 continue;

131 if (!EHInfo->hasUnwindDest(EHPad))

132 continue;

133 auto *UnwindDest = EHInfo->getUnwindDest(EHPad);

136 if (SrcWE->contains(DstWE)) {

137 UnwindWEVec.push_back(std::make_pair(SrcWE, DstWE));

138 LLVM_DEBUG(dbgs() << "Unwind destination ExceptionInfo fix:\n "

139 << DstWE->getEHPad()->getNumber() << "."

140 << DstWE->getEHPad()->getName()

141 << "'s exception is taken out of "

142 << SrcWE->getEHPad()->getNumber() << "."

143 << SrcWE->getEHPad()->getName() << "'s exception\n");

144 DstWE->setParentException(SrcWE->getParentException());

145 }

146 }

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166 for (auto *DomNode : depth_first(&MDT)) {

169 continue;

171

172

173 for (auto &P : UnwindWEVec) {

174 auto *SrcWE = P.first;

175 auto *DstWE = P.second;

176

177

178

179 if (WE != SrcWE && SrcWE->contains(WE) && !DstWE->contains(WE) &&

181 MDT)) {

182 LLVM_DEBUG(dbgs() << "Remaining reachable ExceptionInfo fix:\n "

183 << WE->getEHPad()->getNumber() << "."

184 << WE->getEHPad()->getName()

185 << "'s exception is taken out of "

186 << SrcWE->getEHPad()->getNumber() << "."

187 << SrcWE->getEHPad()->getName() << "'s exception\n");

188 WE->setParentException(SrcWE->getParentException());

189 }

190 }

191 }

192

193

194

195

196 for (auto *DomNode : post_order(&MDT)) {

201 }

202

203

204

205

206 for (auto &P : UnwindWEVec) {

207 auto *SrcWE = P.first;

208 auto *DstWE = P.second;

209

211 if (MBB->isEHPad()) {

213 SrcWE->getEHPad(), MDT) &&

214 "We already handled EH pads above");

215 return false;

216 }

218 MDT)) {

220 << MBB->getName() << " is\n");

222 while (InnerWE != SrcWE) {

226 << "'s exception\n");

229 }

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);

236 return true;

237 }

238 return false;

239 });

240 }

241

242

243 for (auto *DomNode : post_order(&MDT)) {

248 }

249

251 ExceptionPointers.reserve(Exceptions.size());

252

253

254 for (auto &WE : Exceptions) {

255 ExceptionPointers.push_back(WE.get());

256 if (WE->getParentException())

257 WE->getParentException()->getSubExceptions().push_back(std::move(WE));

258 else

260 }

261

262

263

264 for (auto *WE : ExceptionPointers) {

265 WE->reverseBlock();

266 std::reverse(WE->getSubExceptions().begin(), WE->getSubExceptions().end());

267 }

268}

269

271 BBMap.clear();

272 TopLevelExceptions.clear();

273}

274

281

282void WebAssemblyExceptionInfo::discoverAndMapException(

285 unsigned NumBlocks = 0;

286 unsigned NumSubExceptions = 0;

287

288

292 while (!WL.empty()) {

294

295

296

298 if (SubE) {

299 if (SubE != WE) {

300

302 ++NumSubExceptions;

304

305

306

307 for (auto &Frontier : MDF.find(SubE->getEHPad())->second)

308 if (MDT.dominates(EHPad, Frontier))

310 }

311 continue;

312 }

313

314

316 ++NumBlocks;

317

318

322 }

323

326}

327

329WebAssemblyExceptionInfo::getOutermostException(MachineBasicBlock *MBB) const {

331 if (WE) {

333 WE = Parent;

334 }

335 return WE;

336}

337

340 << " containing: ";

341

342 for (unsigned I = 0; I < getBlocks().size(); ++I) {

344 if (I)

345 OS << ", ";

346 OS << "%bb." << MBB->getNumber();

347 if (const auto *BB = MBB->getBasicBlock())

348 if (BB->hasName())

349 OS << "." << BB->getName();

350

352 OS << " (landing-pad)";

353 }

354 OS << "\n";

355

356 for (auto &SubE : SubExceptions)

358}

359

360#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

362#endif

363

368

370 for (auto &WE : TopLevelExceptions)

372}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

#define LLVM_DUMP_METHOD

Mark debug helper function definitions like dump() that should not be stripped from debug builds.

This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.

#define INITIALIZE_PASS_DEPENDENCY(depName)

#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)

#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)

This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.

static bool isReachableAmongDominated(const MachineBasicBlock *Src, const MachineBasicBlock *Dst, const MachineBasicBlock *Header, const MachineDominatorTree &MDT)

Definition WebAssemblyExceptionInfo.cpp:57

This file implements WebAssemblyException information analysis.

This file contains the declaration of the WebAssembly-specific utility functions.

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

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.

int getNumber() const

MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...

iterator_range< succ_iterator > successors()

LLVM_ABI StringRef getName() const

Return the name of the corresponding LLVM basic block, or an empty string.

iterator find(MachineBasicBlock *B)

Analysis pass which computes a MachineDominatorTree.

DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...

bool dominates(const MachineInstr *A, const MachineInstr *B) const

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

const WasmEHFuncInfo * getWasmEHFuncInfo() const

getWasmEHFuncInfo - Return information about how the current function uses Wasm exception handling.

A Module instance is used to store all the information related to an LLVM module.

AnalysisType & getAnalysis() const

getAnalysis() - This function is used by subclasses to get to the analysis information ...

size_type count(ConstPtrType Ptr) const

count - Return 1 if the specified pointer is in the set, 0 otherwise.

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

void reserve(size_type N)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

WebAssemblyExceptionInfo()

void changeExceptionFor(const MachineBasicBlock *MBB, WebAssemblyException *WE)

bool runOnMachineFunction(MachineFunction &) override

runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...

Definition WebAssemblyExceptionInfo.cpp:39

void addTopLevelException(std::unique_ptr< WebAssemblyException > WE)

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

Definition WebAssemblyExceptionInfo.cpp:275

void recalculate(MachineFunction &MF, MachineDominatorTree &MDT, const MachineDominanceFrontier &MDF)

Definition WebAssemblyExceptionInfo.cpp:78

WebAssemblyException * getExceptionFor(const MachineBasicBlock *MBB) const

void print(raw_ostream &OS, const Module *M=nullptr) const override

print - Print out the internal state of the pass.

Definition WebAssemblyExceptionInfo.cpp:369

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:270

void print(raw_ostream &OS, unsigned Depth=0) const

Definition WebAssemblyExceptionInfo.cpp:338

MachineBasicBlock * getEHPad() const

void addToBlocksSet(MachineBasicBlock *MBB)

void dump() const

Definition WebAssemblyExceptionInfo.cpp:361

void reserveBlocks(unsigned Size)

const std::vector< std::unique_ptr< WebAssemblyException > > & getSubExceptions() const

ArrayRef< MachineBasicBlock * > getBlocks() const

std::vector< MachineBasicBlock * > & getBlocksVector()

WebAssemblyException * getParentException() const

void removeFromBlocksSet(MachineBasicBlock *MBB)

unsigned getExceptionDepth() const

void setParentException(WebAssemblyException *WE)

void addToBlocksVector(MachineBasicBlock *MBB)

This class implements an extremely fast bulk output stream that can only output to a stream.

raw_ostream & indent(unsigned NumSpaces)

indent - Insert 'NumSpaces' spaces.

This is an optimization pass for GlobalISel generic memory operations.

void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)

@ Wasm

WebAssembly Exception Handling.

iterator_range< po_iterator< T > > post_order(const T &G)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)

iterator_range< df_iterator< T > > depth_first(const T &G)