LLVM 22.0.0git
WinEHPrepare.cpp
Go to the documentation of this file.
1//===-- WinEHPrepare - Prepare exception handling for code generation ---===//
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// This pass lowers LLVM IR exception handling into something closer to what the
10// backend wants for functions using a personality function from a runtime
11// provided by MSVC. Functions with other personality functions are left alone
12// and may be prepared by other passes. In particular, all supported MSVC
13// personality functions require cleanup code to be outlined, and the C++
14// personality requires catch handler code to be outlined.
15//
16//===----------------------------------------------------------------------===//
17
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/MapVector.h"
21#include "llvm/ADT/STLExtras.h"
23#include "llvm/CodeGen/Passes.h"
25#include "llvm/IR/Constants.h"
28#include "llvm/IR/Module.h"
29#include "llvm/IR/Verifier.h"
31#include "llvm/Pass.h"
33#include "llvm/Support/Debug.h"
40
41using namespace llvm;
42
43#define DEBUG_TYPE "win-eh-prepare"
44
46 "disable-demotion", cl::Hidden,
48 "Clone multicolor basic blocks but do not demote cross scopes"),
49 cl::init(false));
50
52 "disable-cleanups", cl::Hidden,
53 cl::desc("Do not remove implausible terminators or other similar cleanups"),
54 cl::init(false));
55
56// TODO: Remove this option when we fully migrate to new pass manager
58 "demote-catchswitch-only", cl::Hidden,
59 cl::desc("Demote catchswitch BBs only (for wasm EH)"), cl::init(false));
60
61namespace {
62
63class WinEHPrepareImpl {
64public:
65 WinEHPrepareImpl(bool DemoteCatchSwitchPHIOnly)
66 : DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {}
67
68 bool runOnFunction(Function &Fn);
69
70private:
71 void insertPHIStores(PHINode *OriginalPHI, AllocaInst *SpillSlot);
72 void
73 insertPHIStore(BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
74 SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist);
75 AllocaInst *insertPHILoads(PHINode *PN, Function &F);
76 void replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
77 DenseMap<BasicBlock *, Value *> &Loads, Function &F);
78 bool prepareExplicitEH(Function &F);
79 void colorFunclets(Function &F);
80
81 bool demotePHIsOnFunclets(Function &F, bool DemoteCatchSwitchPHIOnly);
82 bool cloneCommonBlocks(Function &F);
83 bool removeImplausibleInstructions(Function &F);
84 bool cleanupPreparedFunclets(Function &F);
85 void verifyPreparedFunclets(Function &F);
86
87 bool DemoteCatchSwitchPHIOnly;
88
89 // All fields are reset by runOnFunction.
90 EHPersonality Personality = EHPersonality::Unknown;
91
92 const DataLayout *DL = nullptr;
93 DenseMap<BasicBlock *, ColorVector> BlockColors;
94 MapVector<BasicBlock *, std::vector<BasicBlock *>> FuncletBlocks;
95};
96
97class WinEHPrepare : public FunctionPass {
98 bool DemoteCatchSwitchPHIOnly;
99
100public:
101 static char ID; // Pass identification, replacement for typeid.
102
103 WinEHPrepare(bool DemoteCatchSwitchPHIOnly = false)
104 : FunctionPass(ID), DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {}
105
106 StringRef getPassName() const override {
107 return "Windows exception handling preparation";
108 }
109
110 bool runOnFunction(Function &Fn) override {
111 return WinEHPrepareImpl(DemoteCatchSwitchPHIOnly).runOnFunction(Fn);
112 }
113};
114
115} // end anonymous namespace
116
119 bool Changed = WinEHPrepareImpl(DemoteCatchSwitchPHIOnly).runOnFunction(F);
121}
122
123char WinEHPrepare::ID = 0;
124INITIALIZE_PASS(WinEHPrepare, DEBUG_TYPE, "Prepare Windows exceptions", false,
125 false)
126
127FunctionPass *llvm::createWinEHPass(bool DemoteCatchSwitchPHIOnly) {
128 return new WinEHPrepare(DemoteCatchSwitchPHIOnly);
129}
130
131bool WinEHPrepareImpl::runOnFunction(Function &Fn) {
132 if (!Fn.hasPersonalityFn())
133 return false;
134
135 // Classify the personality to see what kind of preparation we need.
136 Personality = classifyEHPersonality(Fn.getPersonalityFn());
137
138 // Do nothing if this is not a scope-based personality.
139 if (!isScopedEHPersonality(Personality))
140 return false;
141
142 DL = &Fn.getDataLayout();
143 return prepareExplicitEH(Fn);
144}
145
146static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState,
147 const BasicBlock *BB) {
149 UME.ToState = ToState;
150 UME.Cleanup = BB;
151 FuncInfo.CxxUnwindMap.push_back(UME);
152 return FuncInfo.getLastStateNumber();
153}
154
155static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow,
156 int TryHigh, int CatchHigh,
159 TBME.TryLow = TryLow;
160 TBME.TryHigh = TryHigh;
161 TBME.CatchHigh = CatchHigh;
162 assert(TBME.TryLow <= TBME.TryHigh);
163 for (const CatchPadInst *CPI : Handlers) {
165 Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0));
166 if (TypeInfo->isNullValue())
167 HT.TypeDescriptor = nullptr;
168 else
170 HT.Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue();
171 HT.Handler = CPI->getParent();
172 if (auto *AI =
173 dyn_cast<AllocaInst>(CPI->getArgOperand(2)->stripPointerCasts()))
174 HT.CatchObj.Alloca = AI;
175 else
176 HT.CatchObj.Alloca = nullptr;
177 TBME.HandlerArray.push_back(HT);
178 }
179 FuncInfo.TryBlockMap.push_back(TBME);
180}
181
183 for (const User *U : CleanupPad->users())
184 if (const auto *CRI = dyn_cast<CleanupReturnInst>(U))
185 return CRI->getUnwindDest();
186 return nullptr;
187}
188
190 WinEHFuncInfo &FuncInfo) {
191 auto *F = const_cast<Function *>(Fn);
193 for (BasicBlock &BB : *F) {
194 auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
195 if (!II)
196 continue;
197
198 auto &BBColors = BlockColors[&BB];
199 assert(BBColors.size() == 1 && "multi-color BB not removed by preparation");
200 BasicBlock *FuncletEntryBB = BBColors.front();
201
202 BasicBlock *FuncletUnwindDest;
203 auto *FuncletPad =
205 assert(FuncletPad || FuncletEntryBB == &Fn->getEntryBlock());
206 if (!FuncletPad)
207 FuncletUnwindDest = nullptr;
208 else if (auto *CatchPad = dyn_cast<CatchPadInst>(FuncletPad))
209 FuncletUnwindDest = CatchPad->getCatchSwitch()->getUnwindDest();
210 else if (auto *CleanupPad = dyn_cast<CleanupPadInst>(FuncletPad))
211 FuncletUnwindDest = getCleanupRetUnwindDest(CleanupPad);
212 else
213 llvm_unreachable("unexpected funclet pad!");
214
215 BasicBlock *InvokeUnwindDest = II->getUnwindDest();
216 int BaseState = -1;
217 if (FuncletUnwindDest == InvokeUnwindDest) {
218 auto BaseStateI = FuncInfo.FuncletBaseStateMap.find(FuncletPad);
219 if (BaseStateI != FuncInfo.FuncletBaseStateMap.end())
220 BaseState = BaseStateI->second;
221 }
222
223 if (BaseState != -1) {
224 FuncInfo.InvokeStateMap[II] = BaseState;
225 } else {
226 Instruction *PadInst = &*InvokeUnwindDest->getFirstNonPHIIt();
227 assert(FuncInfo.EHPadStateMap.count(PadInst) && "EH Pad has no state!");
228 FuncInfo.InvokeStateMap[II] = FuncInfo.EHPadStateMap[PadInst];
229 }
230 }
231}
232
233// See comments below for calculateSEHStateForAsynchEH().
234// State - incoming State of normal paths
235struct WorkItem {
237 int State;
238 WorkItem(const BasicBlock *BB, int St) {
239 Block = BB;
240 State = St;
241 }
242};
244 WinEHFuncInfo &EHInfo) {
246 struct WorkItem *WI = new WorkItem(BB, State);
247 WorkList.push_back(WI);
248
249 while (!WorkList.empty()) {
250 WI = WorkList.pop_back_val();
251 const BasicBlock *BB = WI->Block;
252 int State = WI->State;
253 delete WI;
254 auto [StateIt, Inserted] = EHInfo.BlockToStateMap.try_emplace(BB);
255 if (!Inserted && StateIt->second <= State)
256 continue; // skip blocks already visited by lower State
257
259 const llvm::Instruction *TI = BB->getTerminator();
260 if (It->isEHPad())
261 State = EHInfo.EHPadStateMap[&*It];
262 StateIt->second = State; // Record state, also flag visiting
263
264 if ((isa<CleanupReturnInst>(TI) || isa<CatchReturnInst>(TI)) && State > 0) {
265 // Retrive the new State
266 State = EHInfo.CxxUnwindMap[State].ToState; // Retrive next State
267 } else if (isa<InvokeInst>(TI)) {
268 auto *Call = cast<CallBase>(TI);
269 const Function *Fn = Call->getCalledFunction();
270 if (Fn && Fn->isIntrinsic() &&
271 (Fn->getIntrinsicID() == Intrinsic::seh_scope_begin ||
272 Fn->getIntrinsicID() == Intrinsic::seh_try_begin))
273 // Retrive the new State from seh_scope_begin
274 State = EHInfo.InvokeStateMap[cast<InvokeInst>(TI)];
275 else if (Fn && Fn->isIntrinsic() &&
276 (Fn->getIntrinsicID() == Intrinsic::seh_scope_end ||
277 Fn->getIntrinsicID() == Intrinsic::seh_try_end)) {
278 // In case of conditional ctor, let's retrieve State from Invoke
279 State = EHInfo.InvokeStateMap[cast<InvokeInst>(TI)];
280 // end of current state, retrive new state from UnwindMap
281 State = EHInfo.CxxUnwindMap[State].ToState;
282 }
283 }
284 // Continue push successors into worklist
285 for (auto *SuccBB : successors(BB)) {
286 WI = new WorkItem(SuccBB, State);
287 WorkList.push_back(WI);
288 }
289 }
290}
291
292// The central theory of this routine is based on the following:
293// A _try scope is always a SEME (Single Entry Multiple Exits) region
294// as jumping into a _try is not allowed
295// The single entry must start with a seh_try_begin() invoke with a
296// correct State number that is the initial state of the SEME.
297// Through control-flow, state number is propagated into all blocks.
298// Side exits marked by seh_try_end() will unwind to parent state via
299// existing SEHUnwindMap[].
300// Side exits can ONLY jump into parent scopes (lower state number).
301// Thus, when a block succeeds various states from its predecessors,
302// the lowest State trumphs others.
303// If some exits flow to unreachable, propagation on those paths terminate,
304// not affecting remaining blocks.
306 WinEHFuncInfo &EHInfo) {
308 struct WorkItem *WI = new WorkItem(BB, State);
309 WorkList.push_back(WI);
310
311 while (!WorkList.empty()) {
312 WI = WorkList.pop_back_val();
313 const BasicBlock *BB = WI->Block;
314 int State = WI->State;
315 delete WI;
316 if (auto It = EHInfo.BlockToStateMap.find(BB);
317 It != EHInfo.BlockToStateMap.end() && It->second <= State)
318 continue; // skip blocks already visited by lower State
319
321 const llvm::Instruction *TI = BB->getTerminator();
322 if (It->isEHPad())
323 State = EHInfo.EHPadStateMap[&*It];
324 EHInfo.BlockToStateMap[BB] = State; // Record state
325
327 const Constant *FilterOrNull = cast<Constant>(
328 cast<CatchPadInst>(It)->getArgOperand(0)->stripPointerCasts());
329 const Function *Filter = dyn_cast<Function>(FilterOrNull);
330 if (!Filter || !Filter->getName().starts_with("__IsLocalUnwind"))
331 State = EHInfo.SEHUnwindMap[State].ToState; // Retrive next State
332 } else if ((isa<CleanupReturnInst>(TI) || isa<CatchReturnInst>(TI)) &&
333 State > 0) {
334 // Retrive the new State.
335 State = EHInfo.SEHUnwindMap[State].ToState; // Retrive next State
336 } else if (isa<InvokeInst>(TI)) {
337 auto *Call = cast<CallBase>(TI);
338 const Function *Fn = Call->getCalledFunction();
339 if (Fn && Fn->isIntrinsic() &&
340 Fn->getIntrinsicID() == Intrinsic::seh_try_begin)
341 // Retrive the new State from seh_try_begin
342 State = EHInfo.InvokeStateMap[cast<InvokeInst>(TI)];
343 else if (Fn && Fn->isIntrinsic() &&
344 Fn->getIntrinsicID() == Intrinsic::seh_try_end)
345 // end of current state, retrive new state from UnwindMap
346 State = EHInfo.SEHUnwindMap[State].ToState;
347 }
348 // Continue push successors into worklist
349 for (auto *SuccBB : successors(BB)) {
350 WI = new WorkItem(SuccBB, State);
351 WorkList.push_back(WI);
352 }
353 }
354}
355
356// Given BB which ends in an unwind edge, return the EHPad that this BB belongs
357// to. If the unwind edge came from an invoke, return null.
359 Value *ParentPad) {
360 const Instruction *TI = BB->getTerminator();
361 if (isa<InvokeInst>(TI))
362 return nullptr;
363 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(TI)) {
364 if (CatchSwitch->getParentPad() != ParentPad)
365 return nullptr;
366 return BB;
367 }
368 assert(!TI->isEHPad() && "unexpected EHPad!");
369 auto *CleanupPad = cast<CleanupReturnInst>(TI)->getCleanupPad();
370 if (CleanupPad->getParentPad() != ParentPad)
371 return nullptr;
372 return CleanupPad->getParent();
373}
374
375// Starting from a EHPad, Backward walk through control-flow graph
376// to produce two primary outputs:
377// FuncInfo.EHPadStateMap[] and FuncInfo.CxxUnwindMap[]
379 const Instruction *FirstNonPHI,
380 int ParentState) {
381 const BasicBlock *BB = FirstNonPHI->getParent();
382 assert(BB->isEHPad() && "not a funclet!");
383
384 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
385 assert(FuncInfo.EHPadStateMap.count(CatchSwitch) == 0 &&
386 "shouldn't revist catch funclets!");
387
389 for (const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
390 auto *CatchPad = cast<CatchPadInst>(CatchPadBB->getFirstNonPHIIt());
391 Handlers.push_back(CatchPad);
392 }
393 int TryLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
394 FuncInfo.EHPadStateMap[CatchSwitch] = TryLow;
395 for (const BasicBlock *PredBlock : predecessors(BB))
396 if ((PredBlock = getEHPadFromPredecessor(PredBlock,
397 CatchSwitch->getParentPad())))
398 calculateCXXStateNumbers(FuncInfo, &*PredBlock->getFirstNonPHIIt(),
399 TryLow);
400 int CatchLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
401
402 // catchpads are separate funclets in C++ EH due to the way rethrow works.
403 int TryHigh = CatchLow - 1;
404
405 // MSVC FrameHandler3/4 on x64&Arm64 expect Catch Handlers in $tryMap$
406 // stored in pre-order (outer first, inner next), not post-order
407 // Add to map here. Fix the CatchHigh after children are processed
408 const Module *Mod = BB->getParent()->getParent();
409 bool IsPreOrder = Mod->getTargetTriple().isArch64Bit();
410 if (IsPreOrder)
411 addTryBlockMapEntry(FuncInfo, TryLow, TryHigh, CatchLow, Handlers);
412 unsigned TBMEIdx = FuncInfo.TryBlockMap.size() - 1;
413
414 for (const auto *CatchPad : Handlers) {
415 FuncInfo.FuncletBaseStateMap[CatchPad] = CatchLow;
416 FuncInfo.EHPadStateMap[CatchPad] = CatchLow;
417 for (const User *U : CatchPad->users()) {
418 const auto *UserI = cast<Instruction>(U);
419 if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
420 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
421 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
422 calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
423 }
424 if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
425 BasicBlock *UnwindDest = getCleanupRetUnwindDest(InnerCleanupPad);
426 // If a nested cleanup pad reports a null unwind destination and the
427 // enclosing catch pad doesn't it must be post-dominated by an
428 // unreachable instruction.
429 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
430 calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
431 }
432 }
433 }
434 int CatchHigh = FuncInfo.getLastStateNumber();
435 // Now child Catches are processed, update CatchHigh
436 if (IsPreOrder)
437 FuncInfo.TryBlockMap[TBMEIdx].CatchHigh = CatchHigh;
438 else // PostOrder
439 addTryBlockMapEntry(FuncInfo, TryLow, TryHigh, CatchHigh, Handlers);
440
441 LLVM_DEBUG(dbgs() << "TryLow[" << BB->getName() << "]: " << TryLow << '\n');
442 LLVM_DEBUG(dbgs() << "TryHigh[" << BB->getName() << "]: " << TryHigh
443 << '\n');
444 LLVM_DEBUG(dbgs() << "CatchHigh[" << BB->getName() << "]: " << CatchHigh
445 << '\n');
446 } else {
447 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
448
449 // It's possible for a cleanup to be visited twice: it might have multiple
450 // cleanupret instructions.
451 auto [It, Inserted] = FuncInfo.EHPadStateMap.try_emplace(CleanupPad);
452 if (!Inserted)
453 return;
454
455 int CleanupState = addUnwindMapEntry(FuncInfo, ParentState, BB);
456 It->second = CleanupState;
457 LLVM_DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
458 << BB->getName() << '\n');
459 for (const BasicBlock *PredBlock : predecessors(BB)) {
460 if ((PredBlock = getEHPadFromPredecessor(PredBlock,
461 CleanupPad->getParentPad()))) {
462 calculateCXXStateNumbers(FuncInfo, &*PredBlock->getFirstNonPHIIt(),
463 CleanupState);
464 }
465 }
466 for (const User *U : CleanupPad->users()) {
467 const auto *UserI = cast<Instruction>(U);
468 if (UserI->isEHPad())
469 report_fatal_error("Cleanup funclets for the MSVC++ personality cannot "
470 "contain exceptional actions");
471 }
472 }
473}
474
475static int addSEHExcept(WinEHFuncInfo &FuncInfo, int ParentState,
476 const Function *Filter, const BasicBlock *Handler) {
477 SEHUnwindMapEntry Entry;
478 Entry.ToState = ParentState;
479 Entry.IsFinally = false;
480 Entry.Filter = Filter;
481 Entry.Handler = Handler;
482 FuncInfo.SEHUnwindMap.push_back(Entry);
483 return FuncInfo.SEHUnwindMap.size() - 1;
484}
485
486static int addSEHFinally(WinEHFuncInfo &FuncInfo, int ParentState,
487 const BasicBlock *Handler) {
488 SEHUnwindMapEntry Entry;
489 Entry.ToState = ParentState;
490 Entry.IsFinally = true;
491 Entry.Filter = nullptr;
492 Entry.Handler = Handler;
493 FuncInfo.SEHUnwindMap.push_back(Entry);
494 return FuncInfo.SEHUnwindMap.size() - 1;
495}
496
497// Starting from a EHPad, Backward walk through control-flow graph
498// to produce two primary outputs:
499// FuncInfo.EHPadStateMap[] and FuncInfo.SEHUnwindMap[]
501 const Instruction *FirstNonPHI,
502 int ParentState) {
503 const BasicBlock *BB = FirstNonPHI->getParent();
504 assert(BB->isEHPad() && "no a funclet!");
505
506 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
507 assert(FuncInfo.EHPadStateMap.count(CatchSwitch) == 0 &&
508 "shouldn't revist catch funclets!");
509
510 // Extract the filter function and the __except basic block and create a
511 // state for them.
512 assert(CatchSwitch->getNumHandlers() == 1 &&
513 "SEH doesn't have multiple handlers per __try");
514 const auto *CatchPad =
515 cast<CatchPadInst>((*CatchSwitch->handler_begin())->getFirstNonPHIIt());
516 const BasicBlock *CatchPadBB = CatchPad->getParent();
517 const Constant *FilterOrNull =
518 cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts());
519 const Function *Filter = dyn_cast<Function>(FilterOrNull);
520 assert((Filter || FilterOrNull->isNullValue()) &&
521 "unexpected filter value");
522 int TryState = addSEHExcept(FuncInfo, ParentState, Filter, CatchPadBB);
523
524 // Everything in the __try block uses TryState as its parent state.
525 FuncInfo.EHPadStateMap[CatchSwitch] = TryState;
526 FuncInfo.EHPadStateMap[CatchPad] = TryState;
527 LLVM_DEBUG(dbgs() << "Assigning state #" << TryState << " to BB "
528 << CatchPadBB->getName() << '\n');
529 for (const BasicBlock *PredBlock : predecessors(BB))
530 if ((PredBlock = getEHPadFromPredecessor(PredBlock,
531 CatchSwitch->getParentPad())))
532 calculateSEHStateNumbers(FuncInfo, &*PredBlock->getFirstNonPHIIt(),
533 TryState);
534
535 // Everything in the __except block unwinds to ParentState, just like code
536 // outside the __try.
537 for (const User *U : CatchPad->users()) {
538 const auto *UserI = cast<Instruction>(U);
539 if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
540 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
541 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
542 calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
543 }
544 if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
545 BasicBlock *UnwindDest = getCleanupRetUnwindDest(InnerCleanupPad);
546 // If a nested cleanup pad reports a null unwind destination and the
547 // enclosing catch pad doesn't it must be post-dominated by an
548 // unreachable instruction.
549 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
550 calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
551 }
552 }
553 } else {
554 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
555
556 // It's possible for a cleanup to be visited twice: it might have multiple
557 // cleanupret instructions.
558 auto [It, Inserted] = FuncInfo.EHPadStateMap.try_emplace(CleanupPad);
559 if (!Inserted)
560 return;
561
562 int CleanupState = addSEHFinally(FuncInfo, ParentState, BB);
563 It->second = CleanupState;
564 LLVM_DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
565 << BB->getName() << '\n');
566 for (const BasicBlock *PredBlock : predecessors(BB))
567 if ((PredBlock =
568 getEHPadFromPredecessor(PredBlock, CleanupPad->getParentPad())))
569 calculateSEHStateNumbers(FuncInfo, &*PredBlock->getFirstNonPHIIt(),
570 CleanupState);
571 for (const User *U : CleanupPad->users()) {
572 const auto *UserI = cast<Instruction>(U);
573 if (UserI->isEHPad())
574 report_fatal_error("Cleanup funclets for the SEH personality cannot "
575 "contain exceptional actions");
576 }
577 }
578}
579
580static bool isTopLevelPadForMSVC(const Instruction *EHPad) {
581 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(EHPad))
582 return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) &&
583 CatchSwitch->unwindsToCaller();
584 if (auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad))
585 return isa<ConstantTokenNone>(CleanupPad->getParentPad()) &&
586 getCleanupRetUnwindDest(CleanupPad) == nullptr;
587 if (isa<CatchPadInst>(EHPad))
588 return false;
589 llvm_unreachable("unexpected EHPad!");
590}
591
593 WinEHFuncInfo &FuncInfo) {
594 // Don't compute state numbers twice.
595 if (!FuncInfo.SEHUnwindMap.empty())
596 return;
597
598 for (const BasicBlock &BB : *Fn) {
599 if (!BB.isEHPad())
600 continue;
601 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
602 if (!isTopLevelPadForMSVC(FirstNonPHI))
603 continue;
604 ::calculateSEHStateNumbers(FuncInfo, FirstNonPHI, -1);
605 }
606
608
609 bool IsEHa = Fn->getParent()->getModuleFlag("eh-asynch");
610 if (IsEHa) {
611 const BasicBlock *EntryBB = &(Fn->getEntryBlock());
612 calculateSEHStateForAsynchEH(EntryBB, -1, FuncInfo);
613 }
614}
615
617 WinEHFuncInfo &FuncInfo) {
618 // Return if it's already been done.
619 if (!FuncInfo.EHPadStateMap.empty())
620 return;
621
622 for (const BasicBlock &BB : *Fn) {
623 if (!BB.isEHPad())
624 continue;
625 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
626 if (!isTopLevelPadForMSVC(FirstNonPHI))
627 continue;
628 calculateCXXStateNumbers(FuncInfo, FirstNonPHI, -1);
629 }
630
632
633 bool IsEHa = Fn->getParent()->getModuleFlag("eh-asynch");
634 if (IsEHa) {
635 const BasicBlock *EntryBB = &(Fn->getEntryBlock());
636 calculateCXXStateForAsynchEH(EntryBB, -1, FuncInfo);
637 }
638}
639
640static int addClrEHHandler(WinEHFuncInfo &FuncInfo, int HandlerParentState,
641 int TryParentState, ClrHandlerType HandlerType,
642 uint32_t TypeToken, const BasicBlock *Handler) {
644 Entry.HandlerParentState = HandlerParentState;
645 Entry.TryParentState = TryParentState;
646 Entry.Handler = Handler;
647 Entry.HandlerType = HandlerType;
648 Entry.TypeToken = TypeToken;
649 FuncInfo.ClrEHUnwindMap.push_back(Entry);
650 return FuncInfo.ClrEHUnwindMap.size() - 1;
651}
652
654 WinEHFuncInfo &FuncInfo) {
655 // Return if it's already been done.
656 if (!FuncInfo.EHPadStateMap.empty())
657 return;
658
659 // This numbering assigns one state number to each catchpad and cleanuppad.
660 // It also computes two tree-like relations over states:
661 // 1) Each state has a "HandlerParentState", which is the state of the next
662 // outer handler enclosing this state's handler (same as nearest ancestor
663 // per the ParentPad linkage on EH pads, but skipping over catchswitches).
664 // 2) Each state has a "TryParentState", which:
665 // a) for a catchpad that's not the last handler on its catchswitch, is
666 // the state of the next catchpad on that catchswitch
667 // b) for all other pads, is the state of the pad whose try region is the
668 // next outer try region enclosing this state's try region. The "try
669 // regions are not present as such in the IR, but will be inferred
670 // based on the placement of invokes and pads which reach each other
671 // by exceptional exits
672 // Catchswitches do not get their own states, but each gets mapped to the
673 // state of its first catchpad.
674
675 // Step one: walk down from outermost to innermost funclets, assigning each
676 // catchpad and cleanuppad a state number. Add an entry to the
677 // ClrEHUnwindMap for each state, recording its HandlerParentState and
678 // handler attributes. Record the TryParentState as well for each catchpad
679 // that's not the last on its catchswitch, but initialize all other entries'
680 // TryParentStates to a sentinel -1 value that the next pass will update.
681
682 // Seed a worklist with pads that have no parent.
684 for (const BasicBlock &BB : *Fn) {
685 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
686 const Value *ParentPad;
687 if (const auto *CPI = dyn_cast<CleanupPadInst>(FirstNonPHI))
688 ParentPad = CPI->getParentPad();
689 else if (const auto *CSI = dyn_cast<CatchSwitchInst>(FirstNonPHI))
690 ParentPad = CSI->getParentPad();
691 else
692 continue;
693 if (isa<ConstantTokenNone>(ParentPad))
694 Worklist.emplace_back(FirstNonPHI, -1);
695 }
696
697 // Use the worklist to visit all pads, from outer to inner. Record
698 // HandlerParentState for all pads. Record TryParentState only for catchpads
699 // that aren't the last on their catchswitch (setting all other entries'
700 // TryParentStates to an initial value of -1). This loop is also responsible
701 // for setting the EHPadStateMap entry for all catchpads, cleanuppads, and
702 // catchswitches.
703 while (!Worklist.empty()) {
704 const Instruction *Pad;
705 int HandlerParentState;
706 std::tie(Pad, HandlerParentState) = Worklist.pop_back_val();
707
708 if (const auto *Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
709 // Create the entry for this cleanup with the appropriate handler
710 // properties. Finally and fault handlers are distinguished by arity.
711 ClrHandlerType HandlerType =
712 (Cleanup->arg_size() ? ClrHandlerType::Fault
714 int CleanupState = addClrEHHandler(FuncInfo, HandlerParentState, -1,
715 HandlerType, 0, Pad->getParent());
716 // Queue any child EH pads on the worklist.
717 for (const User *U : Cleanup->users())
718 if (const auto *I = dyn_cast<Instruction>(U))
719 if (I->isEHPad())
720 Worklist.emplace_back(I, CleanupState);
721 // Remember this pad's state.
722 FuncInfo.EHPadStateMap[Cleanup] = CleanupState;
723 } else {
724 // Walk the handlers of this catchswitch in reverse order since all but
725 // the last need to set the following one as its TryParentState.
726 const auto *CatchSwitch = cast<CatchSwitchInst>(Pad);
727 int CatchState = -1, FollowerState = -1;
728 SmallVector<const BasicBlock *, 4> CatchBlocks(CatchSwitch->handlers());
729 for (const BasicBlock *CatchBlock : llvm::reverse(CatchBlocks)) {
730 // Create the entry for this catch with the appropriate handler
731 // properties.
732 const auto *Catch = cast<CatchPadInst>(CatchBlock->getFirstNonPHIIt());
733 uint32_t TypeToken = static_cast<uint32_t>(
734 cast<ConstantInt>(Catch->getArgOperand(0))->getZExtValue());
735 CatchState =
736 addClrEHHandler(FuncInfo, HandlerParentState, FollowerState,
737 ClrHandlerType::Catch, TypeToken, CatchBlock);
738 // Queue any child EH pads on the worklist.
739 for (const User *U : Catch->users())
740 if (const auto *I = dyn_cast<Instruction>(U))
741 if (I->isEHPad())
742 Worklist.emplace_back(I, CatchState);
743 // Remember this catch's state.
744 FuncInfo.EHPadStateMap[Catch] = CatchState;
745 FollowerState = CatchState;
746 }
747 // Associate the catchswitch with the state of its first catch.
748 assert(CatchSwitch->getNumHandlers());
749 FuncInfo.EHPadStateMap[CatchSwitch] = CatchState;
750 }
751 }
752
753 // Step two: record the TryParentState of each state. For cleanuppads that
754 // don't have cleanuprets, we may need to infer this from their child pads,
755 // so visit pads in descendant-most to ancestor-most order.
756 for (ClrEHUnwindMapEntry &Entry : llvm::reverse(FuncInfo.ClrEHUnwindMap)) {
757 const Instruction *Pad =
758 &*cast<const BasicBlock *>(Entry.Handler)->getFirstNonPHIIt();
759 // For most pads, the TryParentState is the state associated with the
760 // unwind dest of exceptional exits from it.
761 const BasicBlock *UnwindDest;
762 if (const auto *Catch = dyn_cast<CatchPadInst>(Pad)) {
763 // If a catch is not the last in its catchswitch, its TryParentState is
764 // the state associated with the next catch in the switch, even though
765 // that's not the unwind dest of exceptions escaping the catch. Those
766 // cases were already assigned a TryParentState in the first pass, so
767 // skip them.
768 if (Entry.TryParentState != -1)
769 continue;
770 // Otherwise, get the unwind dest from the catchswitch.
771 UnwindDest = Catch->getCatchSwitch()->getUnwindDest();
772 } else {
773 const auto *Cleanup = cast<CleanupPadInst>(Pad);
774 UnwindDest = nullptr;
775 for (const User *U : Cleanup->users()) {
776 if (auto *CleanupRet = dyn_cast<CleanupReturnInst>(U)) {
777 // Common and unambiguous case -- cleanupret indicates cleanup's
778 // unwind dest.
779 UnwindDest = CleanupRet->getUnwindDest();
780 break;
781 }
782
783 // Get an unwind dest for the user
784 const BasicBlock *UserUnwindDest = nullptr;
785 if (auto *Invoke = dyn_cast<InvokeInst>(U)) {
786 UserUnwindDest = Invoke->getUnwindDest();
787 } else if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(U)) {
788 UserUnwindDest = CatchSwitch->getUnwindDest();
789 } else if (auto *ChildCleanup = dyn_cast<CleanupPadInst>(U)) {
790 int UserState = FuncInfo.EHPadStateMap[ChildCleanup];
791 int UserUnwindState =
792 FuncInfo.ClrEHUnwindMap[UserState].TryParentState;
793 if (UserUnwindState != -1)
794 UserUnwindDest = cast<const BasicBlock *>(
795 FuncInfo.ClrEHUnwindMap[UserUnwindState].Handler);
796 }
797
798 // Not having an unwind dest for this user might indicate that it
799 // doesn't unwind, so can't be taken as proof that the cleanup itself
800 // may unwind to caller (see e.g. SimplifyUnreachable and
801 // RemoveUnwindEdge).
802 if (!UserUnwindDest)
803 continue;
804
805 // Now we have an unwind dest for the user, but we need to see if it
806 // unwinds all the way out of the cleanup or if it stays within it.
807 const Instruction *UserUnwindPad = &*UserUnwindDest->getFirstNonPHIIt();
808 const Value *UserUnwindParent;
809 if (auto *CSI = dyn_cast<CatchSwitchInst>(UserUnwindPad))
810 UserUnwindParent = CSI->getParentPad();
811 else
812 UserUnwindParent =
813 cast<CleanupPadInst>(UserUnwindPad)->getParentPad();
814
815 // The unwind stays within the cleanup iff it targets a child of the
816 // cleanup.
817 if (UserUnwindParent == Cleanup)
818 continue;
819
820 // This unwind exits the cleanup, so its dest is the cleanup's dest.
821 UnwindDest = UserUnwindDest;
822 break;
823 }
824 }
825
826 // Record the state of the unwind dest as the TryParentState.
827 int UnwindDestState;
828
829 // If UnwindDest is null at this point, either the pad in question can
830 // be exited by unwind to caller, or it cannot be exited by unwind. In
831 // either case, reporting such cases as unwinding to caller is correct.
832 // This can lead to EH tables that "look strange" -- if this pad's is in
833 // a parent funclet which has other children that do unwind to an enclosing
834 // pad, the try region for this pad will be missing the "duplicate" EH
835 // clause entries that you'd expect to see covering the whole parent. That
836 // should be benign, since the unwind never actually happens. If it were
837 // an issue, we could add a subsequent pass that pushes unwind dests down
838 // from parents that have them to children that appear to unwind to caller.
839 if (!UnwindDest) {
840 UnwindDestState = -1;
841 } else {
842 UnwindDestState =
843 FuncInfo.EHPadStateMap[&*UnwindDest->getFirstNonPHIIt()];
844 }
845
846 Entry.TryParentState = UnwindDestState;
847 }
848
849 // Step three: transfer information from pads to invokes.
851}
852
853void WinEHPrepareImpl::colorFunclets(Function &F) {
854 BlockColors = colorEHFunclets(F);
855
856 // Invert the map from BB to colors to color to BBs.
857 for (BasicBlock &BB : F) {
858 ColorVector &Colors = BlockColors[&BB];
859 for (BasicBlock *Color : Colors)
860 FuncletBlocks[Color].push_back(&BB);
861 }
862}
863
864bool WinEHPrepareImpl::demotePHIsOnFunclets(Function &F,
865 bool DemoteCatchSwitchPHIOnly) {
866 bool Changed = false;
867
868 // Strip PHI nodes off of EH pads.
870 for (BasicBlock &BB : make_early_inc_range(F)) {
871 if (!BB.isEHPad())
872 continue;
873
874 for (Instruction &I : make_early_inc_range(BB)) {
875 auto *PN = dyn_cast<PHINode>(&I);
876 // Stop at the first non-PHI.
877 if (!PN)
878 break;
879
880 // If DemoteCatchSwitchPHIOnly is true, we only demote a PHI when
881 // 1. The PHI is within a catchswitch BB
882 // 2. The PHI has a catchswitch BB has one of its incoming blocks
883 if (DemoteCatchSwitchPHIOnly) {
884 bool IsCatchSwitchBB = isa<CatchSwitchInst>(BB.getFirstNonPHIIt());
885 bool HasIncomingCatchSwitchBB = false;
886 for (unsigned I = 0, E = PN->getNumIncomingValues(); I < E; ++I) {
888 PN->getIncomingBlock(I)->getFirstNonPHIIt())) {
889 HasIncomingCatchSwitchBB = true;
890 break;
891 }
892 }
893 if (!IsCatchSwitchBB && !HasIncomingCatchSwitchBB)
894 break;
895 }
896
897 Changed = true;
898
899 AllocaInst *SpillSlot = insertPHILoads(PN, F);
900 if (SpillSlot)
901 insertPHIStores(PN, SpillSlot);
902
903 PHINodes.push_back(PN);
904 }
905 }
906
907 for (auto *PN : PHINodes) {
908 // There may be lingering uses on other EH PHIs being removed
909 PN->replaceAllUsesWith(PoisonValue::get(PN->getType()));
910 PN->eraseFromParent();
911 }
912
913 return Changed;
914}
915
916bool WinEHPrepareImpl::cloneCommonBlocks(Function &F) {
917 bool Changed = false;
918
919 // We need to clone all blocks which belong to multiple funclets. Values are
920 // remapped throughout the funclet to propagate both the new instructions
921 // *and* the new basic blocks themselves.
922 for (auto &Funclets : FuncletBlocks) {
923 BasicBlock *FuncletPadBB = Funclets.first;
924 std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
925 Value *FuncletToken;
926 if (FuncletPadBB == &F.getEntryBlock())
927 FuncletToken = ConstantTokenNone::get(F.getContext());
928 else
929 FuncletToken = &*FuncletPadBB->getFirstNonPHIIt();
930
931 std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
933 for (BasicBlock *BB : BlocksInFunclet) {
934 ColorVector &ColorsForBB = BlockColors[BB];
935 // We don't need to do anything if the block is monochromatic.
936 size_t NumColorsForBB = ColorsForBB.size();
937 if (NumColorsForBB == 1)
938 continue;
939
940 DEBUG_WITH_TYPE("win-eh-prepare-coloring",
941 dbgs() << " Cloning block \'" << BB->getName()
942 << "\' for funclet \'" << FuncletPadBB->getName()
943 << "\'.\n");
944
945 // Create a new basic block and copy instructions into it!
946 BasicBlock *CBB =
947 CloneBasicBlock(BB, VMap, Twine(".for.", FuncletPadBB->getName()));
948 // Insert the clone immediately after the original to ensure determinism
949 // and to keep the same relative ordering of any funclet's blocks.
950 CBB->insertInto(&F, BB->getNextNode());
951
952 // Add basic block mapping.
953 VMap[BB] = CBB;
954
955 // Record delta operations that we need to perform to our color mappings.
956 Orig2Clone.emplace_back(BB, CBB);
957 }
958
959 // If nothing was cloned, we're done cloning in this funclet.
960 if (Orig2Clone.empty())
961 continue;
962
963 Changed = true;
964
965 // Update our color mappings to reflect that one block has lost a color and
966 // another has gained a color.
967 for (auto &BBMapping : Orig2Clone) {
968 BasicBlock *OldBlock = BBMapping.first;
969 BasicBlock *NewBlock = BBMapping.second;
970
971 BlocksInFunclet.push_back(NewBlock);
972 ColorVector &NewColors = BlockColors[NewBlock];
973 assert(NewColors.empty() && "A new block should only have one color!");
974 NewColors.push_back(FuncletPadBB);
975
976 DEBUG_WITH_TYPE("win-eh-prepare-coloring",
977 dbgs() << " Assigned color \'" << FuncletPadBB->getName()
978 << "\' to block \'" << NewBlock->getName()
979 << "\'.\n");
980
981 llvm::erase(BlocksInFunclet, OldBlock);
982 ColorVector &OldColors = BlockColors[OldBlock];
983 llvm::erase(OldColors, FuncletPadBB);
984
985 DEBUG_WITH_TYPE("win-eh-prepare-coloring",
986 dbgs() << " Removed color \'" << FuncletPadBB->getName()
987 << "\' from block \'" << OldBlock->getName()
988 << "\'.\n");
989 }
990
991 // Loop over all of the instructions in this funclet, fixing up operand
992 // references as we go. This uses VMap to do all the hard work.
993 for (BasicBlock *BB : BlocksInFunclet)
994 // Loop over all instructions, fixing each one as we find it...
995 for (Instruction &I : *BB)
996 RemapInstruction(&I, VMap,
998
999 // Catchrets targeting cloned blocks need to be updated separately from
1000 // the loop above because they are not in the current funclet.
1001 SmallVector<CatchReturnInst *, 2> FixupCatchrets;
1002 for (auto &BBMapping : Orig2Clone) {
1003 BasicBlock *OldBlock = BBMapping.first;
1004 BasicBlock *NewBlock = BBMapping.second;
1005
1006 FixupCatchrets.clear();
1007 for (BasicBlock *Pred : predecessors(OldBlock))
1008 if (auto *CatchRet = dyn_cast<CatchReturnInst>(Pred->getTerminator()))
1009 if (CatchRet->getCatchSwitchParentPad() == FuncletToken)
1010 FixupCatchrets.push_back(CatchRet);
1011
1012 for (CatchReturnInst *CatchRet : FixupCatchrets)
1013 CatchRet->setSuccessor(NewBlock);
1014 }
1015
1016 auto UpdatePHIOnClonedBlock = [&](PHINode *PN, bool IsForOldBlock) {
1018 [&](unsigned Idx) {
1019 BasicBlock *IncomingBlock = PN->getIncomingBlock(Idx);
1020 bool EdgeTargetsFunclet;
1021 if (auto *CRI =
1022 dyn_cast<CatchReturnInst>(IncomingBlock->getTerminator())) {
1023 EdgeTargetsFunclet =
1024 (CRI->getCatchSwitchParentPad() == FuncletToken);
1025 } else {
1026 ColorVector &IncomingColors = BlockColors[IncomingBlock];
1027 assert(!IncomingColors.empty() && "Block not colored!");
1028 assert(
1029 (IncomingColors.size() == 1 ||
1030 !llvm::is_contained(IncomingColors, FuncletPadBB)) &&
1031 "Cloning should leave this funclet's blocks monochromatic");
1032 EdgeTargetsFunclet = (IncomingColors.front() == FuncletPadBB);
1033 }
1034 return IsForOldBlock == EdgeTargetsFunclet;
1035 },
1036 /*DeletePHIIfEmpty=*/false);
1037 };
1038
1039 for (auto &BBMapping : Orig2Clone) {
1040 BasicBlock *OldBlock = BBMapping.first;
1041 BasicBlock *NewBlock = BBMapping.second;
1042 for (PHINode &OldPN : OldBlock->phis()) {
1043 UpdatePHIOnClonedBlock(&OldPN, /*IsForOldBlock=*/true);
1044 }
1045 for (PHINode &NewPN : NewBlock->phis()) {
1046 UpdatePHIOnClonedBlock(&NewPN, /*IsForOldBlock=*/false);
1047 }
1048 }
1049
1050 // Check to see if SuccBB has PHI nodes. If so, we need to add entries to
1051 // the PHI nodes for NewBB now.
1052 for (auto &BBMapping : Orig2Clone) {
1053 BasicBlock *OldBlock = BBMapping.first;
1054 BasicBlock *NewBlock = BBMapping.second;
1055 for (BasicBlock *SuccBB : successors(NewBlock)) {
1056 for (PHINode &SuccPN : SuccBB->phis()) {
1057 // Ok, we have a PHI node. Figure out what the incoming value was for
1058 // the OldBlock.
1059 int OldBlockIdx = SuccPN.getBasicBlockIndex(OldBlock);
1060 if (OldBlockIdx == -1)
1061 break;
1062 Value *IV = SuccPN.getIncomingValue(OldBlockIdx);
1063
1064 // Remap the value if necessary.
1065 if (auto *Inst = dyn_cast<Instruction>(IV)) {
1066 ValueToValueMapTy::iterator I = VMap.find(Inst);
1067 if (I != VMap.end())
1068 IV = I->second;
1069 }
1070
1071 SuccPN.addIncoming(IV, NewBlock);
1072 }
1073 }
1074 }
1075
1076 for (ValueToValueMapTy::value_type VT : VMap) {
1077 // If there were values defined in BB that are used outside the funclet,
1078 // then we now have to update all uses of the value to use either the
1079 // original value, the cloned value, or some PHI derived value. This can
1080 // require arbitrary PHI insertion, of which we are prepared to do, clean
1081 // these up now.
1082 SmallVector<Use *, 16> UsesToRename;
1083
1084 auto *OldI = dyn_cast<Instruction>(const_cast<Value *>(VT.first));
1085 if (!OldI)
1086 continue;
1087 auto *NewI = cast<Instruction>(VT.second);
1088 // Scan all uses of this instruction to see if it is used outside of its
1089 // funclet, and if so, record them in UsesToRename.
1090 for (Use &U : OldI->uses()) {
1091 Instruction *UserI = cast<Instruction>(U.getUser());
1092 BasicBlock *UserBB = UserI->getParent();
1093 ColorVector &ColorsForUserBB = BlockColors[UserBB];
1094 assert(!ColorsForUserBB.empty());
1095 if (ColorsForUserBB.size() > 1 ||
1096 *ColorsForUserBB.begin() != FuncletPadBB)
1097 UsesToRename.push_back(&U);
1098 }
1099
1100 // If there are no uses outside the block, we're done with this
1101 // instruction.
1102 if (UsesToRename.empty())
1103 continue;
1104
1105 // We found a use of OldI outside of the funclet. Rename all uses of OldI
1106 // that are outside its funclet to be uses of the appropriate PHI node
1107 // etc.
1108 SSAUpdater SSAUpdate;
1109 SSAUpdate.Initialize(OldI->getType(), OldI->getName());
1110 SSAUpdate.AddAvailableValue(OldI->getParent(), OldI);
1111 SSAUpdate.AddAvailableValue(NewI->getParent(), NewI);
1112
1113 while (!UsesToRename.empty())
1114 SSAUpdate.RewriteUseAfterInsertions(*UsesToRename.pop_back_val());
1115 }
1116 }
1117
1118 return Changed;
1119}
1120
1121bool WinEHPrepareImpl::removeImplausibleInstructions(Function &F) {
1122 bool Changed = false;
1123
1124 // Remove implausible terminators and replace them with UnreachableInst.
1125 for (auto &Funclet : FuncletBlocks) {
1126 BasicBlock *FuncletPadBB = Funclet.first;
1127 std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
1128 Instruction *FirstNonPHI = &*FuncletPadBB->getFirstNonPHIIt();
1129 auto *FuncletPad = dyn_cast<FuncletPadInst>(FirstNonPHI);
1130 auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad);
1131 auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad);
1132
1133 for (BasicBlock *BB : BlocksInFunclet) {
1134 for (Instruction &I : *BB) {
1135 auto *CB = dyn_cast<CallBase>(&I);
1136 if (!CB)
1137 continue;
1138
1139 Value *FuncletBundleOperand = nullptr;
1140 if (auto BU = CB->getOperandBundle(LLVMContext::OB_funclet))
1141 FuncletBundleOperand = BU->Inputs.front();
1142
1143 if (FuncletBundleOperand == FuncletPad)
1144 continue;
1145
1146 // Skip call sites which are nounwind intrinsics or inline asm.
1147 auto *CalledFn =
1148 dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());
1149 if (CB->isInlineAsm() ||
1150 (CalledFn && CalledFn->isIntrinsic() && CB->doesNotThrow()))
1151 continue;
1152
1153 Changed = true;
1154
1155 // This call site was not part of this funclet, remove it.
1156 if (isa<InvokeInst>(CB)) {
1157 // Remove the unwind edge if it was an invoke.
1158 removeUnwindEdge(BB);
1159 // Get a pointer to the new call.
1160 BasicBlock::iterator CallI =
1161 std::prev(BB->getTerminator()->getIterator());
1162 auto *CI = cast<CallInst>(&*CallI);
1164 } else {
1166 }
1167
1168 // There are no more instructions in the block (except for unreachable),
1169 // we are done.
1170 break;
1171 }
1172
1173 Instruction *TI = BB->getTerminator();
1174 // CatchPadInst and CleanupPadInst can't transfer control to a ReturnInst.
1175 bool IsUnreachableRet = isa<ReturnInst>(TI) && FuncletPad;
1176 // The token consumed by a CatchReturnInst must match the funclet token.
1177 bool IsUnreachableCatchret = false;
1178 if (auto *CRI = dyn_cast<CatchReturnInst>(TI))
1179 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
1180 // The token consumed by a CleanupReturnInst must match the funclet token.
1181 bool IsUnreachableCleanupret = false;
1182 if (auto *CRI = dyn_cast<CleanupReturnInst>(TI))
1183 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
1184 if (IsUnreachableRet || IsUnreachableCatchret ||
1185 IsUnreachableCleanupret) {
1186 Changed = true;
1188 } else if (isa<InvokeInst>(TI)) {
1189 if (Personality == EHPersonality::MSVC_CXX && CleanupPad) {
1190 Changed = true;
1191 // Invokes within a cleanuppad for the MSVC++ personality never
1192 // transfer control to their unwind edge: the personality will
1193 // terminate the program.
1194 removeUnwindEdge(BB);
1195 }
1196 }
1197 }
1198 }
1199
1200 return Changed;
1201}
1202
1203bool WinEHPrepareImpl::cleanupPreparedFunclets(Function &F) {
1204 bool Changed = false;
1205
1206 // Clean-up some of the mess we made by removing useles PHI nodes, trivial
1207 // branches, etc.
1210 Changed |= ConstantFoldTerminator(&BB, /*DeleteDeadConditions=*/true);
1212 }
1213
1214 // We might have some unreachable blocks after cleaning up some impossible
1215 // control flow.
1217
1218 return Changed;
1219}
1220
1221#ifndef NDEBUG
1222void WinEHPrepareImpl::verifyPreparedFunclets(Function &F) {
1223 for (BasicBlock &BB : F) {
1224 size_t NumColors = BlockColors[&BB].size();
1225 assert(NumColors == 1 && "Expected monochromatic BB!");
1226 if (NumColors == 0)
1227 report_fatal_error("Uncolored BB!");
1228 if (NumColors > 1)
1229 report_fatal_error("Multicolor BB!");
1230 assert((DisableDemotion || !(BB.isEHPad() && isa<PHINode>(BB.begin()))) &&
1231 "EH Pad still has a PHI!");
1232 }
1233}
1234#endif
1235
1236bool WinEHPrepareImpl::prepareExplicitEH(Function &F) {
1237 // Remove unreachable blocks. It is not valuable to assign them a color and
1238 // their existence can trick us into thinking values are alive when they are
1239 // not.
1241
1242 // Determine which blocks are reachable from which funclet entries.
1243 colorFunclets(F);
1244
1245 Changed |= cloneCommonBlocks(F);
1246
1247 if (!DisableDemotion)
1248 Changed |= demotePHIsOnFunclets(F, DemoteCatchSwitchPHIOnly ||
1250
1251 if (!DisableCleanups) {
1252 assert(!verifyFunction(F, &dbgs()));
1253 Changed |= removeImplausibleInstructions(F);
1254
1255 assert(!verifyFunction(F, &dbgs()));
1256 Changed |= cleanupPreparedFunclets(F);
1257 }
1258
1259 LLVM_DEBUG(verifyPreparedFunclets(F));
1260 // Recolor the CFG to verify that all is well.
1261 LLVM_DEBUG(colorFunclets(F));
1262 LLVM_DEBUG(verifyPreparedFunclets(F));
1263
1264 return Changed;
1265}
1266
1267// TODO: Share loads when one use dominates another, or when a catchpad exit
1268// dominates uses (needs dominators).
1269AllocaInst *WinEHPrepareImpl::insertPHILoads(PHINode *PN, Function &F) {
1270 BasicBlock *PHIBlock = PN->getParent();
1271 AllocaInst *SpillSlot = nullptr;
1272 Instruction *EHPad = &*PHIBlock->getFirstNonPHIIt();
1273
1274 if (!EHPad->isTerminator()) {
1275 // If the EHPad isn't a terminator, then we can insert a load in this block
1276 // that will dominate all uses.
1277 SpillSlot = new AllocaInst(PN->getType(), DL->getAllocaAddrSpace(), nullptr,
1278 Twine(PN->getName(), ".wineh.spillslot"),
1279 F.getEntryBlock().begin());
1280 Value *V = new LoadInst(PN->getType(), SpillSlot,
1281 Twine(PN->getName(), ".wineh.reload"),
1282 PHIBlock->getFirstInsertionPt());
1283 PN->replaceAllUsesWith(V);
1284 return SpillSlot;
1285 }
1286
1287 // Otherwise, we have a PHI on a terminator EHPad, and we give up and insert
1288 // loads of the slot before every use.
1290 for (Use &U : llvm::make_early_inc_range(PN->uses())) {
1291 auto *UsingInst = cast<Instruction>(U.getUser());
1292 if (isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
1293 // Use is on an EH pad phi. Leave it alone; we'll insert loads and
1294 // stores for it separately.
1295 continue;
1296 }
1297 replaceUseWithLoad(PN, U, SpillSlot, Loads, F);
1298 }
1299 return SpillSlot;
1300}
1301
1302// TODO: improve store placement. Inserting at def is probably good, but need
1303// to be careful not to introduce interfering stores (needs liveness analysis).
1304// TODO: identify related phi nodes that can share spill slots, and share them
1305// (also needs liveness).
1306void WinEHPrepareImpl::insertPHIStores(PHINode *OriginalPHI,
1307 AllocaInst *SpillSlot) {
1308 // Use a worklist of (Block, Value) pairs -- the given Value needs to be
1309 // stored to the spill slot by the end of the given Block.
1311
1312 Worklist.push_back({OriginalPHI->getParent(), OriginalPHI});
1313
1314 while (!Worklist.empty()) {
1315 BasicBlock *EHBlock;
1316 Value *InVal;
1317 std::tie(EHBlock, InVal) = Worklist.pop_back_val();
1318
1319 PHINode *PN = dyn_cast<PHINode>(InVal);
1320 if (PN && PN->getParent() == EHBlock) {
1321 // The value is defined by another PHI we need to remove, with no room to
1322 // insert a store after the PHI, so each predecessor needs to store its
1323 // incoming value.
1324 for (unsigned i = 0, e = PN->getNumIncomingValues(); i < e; ++i) {
1325 Value *PredVal = PN->getIncomingValue(i);
1326
1327 // Undef can safely be skipped.
1328 if (isa<UndefValue>(PredVal))
1329 continue;
1330
1331 insertPHIStore(PN->getIncomingBlock(i), PredVal, SpillSlot, Worklist);
1332 }
1333 } else {
1334 // We need to store InVal, which dominates EHBlock, but can't put a store
1335 // in EHBlock, so need to put stores in each predecessor.
1336 for (BasicBlock *PredBlock : predecessors(EHBlock)) {
1337 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
1338 }
1339 }
1340 }
1341}
1342
1343void WinEHPrepareImpl::insertPHIStore(
1344 BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
1345 SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist) {
1346
1347 if (PredBlock->isEHPad() && PredBlock->getFirstNonPHIIt()->isTerminator()) {
1348 // Pred is unsplittable, so we need to queue it on the worklist.
1349 Worklist.push_back({PredBlock, PredVal});
1350 return;
1351 }
1352
1353 // Otherwise, insert the store at the end of the basic block.
1354 new StoreInst(PredVal, SpillSlot, PredBlock->getTerminator()->getIterator());
1355}
1356
1357void WinEHPrepareImpl::replaceUseWithLoad(
1358 Value *V, Use &U, AllocaInst *&SpillSlot,
1360 // Lazilly create the spill slot.
1361 if (!SpillSlot)
1362 SpillSlot = new AllocaInst(V->getType(), DL->getAllocaAddrSpace(), nullptr,
1363 Twine(V->getName(), ".wineh.spillslot"),
1364 F.getEntryBlock().begin());
1365
1366 auto *UsingInst = cast<Instruction>(U.getUser());
1367 if (auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) {
1368 // If this is a PHI node, we can't insert a load of the value before
1369 // the use. Instead insert the load in the predecessor block
1370 // corresponding to the incoming value.
1371 //
1372 // Note that if there are multiple edges from a basic block to this
1373 // PHI node that we cannot have multiple loads. The problem is that
1374 // the resulting PHI node will have multiple values (from each load)
1375 // coming in from the same block, which is illegal SSA form.
1376 // For this reason, we keep track of and reuse loads we insert.
1377 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
1378 if (auto *CatchRet =
1379 dyn_cast<CatchReturnInst>(IncomingBlock->getTerminator())) {
1380 // Putting a load above a catchret and use on the phi would still leave
1381 // a cross-funclet def/use. We need to split the edge, change the
1382 // catchret to target the new block, and put the load there.
1383 BasicBlock *PHIBlock = UsingInst->getParent();
1384 BasicBlock *NewBlock = SplitEdge(IncomingBlock, PHIBlock);
1385 // SplitEdge gives us:
1386 // IncomingBlock:
1387 // ...
1388 // br label %NewBlock
1389 // NewBlock:
1390 // catchret label %PHIBlock
1391 // But we need:
1392 // IncomingBlock:
1393 // ...
1394 // catchret label %NewBlock
1395 // NewBlock:
1396 // br label %PHIBlock
1397 // So move the terminators to each others' blocks and swap their
1398 // successors.
1399 BranchInst *Goto = cast<BranchInst>(IncomingBlock->getTerminator());
1400 Goto->removeFromParent();
1401 CatchRet->removeFromParent();
1402 CatchRet->insertInto(IncomingBlock, IncomingBlock->end());
1403 Goto->insertInto(NewBlock, NewBlock->end());
1404 Goto->setSuccessor(0, PHIBlock);
1405 CatchRet->setSuccessor(NewBlock);
1406 // Update the color mapping for the newly split edge.
1407 // Grab a reference to the ColorVector to be inserted before getting the
1408 // reference to the vector we are copying because inserting the new
1409 // element in BlockColors might cause the map to be reallocated.
1410 ColorVector &ColorsForNewBlock = BlockColors[NewBlock];
1411 ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
1412 ColorsForNewBlock = ColorsForPHIBlock;
1413 for (BasicBlock *FuncletPad : ColorsForPHIBlock)
1414 FuncletBlocks[FuncletPad].push_back(NewBlock);
1415 // Treat the new block as incoming for load insertion.
1416 IncomingBlock = NewBlock;
1417 }
1418 Value *&Load = Loads[IncomingBlock];
1419 // Insert the load into the predecessor block
1420 if (!Load)
1421 Load = new LoadInst(
1422 V->getType(), SpillSlot, Twine(V->getName(), ".wineh.reload"),
1423 /*isVolatile=*/false, IncomingBlock->getTerminator()->getIterator());
1424
1425 U.set(Load);
1426 } else {
1427 // Reload right before the old use.
1428 auto *Load = new LoadInst(V->getType(), SpillSlot,
1429 Twine(V->getName(), ".wineh.reload"),
1430 /*isVolatile=*/false, UsingInst->getIterator());
1431 U.set(Load);
1432 }
1433}
1434
1436 MCSymbol *InvokeBegin,
1437 MCSymbol *InvokeEnd) {
1438 assert(InvokeStateMap.count(II) &&
1439 "should get invoke with precomputed state");
1440 LabelToStateMap[InvokeBegin] = std::make_pair(InvokeStateMap[II], InvokeEnd);
1441}
1442
1443void WinEHFuncInfo::addIPToStateRange(int State, MCSymbol* InvokeBegin,
1444 MCSymbol* InvokeEnd) {
1445 LabelToStateMap[InvokeBegin] = std::make_pair(State, InvokeEnd);
1446}
1447
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
#define DEBUG_TYPE
static const HTTPClientCleanup Cleanup
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file implements a map that provides insertion order iteration.
uint64_t IntrinsicInst * II
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
This file contains some templates that are useful if you are working with the STL at all.
#define LLVM_DEBUG(...)
Definition Debug.h:114
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
Definition Debug.h:72
static cl::opt< bool > DisableDemotion("disable-demotion", cl::Hidden, cl::desc("Clone multicolor basic blocks but do not demote cross scopes"), cl::init(false))
static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState, const BasicBlock *BB)
static void calculateStateNumbersForInvokes(const Function *Fn, WinEHFuncInfo &FuncInfo)
static BasicBlock * getCleanupRetUnwindDest(const CleanupPadInst *CleanupPad)
static cl::opt< bool > DisableCleanups("disable-cleanups", cl::Hidden, cl::desc("Do not remove implausible terminators or other similar cleanups"), cl::init(false))
static int addSEHFinally(WinEHFuncInfo &FuncInfo, int ParentState, const BasicBlock *Handler)
static const BasicBlock * getEHPadFromPredecessor(const BasicBlock *BB, Value *ParentPad)
static int addClrEHHandler(WinEHFuncInfo &FuncInfo, int HandlerParentState, int TryParentState, ClrHandlerType HandlerType, uint32_t TypeToken, const BasicBlock *Handler)
static void calculateCXXStateNumbers(WinEHFuncInfo &FuncInfo, const Instruction *FirstNonPHI, int ParentState)
static cl::opt< bool > DemoteCatchSwitchPHIOnlyOpt("demote-catchswitch-only", cl::Hidden, cl::desc("Demote catchswitch BBs only (for wasm EH)"), cl::init(false))
static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow, int TryHigh, int CatchHigh, ArrayRef< const CatchPadInst * > Handlers)
static bool isTopLevelPadForMSVC(const Instruction *EHPad)
static int addSEHExcept(WinEHFuncInfo &FuncInfo, int ParentState, const Function *Filter, const BasicBlock *Handler)
static const uint32_t IV[8]
Definition blake3_impl.h:83
an instruction to allocate memory on the stack
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator end()
Definition BasicBlock.h:472
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
Definition BasicBlock.h:528
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
InstListType::const_iterator const_iterator
Definition BasicBlock.h:171
const Instruction & front() const
Definition BasicBlock.h:482
LLVM_ABI void insertInto(Function *Parent, BasicBlock *InsertBefore=nullptr)
Insert unlinked basic block into a function.
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
bool isEHPad() const
Return true if this basic block is an exception handling block.
Definition BasicBlock.h:707
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition BasicBlock.h:233
Conditional or Unconditional Branch instruction.
void setSuccessor(unsigned idx, BasicBlock *NewSucc)
static LLVM_ABI ConstantTokenNone * get(LLVMContext &Context)
Return the ConstantTokenNone.
This is an important base class in LLVM.
Definition Constant.h:43
const Constant * stripPointerCasts() const
Definition Constant.h:222
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Definition Constants.cpp:90
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:178
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:256
iterator end()
Definition DenseMap.h:81
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
const BasicBlock & getEntryBlock() const
Definition Function.h:807
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Definition Function.cpp:363
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Definition Function.h:244
bool hasPersonalityFn() const
Check whether this function has a personality function.
Definition Function.h:903
Constant * getPersonalityFn() const
Get the personality function associated with this function.
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
Definition Function.h:249
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
bool isTerminator() const
LLVM_ABI InstListType::iterator insertInto(BasicBlock *ParentBB, InstListType::iterator It)
Inserts an unlinked instruction into ParentBB at position It and returns the iterator of the inserted...
Invoke instruction.
An instruction for reading from memory.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
Definition Module.cpp:353
LLVM_ABI void removeIncomingValueIf(function_ref< bool(unsigned)> Predicate, bool DeletePHIIfEmpty=true)
Remove all incoming values for which the predicate returns true.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
Helper class for SSA formation on a set of values defined in multiple blocks.
Definition SSAUpdater.h:39
void RewriteUseAfterInsertions(Use &U)
Rewrite a use like RewriteUse but handling in-block definitions.
void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
void push_back(EltTy NewVal)
EltTy front() const
unsigned size() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
std::pair< const Value *, WeakTrackingVH > value_type
Definition ValueMap.h:101
iterator find(const KeyT &Val)
Definition ValueMap.h:160
iterator end()
Definition ValueMap.h:139
ValueMapIteratorImpl< MapT, const Value *, false > iterator
Definition ValueMap.h:135
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:256
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:546
iterator_range< user_iterator > users()
Definition Value.h:426
iterator_range< use_iterator > uses()
Definition Value.h:380
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:322
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
CallInst * Call
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
LLVM_ABI bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions=false, const TargetLibraryInfo *TLI=nullptr, DomTreeUpdater *DTU=nullptr)
If a terminator instruction is predicated on a constant value, convert it into an unconditional branc...
Definition Local.cpp:134
LLVM_ABI BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr, bool MapAtoms=true)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
auto successors(const MachineBasicBlock *BB)
LLVM_ABI DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:632
LLVM_ABI bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr)
Scan the specified basic block and try to simplify any instructions in it and recursively delete dead...
Definition Local.cpp:721
void calculateWinCXXEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo)
Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which describes the state number...
bool isScopedEHPersonality(EHPersonality Pers)
Returns true if this personality uses scope-style EH IR instructions: catchswitch,...
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
Definition STLExtras.h:2140
auto reverse(ContainerTy &&C)
Definition STLExtras.h:406
@ RF_IgnoreMissingLocals
If this flag is set, the remapper ignores missing function-local entries (Argument,...
Definition ValueMapper.h:98
@ RF_NoModuleLevelChanges
If this flag is set, the remapper knows that only local values within a function (such as an instruct...
Definition ValueMapper.h:80
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:167
LLVM_ABI Instruction * removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU=nullptr)
Replace 'BB's terminator with one that does not have an unwind successor block.
Definition Local.cpp:2845
void calculateSEHStateForAsynchEH(const BasicBlock *BB, int State, WinEHFuncInfo &FuncInfo)
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI unsigned changeToUnreachable(Instruction *I, bool PreserveLCSSA=false, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Insert an unreachable instruction before the specified instruction, making it and the rest of the cod...
Definition Local.cpp:2513
void calculateCXXStateForAsynchEH(const BasicBlock *BB, int State, WinEHFuncInfo &FuncInfo)
void calculateSEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo)
LLVM_ABI bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr, bool PredecessorWithTwoSuccessors=false, DominatorTree *DT=nullptr)
Attempts to merge a block into its predecessor, if possible.
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataPredicate *IdentityMD=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
LLVM_ABI FunctionPass * createWinEHPass(bool DemoteCatchSwitchPHIOnly=false)
createWinEHPass - Prepares personality functions used by MSVC on Windows, in addition to the Itanium ...
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
TinyPtrVector< BasicBlock * > ColorVector
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1909
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
Definition Local.cpp:2883
void calculateClrEHStateNumbers(const Function *Fn, WinEHFuncInfo &FuncInfo)
const BasicBlock * Block
WorkItem(const BasicBlock *BB, int St)
int HandlerParentState
Outer handler enclosing this entry's handler.
MBBOrBasicBlock Cleanup
Similar to CxxUnwindMapEntry, but supports SEH filters.
int ToState
If unwinding continues through this handler, transition to the handler at this state.
void addIPToStateRange(const InvokeInst *II, MCSymbol *InvokeBegin, MCSymbol *InvokeEnd)
SmallVector< SEHUnwindMapEntry, 4 > SEHUnwindMap
SmallVector< ClrEHUnwindMapEntry, 4 > ClrEHUnwindMap
DenseMap< const FuncletPadInst *, int > FuncletBaseStateMap
DenseMap< const BasicBlock *, int > BlockToStateMap
DenseMap< const InvokeInst *, int > InvokeStateMap
SmallVector< WinEHTryBlockMapEntry, 4 > TryBlockMap
DenseMap< const Instruction *, int > EHPadStateMap
DenseMap< MCSymbol *, std::pair< int, MCSymbol * > > LabelToStateMap
SmallVector< CxxUnwindMapEntry, 4 > CxxUnwindMap
int getLastStateNumber() const
GlobalVariable * TypeDescriptor
union llvm::WinEHHandlerType::@246205307012256373115155017221207221353102114334 CatchObj
The CatchObj starts out life as an LLVM alloca and is eventually turned frame index.
const AllocaInst * Alloca
MBBOrBasicBlock Handler
SmallVector< WinEHHandlerType, 1 > HandlerArray