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