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