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/IRBuilder.h"
30#include "llvm/IR/Module.h"
31#include "llvm/IR/Verifier.h"
33#include "llvm/Pass.h"
35#include "llvm/Support/Debug.h"
42
43using namespace llvm;
44
45#define DEBUG_TYPE "win-eh-prepare"
46
48 "disable-demotion", cl::Hidden,
50 "Clone multicolor basic blocks but do not demote cross scopes"),
51 cl::init(false));
52
54 "disable-cleanups", cl::Hidden,
55 cl::desc("Do not remove implausible terminators or other similar cleanups"),
56 cl::init(false));
57
58static bool isMalformedCatchpad(const CatchPadInst *CPI,
59 EHPersonality Personality) {
60 switch (Personality) {
62 if (CPI->arg_size() != 3)
63 return true;
64
65 Constant *TypeInfo = dyn_cast<Constant>(CPI->getArgOperand(0));
66 if (!TypeInfo)
67 return true;
68 if (!TypeInfo->isNullValue() &&
70 return true;
71
72 if (!isa<ConstantInt>(CPI->getArgOperand(1)))
73 return true;
74
75 return false;
76 }
79 if (CPI->arg_size() == 0)
80 return true;
81
82 Constant *FilterOrNull = dyn_cast<Constant>(CPI->getArgOperand(0));
83 if (!FilterOrNull)
84 return true;
85
86 Constant *Filter = FilterOrNull->stripPointerCasts();
87 if (!Filter->isNullValue() && !isa<Function>(Filter))
88 return true;
89
90 return false;
91 }
93 if (CPI->arg_size() == 0)
94 return true;
95
96 if (!isa<ConstantInt>(CPI->getArgOperand(0)))
97 return true;
98
99 return false;
100 }
103 if (CPI->arg_size() == 1 && !isa<Constant>(CPI->getArgOperand(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
166 bool Changed = WinEHPrepareImpl().runOnFunction(F);
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(Fn.getPersonalityFn());
182
183 // Do nothing if this is not a scope-based personality.
184 if (!isScopedEHPersonality(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(Personality);
191
192 DL = &Fn.getDataLayout();
193 return prepareExplicitEH(Fn);
194}
195
196static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState,
197 const BasicBlock *BB) {
199 UME.ToState = ToState;
200 UME.Cleanup = BB;
201 FuncInfo.CxxUnwindMap.push_back(UME);
202 return FuncInfo.getLastStateNumber();
203}
204
205static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow,
206 int TryHigh, int CatchHigh,
209 TBME.TryLow = TryLow;
210 TBME.TryHigh = TryHigh;
211 TBME.CatchHigh = CatchHigh;
212 assert(TBME.TryLow <= TBME.TryHigh);
213 for (const CatchPadInst *CPI : Handlers) {
216 "Malformed CatchPadInst not caught by win-eh-prepare");
217 Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0));
218 if (TypeInfo->isNullValue())
219 HT.TypeDescriptor = nullptr;
220 else
222 HT.Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue();
223 HT.Handler = CPI->getParent();
224 if (auto *AI =
225 dyn_cast<AllocaInst>(CPI->getArgOperand(2)->stripPointerCasts()))
226 HT.CatchObj.Alloca = AI;
227 else
228 HT.CatchObj.Alloca = nullptr;
229 TBME.HandlerArray.push_back(HT);
230 }
231 FuncInfo.TryBlockMap.push_back(TBME);
232}
233
235 for (const User *U : CleanupPad->users())
236 if (const auto *CRI = dyn_cast<CleanupReturnInst>(U))
237 return CRI->getUnwindDest();
238 return nullptr;
239}
240
242 WinEHFuncInfo &FuncInfo) {
243 auto *F = const_cast<Function *>(Fn);
245 for (BasicBlock &BB : *F) {
246 auto *II = dyn_cast<InvokeInst>(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 =
257 assert(FuncletPad || FuncletEntryBB == &Fn->getEntryBlock());
258 if (!FuncletPad)
259 FuncletUnwindDest = nullptr;
260 else if (auto *CatchPad = dyn_cast<CatchPadInst>(FuncletPad))
261 FuncletUnwindDest = CatchPad->getCatchSwitch()->getUnwindDest();
262 else if (auto *CleanupPad = dyn_cast<CleanupPadInst>(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(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 {
289 int State;
290 WorkItem(const BasicBlock *BB, int St) {
291 Block = BB;
292 State = St;
293 }
294};
296 WinEHFuncInfo &EHInfo) {
298 struct WorkItem *WI = new WorkItem(BB, State);
299 WorkList.push_back(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(BB);
307 if (!Inserted && StateIt->second <= State)
308 continue; // skip blocks already visited by lower State
309
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>(TI) || isa<CatchReturnInst>(TI)) && State > 0) {
317 // Retrive the new State
318 State = EHInfo.CxxUnwindMap[State].ToState; // Retrive next State
319 } else if (isa<InvokeInst>(TI)) {
320 auto *Call = cast<CallBase>(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>(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>(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(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.
358 WinEHFuncInfo &EHInfo) {
360 struct WorkItem *WI = new WorkItem(BB, State);
361 WorkList.push_back(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(BB);
369 It != EHInfo.BlockToStateMap.end() && It->second <= State)
370 continue; // skip blocks already visited by lower State
371
373 const llvm::Instruction *TI = BB->getTerminator();
374 if (It->isEHPad())
375 State = EHInfo.EHPadStateMap[&*It];
376 EHInfo.BlockToStateMap[BB] = State; // Record state
377
381 "Malformed CatchPadInst not caught by win-eh-prepare");
382 const Constant *FilterOrNull = cast<Constant>(
383 cast<CatchPadInst>(It)->getArgOperand(0)->stripPointerCasts());
384 const Function *Filter = dyn_cast<Function>(FilterOrNull);
385 if (!Filter || !Filter->getName().starts_with("__IsLocalUnwind"))
386 State = EHInfo.SEHUnwindMap[State].ToState; // Retrive next State
387 } else if ((isa<CleanupReturnInst>(TI) || isa<CatchReturnInst>(TI)) &&
388 State > 0) {
389 // Retrive the new State.
390 State = EHInfo.SEHUnwindMap[State].ToState; // Retrive next State
391 } else if (isa<InvokeInst>(TI)) {
392 auto *Call = cast<CallBase>(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>(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(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.
414 Value *ParentPad) {
415 const Instruction *TI = BB->getTerminator();
416 if (isa<InvokeInst>(TI))
417 return nullptr;
418 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(TI)) {
419 if (CatchSwitch->getParentPad() != ParentPad)
420 return nullptr;
421 return BB;
422 }
423 assert(!TI->isEHPad() && "unexpected EHPad!");
424 auto *CleanupPad = cast<CleanupReturnInst>(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[]
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>(FirstNonPHI)) {
440 assert(FuncInfo.EHPadStateMap.count(CatchSwitch) == 0 &&
441 "shouldn't revist catch funclets!");
442
444 for (const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
445 auto *CatchPad = cast<CatchPadInst>(CatchPadBB->getFirstNonPHIIt());
446 Handlers.push_back(CatchPad);
447 }
448 int TryLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
449 FuncInfo.EHPadStateMap[CatchSwitch] = TryLow;
450 for (const BasicBlock *PredBlock : predecessors(BB))
451 if ((PredBlock = getEHPadFromPredecessor(PredBlock,
452 CatchSwitch->getParentPad())))
453 calculateCXXStateNumbers(FuncInfo, &*PredBlock->getFirstNonPHIIt(),
454 TryLow);
455 int CatchLow = addUnwindMapEntry(FuncInfo, ParentState, 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, 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>(U);
474 if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
475 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
476 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
477 calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
478 }
479 if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
480 BasicBlock *UnwindDest = getCleanupRetUnwindDest(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, UserI, 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>(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(CleanupPad);
507 if (!Inserted)
508 return;
509
510 int CleanupState = addUnwindMapEntry(FuncInfo, 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(PredBlock,
516 CleanupPad->getParentPad()))) {
517 calculateCXXStateNumbers(FuncInfo, &*PredBlock->getFirstNonPHIIt(),
518 CleanupState);
519 }
520 }
521 for (const User *U : CleanupPad->users()) {
522 const auto *UserI = cast<Instruction>(U);
523 if (UserI->isEHPad())
524 report_fatal_error("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(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(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[]
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>(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>((*CatchSwitch->handler_begin())->getFirstNonPHIIt());
571 const BasicBlock *CatchPadBB = CatchPad->getParent();
573 "Malformed CatchPadInst not caught by win-eh-prepare");
574 const Constant *FilterOrNull =
575 cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts());
576 const Function *Filter = dyn_cast<Function>(FilterOrNull);
577 assert((Filter || FilterOrNull->isNullValue()) &&
578 "unexpected filter value");
579 int TryState = addSEHExcept(FuncInfo, ParentState, Filter, 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(PredBlock,
588 CatchSwitch->getParentPad())))
589 calculateSEHStateNumbers(FuncInfo, &*PredBlock->getFirstNonPHIIt(),
590 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>(U);
596 if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
597 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
598 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
599 calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
600 }
601 if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
602 BasicBlock *UnwindDest = getCleanupRetUnwindDest(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, UserI, ParentState);
608 }
609 }
610 } else {
611 auto *CleanupPad = cast<CleanupPadInst>(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(CleanupPad);
616 if (!Inserted)
617 return;
618
619 int CleanupState = addSEHFinally(FuncInfo, ParentState, 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(PredBlock, CleanupPad->getParentPad())))
626 calculateSEHStateNumbers(FuncInfo, &*PredBlock->getFirstNonPHIIt(),
627 CleanupState);
628 for (const User *U : CleanupPad->users()) {
629 const auto *UserI = cast<Instruction>(U);
630 if (UserI->isEHPad())
631 report_fatal_error("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>(EHPad))
639 return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) &&
640 CatchSwitch->unwindsToCaller();
641 if (auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad))
642 return isa<ConstantTokenNone>(CleanupPad->getParentPad()) &&
643 getCleanupRetUnwindDest(CleanupPad) == nullptr;
644 if (isa<CatchPadInst>(EHPad))
645 return false;
646 llvm_unreachable("unexpected EHPad!");
647}
648
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(FirstNonPHI))
660 continue;
661 ::calculateSEHStateNumbers(FuncInfo, FirstNonPHI, -1);
662 }
663
665
666 bool IsEHa = Fn->getParent()->getModuleFlag("eh-asynch");
667 if (IsEHa) {
668 const BasicBlock *EntryBB = &(Fn->getEntryBlock());
669 calculateSEHStateForAsynchEH(EntryBB, -1, FuncInfo);
670 }
671}
672
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(FirstNonPHI))
684 continue;
685 calculateCXXStateNumbers(FuncInfo, FirstNonPHI, -1);
686 }
687
689
690 bool IsEHa = Fn->getParent()->getModuleFlag("eh-asynch");
691 if (IsEHa) {
692 const BasicBlock *EntryBB = &(Fn->getEntryBlock());
693 calculateCXXStateForAsynchEH(EntryBB, -1, FuncInfo);
694 }
695}
696
697static int addClrEHHandler(WinEHFuncInfo &FuncInfo, int HandlerParentState,
698 int TryParentState, ClrHandlerType HandlerType,
699 uint32_t TypeToken, const BasicBlock *Handler) {
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(Entry);
707 return FuncInfo.ClrEHUnwindMap.size() - 1;
708}
709
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.
741 for (const BasicBlock &BB : *Fn) {
742 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
743 const Value *ParentPad;
744 if (const auto *CPI = dyn_cast<CleanupPadInst>(FirstNonPHI))
745 ParentPad = CPI->getParentPad();
746 else if (const auto *CSI = dyn_cast<CatchSwitchInst>(FirstNonPHI))
747 ParentPad = CSI->getParentPad();
748 else
749 continue;
750 if (isa<ConstantTokenNone>(ParentPad))
751 Worklist.emplace_back(FirstNonPHI, -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(Pad, HandlerParentState) = Worklist.pop_back_val();
764
765 if (const auto *Cleanup = dyn_cast<CleanupPadInst>(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
771 int CleanupState = addClrEHHandler(FuncInfo, HandlerParentState, -1,
772 HandlerType, 0, 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>(U))
776 if (I->isEHPad())
777 Worklist.emplace_back(I, 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>(Pad);
784 int CatchState = -1, FollowerState = -1;
785 SmallVector<const BasicBlock *, 4> CatchBlocks(CatchSwitch->handlers());
786 for (const BasicBlock *CatchBlock : llvm::reverse(CatchBlocks)) {
787 // Create the entry for this catch with the appropriate handler
788 // properties.
789 const auto *Catch = cast<CatchPadInst>(CatchBlock->getFirstNonPHIIt());
791 "Malformed CatchPadInst not caught by win-eh-prepare");
792 uint32_t TypeToken = static_cast<uint32_t>(
793 cast<ConstantInt>(Catch->getArgOperand(0))->getZExtValue());
794 CatchState =
795 addClrEHHandler(FuncInfo, HandlerParentState, FollowerState,
796 ClrHandlerType::Catch, TypeToken, 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>(U))
800 if (I->isEHPad())
801 Worklist.emplace_back(I, 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(FuncInfo.ClrEHUnwindMap)) {
816 const Instruction *Pad =
817 &*cast<const BasicBlock *>(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>(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>(Pad);
833 UnwindDest = nullptr;
834 for (const User *U : Cleanup->users()) {
835 if (auto *CleanupRet = dyn_cast<CleanupReturnInst>(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>(U)) {
845 UserUnwindDest = Invoke->getUnwindDest();
846 } else if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(U)) {
847 UserUnwindDest = CatchSwitch->getUnwindDest();
848 } else if (auto *ChildCleanup = dyn_cast<CleanupPadInst>(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 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>(UserUnwindPad))
869 UserUnwindParent = CSI->getParentPad();
870 else
871 UserUnwindParent =
872 cast<CleanupPadInst>(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.
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(&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.
929 for (BasicBlock &BB : make_early_inc_range(F)) {
930 if (!BB.isEHPad())
931 continue;
932
933 for (Instruction &I : make_early_inc_range(BB)) {
934 auto *PN = dyn_cast<PHINode>(&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>(BB.getFirstNonPHIIt());
944 bool HasIncomingCatchSwitchBB = false;
945 for (unsigned I = 0, E = PN->getNumIncomingValues(); I < E; ++I) {
947 PN->getIncomingBlock(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(PN, SpillSlot);
961
962 PHINodes.push_back(PN);
963 }
964 }
965
966 for (auto *PN : PHINodes) {
967 // There may be lingering uses on other EH PHIs being removed
968 PN->replaceAllUsesWith(PoisonValue::get(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>(FuncletToken);
979
980 if (!CatchPad)
981 return false;
982
983 if (!isMalformedCatchpad(CatchPad, Personality))
984 return false;
985
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>(Handler->getFirstNonPHIIt())) {
994 LLVMContext &CTX = CPI->getContext();
995 IRBuilder<> Builder(CPI);
996
997 // default values for the CatchPad's args
1000 Value *constantZero = ConstantInt::get(Type::getInt32Ty(CTX), 0);
1001 switch (Personality) {
1003 args = {nullPtr, constantZero, nullPtr};
1004 break;
1009 args = {nullPtr};
1010 break;
1012 args = {constantZero};
1013 break;
1014 default:
1015 llvm_unreachable("Unsupported Personality for WinEH");
1016 };
1017 Value *NewCatchPad =
1018 Builder.CreateCatchPad(CPI->getParentPad(), args, CPI->getName());
1019 CPI->replaceAllUsesWith(NewCatchPad);
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(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, 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(&F, 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(BB, 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(NewBlock);
1085 ColorVector &NewColors = BlockColors[NewBlock];
1086 assert(NewColors.empty() && "A new block should only have one color!");
1087 NewColors.push_back(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(BlocksInFunclet, OldBlock);
1095 ColorVector &OldColors = BlockColors[OldBlock];
1096 llvm::erase(OldColors, 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, VMap,
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(OldBlock))
1121 if (auto *CatchRet = dyn_cast<CatchReturnInst>(Pred->getTerminator()))
1122 if (CatchRet->getCatchSwitchParentPad() == FuncletToken)
1123 FixupCatchrets.push_back(CatchRet);
1124
1125 for (CatchReturnInst *CatchRet : FixupCatchrets)
1126 CatchRet->setSuccessor(NewBlock);
1127 }
1128
1129 auto UpdatePHIOnClonedBlock = [&](PHINode *PN, bool IsForOldBlock) {
1131 [&](unsigned Idx) {
1132 BasicBlock *IncomingBlock = PN->getIncomingBlock(Idx);
1133 bool EdgeTargetsFunclet;
1134 if (auto *CRI =
1135 dyn_cast<CatchReturnInst>(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(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(OldBlock);
1173 if (OldBlockIdx == -1)
1174 break;
1175 Value *IV = SuccPN.getIncomingValue(OldBlockIdx);
1176
1177 // Remap the value if necessary.
1178 if (auto *Inst = dyn_cast<Instruction>(IV)) {
1179 ValueToValueMapTy::iterator I = VMap.find(Inst);
1180 if (I != VMap.end())
1181 IV = I->second;
1182 }
1183
1184 SuccPN.addIncoming(IV, 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>(const_cast<Value *>(VT.first));
1198 if (!OldI)
1199 continue;
1200 auto *NewI = cast<Instruction>(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>(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(&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(OldI->getType(), OldI->getName());
1223 SSAUpdate.AddAvailableValue(OldI->getParent(), OldI);
1224 SSAUpdate.AddAvailableValue(NewI->getParent(), NewI);
1225
1226 while (!UsesToRename.empty())
1227 SSAUpdate.RewriteUseAfterInsertions(*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>(FirstNonPHI);
1243 auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad);
1244 auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad);
1245
1246 for (BasicBlock *BB : BlocksInFunclet) {
1247 for (Instruction &I : *BB) {
1248 auto *CB = dyn_cast<CallBase>(&I);
1249 if (!CB)
1250 continue;
1251
1252 Value *FuncletBundleOperand = nullptr;
1253 if (auto BU = CB->getOperandBundle(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>(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>(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(BB->getTerminator()->getIterator());
1275 auto *CI = cast<CallInst>(&*CallI);
1277 } else {
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>(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>(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>(TI))
1296 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
1297 if (IsUnreachableRet || IsUnreachableCatchret ||
1298 IsUnreachableCleanupret) {
1299 Changed = true;
1301 } else if (isa<InvokeInst>(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.
1323 Changed |= ConstantFoldTerminator(&BB, /*DeleteDeadConditions=*/true);
1325 }
1326
1327 // We might have some unreachable blocks after cleaning up some impossible
1328 // control flow.
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.
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.
1402 for (Use &U : llvm::make_early_inc_range(PN->uses())) {
1403 auto *UsingInst = cast<Instruction>(U.getUser());
1404 if (isa<PHINode>(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(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.
1423
1424 Worklist.push_back({OriginalPHI->getParent(), OriginalPHI});
1425
1426 while (!Worklist.empty()) {
1427 BasicBlock *EHBlock;
1428 Value *InVal;
1429 std::tie(EHBlock, InVal) = Worklist.pop_back_val();
1430
1431 PHINode *PN = dyn_cast<PHINode>(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>(PredVal))
1441 continue;
1442
1443 insertPHIStore(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(EHBlock)) {
1449 insertPHIStore(PredBlock, 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({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,
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>(U.getUser());
1479 if (auto *UsingPHI = dyn_cast<PHINode>(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>(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(IncomingBlock, 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>(IncomingBlock->getTerminator());
1512 Goto->removeFromParent();
1513 CatchRet->removeFromParent();
1514 CatchRet->insertInto(IncomingBlock, IncomingBlock->end());
1515 Goto->insertInto(NewBlock, 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(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
1548 MCSymbol *InvokeBegin,
1549 MCSymbol *InvokeEnd) {
1550 assert(InvokeStateMap.count(II) &&
1551 "should get invoke with precomputed state");
1552 LabelToStateMap[InvokeBegin] = std::make_pair(InvokeStateMap[II], InvokeEnd);
1553}
1554
1555void WinEHFuncInfo::addIPToStateRange(int State, MCSymbol* InvokeBegin,
1556 MCSymbol* InvokeEnd) {
1557 LabelToStateMap[InvokeBegin] = std::make_pair(State, InvokeEnd);
1558}
1559
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.
nvptx lower args
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 bool isMalformedCatchpad(const CatchPadInst *CPI, EHPersonality Personality)
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
CatchSwitchInst * getCatchSwitch() const
Convenience accessors.
handler_range handlers()
iteration adapter for range-for loops.
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
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:237
unsigned arg_size() const
arg_size - Return the number of funcletpad arguments.
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th funcletpad argument.
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...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2901
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
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.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
An instruction for reading from memory.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h: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 PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
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
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
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
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:260
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,...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
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