LLVM  14.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 
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/ADT/MapVector.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/ADT/Triple.h"
22 #include "llvm/Analysis/CFG.h"
25 #include "llvm/CodeGen/Passes.h"
27 #include "llvm/IR/Verifier.h"
28 #include "llvm/InitializePasses.h"
29 #include "llvm/MC/MCSymbol.h"
30 #include "llvm/Pass.h"
32 #include "llvm/Support/Debug.h"
38 
39 using namespace llvm;
40 
41 #define DEBUG_TYPE "winehprepare"
42 
44  "disable-demotion", cl::Hidden,
45  cl::desc(
46  "Clone multicolor basic blocks but do not demote cross scopes"),
47  cl::init(false));
48 
50  "disable-cleanups", cl::Hidden,
51  cl::desc("Do not remove implausible terminators or other similar cleanups"),
52  cl::init(false));
53 
55  "demote-catchswitch-only", cl::Hidden,
56  cl::desc("Demote catchswitch BBs only (for wasm EH)"), cl::init(false));
57 
58 namespace {
59 
60 class WinEHPrepare : public FunctionPass {
61 public:
62  static char ID; // Pass identification, replacement for typeid.
63  WinEHPrepare(bool DemoteCatchSwitchPHIOnly = false)
64  : FunctionPass(ID), DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {}
65 
66  bool runOnFunction(Function &Fn) override;
67 
68  bool doFinalization(Module &M) override;
69 
70  void getAnalysisUsage(AnalysisUsage &AU) const override;
71 
72  StringRef getPassName() const override {
73  return "Windows exception handling preparation";
74  }
75 
76 private:
77  void insertPHIStores(PHINode *OriginalPHI, AllocaInst *SpillSlot);
78  void
79  insertPHIStore(BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
80  SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist);
81  AllocaInst *insertPHILoads(PHINode *PN, Function &F);
82  void replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
84  bool prepareExplicitEH(Function &F);
85  void colorFunclets(Function &F);
86 
87  void demotePHIsOnFunclets(Function &F, bool DemoteCatchSwitchPHIOnly);
88  void cloneCommonBlocks(Function &F);
89  void removeImplausibleInstructions(Function &F);
90  void cleanupPreparedFunclets(Function &F);
91  void verifyPreparedFunclets(Function &F);
92 
93  bool DemoteCatchSwitchPHIOnly;
94 
95  // All fields are reset by runOnFunction.
97 
98  const DataLayout *DL = nullptr;
101 };
102 
103 } // end anonymous namespace
104 
105 char WinEHPrepare::ID = 0;
106 INITIALIZE_PASS(WinEHPrepare, DEBUG_TYPE, "Prepare Windows exceptions",
107  false, false)
108 
109 FunctionPass *llvm::createWinEHPass(bool DemoteCatchSwitchPHIOnly) {
110  return new WinEHPrepare(DemoteCatchSwitchPHIOnly);
111 }
112 
114  if (!Fn.hasPersonalityFn())
115  return false;
116 
117  // Classify the personality to see what kind of preparation we need.
118  Personality = classifyEHPersonality(Fn.getPersonalityFn());
119 
120  // Do nothing if this is not a scope-based personality.
121  if (!isScopedEHPersonality(Personality))
122  return false;
123 
124  DL = &Fn.getParent()->getDataLayout();
125  return prepareExplicitEH(Fn);
126 }
127 
128 bool WinEHPrepare::doFinalization(Module &M) { return false; }
129 
130 void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {}
131 
132 static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState,
133  const BasicBlock *BB) {
134  CxxUnwindMapEntry UME;
135  UME.ToState = ToState;
136  UME.Cleanup = BB;
137  FuncInfo.CxxUnwindMap.push_back(UME);
138  return FuncInfo.getLastStateNumber();
139 }
140 
141 static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow,
142  int TryHigh, int CatchHigh,
145  TBME.TryLow = TryLow;
146  TBME.TryHigh = TryHigh;
147  TBME.CatchHigh = CatchHigh;
148  assert(TBME.TryLow <= TBME.TryHigh);
149  for (const CatchPadInst *CPI : Handlers) {
150  WinEHHandlerType HT;
151  Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0));
152  if (TypeInfo->isNullValue())
153  HT.TypeDescriptor = nullptr;
154  else
155  HT.TypeDescriptor = cast<GlobalVariable>(TypeInfo->stripPointerCasts());
156  HT.Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue();
157  HT.Handler = CPI->getParent();
158  if (auto *AI =
159  dyn_cast<AllocaInst>(CPI->getArgOperand(2)->stripPointerCasts()))
160  HT.CatchObj.Alloca = AI;
161  else
162  HT.CatchObj.Alloca = nullptr;
163  TBME.HandlerArray.push_back(HT);
164  }
165  FuncInfo.TryBlockMap.push_back(TBME);
166 }
167 
169  for (const User *U : CleanupPad->users())
170  if (const auto *CRI = dyn_cast<CleanupReturnInst>(U))
171  return CRI->getUnwindDest();
172  return nullptr;
173 }
174 
176  WinEHFuncInfo &FuncInfo) {
177  auto *F = const_cast<Function *>(Fn);
179  for (BasicBlock &BB : *F) {
180  auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
181  if (!II)
182  continue;
183 
184  auto &BBColors = BlockColors[&BB];
185  assert(BBColors.size() == 1 && "multi-color BB not removed by preparation");
186  BasicBlock *FuncletEntryBB = BBColors.front();
187 
188  BasicBlock *FuncletUnwindDest;
189  auto *FuncletPad =
190  dyn_cast<FuncletPadInst>(FuncletEntryBB->getFirstNonPHI());
191  assert(FuncletPad || FuncletEntryBB == &Fn->getEntryBlock());
192  if (!FuncletPad)
193  FuncletUnwindDest = nullptr;
194  else if (auto *CatchPad = dyn_cast<CatchPadInst>(FuncletPad))
195  FuncletUnwindDest = CatchPad->getCatchSwitch()->getUnwindDest();
196  else if (auto *CleanupPad = dyn_cast<CleanupPadInst>(FuncletPad))
197  FuncletUnwindDest = getCleanupRetUnwindDest(CleanupPad);
198  else
199  llvm_unreachable("unexpected funclet pad!");
200 
201  BasicBlock *InvokeUnwindDest = II->getUnwindDest();
202  int BaseState = -1;
203  if (FuncletUnwindDest == InvokeUnwindDest) {
204  auto BaseStateI = FuncInfo.FuncletBaseStateMap.find(FuncletPad);
205  if (BaseStateI != FuncInfo.FuncletBaseStateMap.end())
206  BaseState = BaseStateI->second;
207  }
208 
209  if (BaseState != -1) {
210  FuncInfo.InvokeStateMap[II] = BaseState;
211  } else {
212  Instruction *PadInst = InvokeUnwindDest->getFirstNonPHI();
213  assert(FuncInfo.EHPadStateMap.count(PadInst) && "EH Pad has no state!");
214  FuncInfo.InvokeStateMap[II] = FuncInfo.EHPadStateMap[PadInst];
215  }
216  }
217 }
218 
219 // Given BB which ends in an unwind edge, return the EHPad that this BB belongs
220 // to. If the unwind edge came from an invoke, return null.
222  Value *ParentPad) {
223  const Instruction *TI = BB->getTerminator();
224  if (isa<InvokeInst>(TI))
225  return nullptr;
226  if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(TI)) {
227  if (CatchSwitch->getParentPad() != ParentPad)
228  return nullptr;
229  return BB;
230  }
231  assert(!TI->isEHPad() && "unexpected EHPad!");
232  auto *CleanupPad = cast<CleanupReturnInst>(TI)->getCleanupPad();
233  if (CleanupPad->getParentPad() != ParentPad)
234  return nullptr;
235  return CleanupPad->getParent();
236 }
237 
238 // Starting from a EHPad, Backward walk through control-flow graph
239 // to produce two primary outputs:
240 // FuncInfo.EHPadStateMap[] and FuncInfo.CxxUnwindMap[]
242  const Instruction *FirstNonPHI,
243  int ParentState) {
244  const BasicBlock *BB = FirstNonPHI->getParent();
245  assert(BB->isEHPad() && "not a funclet!");
246 
247  if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
248  assert(FuncInfo.EHPadStateMap.count(CatchSwitch) == 0 &&
249  "shouldn't revist catch funclets!");
250 
252  for (const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
253  auto *CatchPad = cast<CatchPadInst>(CatchPadBB->getFirstNonPHI());
254  Handlers.push_back(CatchPad);
255  }
256  int TryLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
257  FuncInfo.EHPadStateMap[CatchSwitch] = TryLow;
258  for (const BasicBlock *PredBlock : predecessors(BB))
259  if ((PredBlock = getEHPadFromPredecessor(PredBlock,
260  CatchSwitch->getParentPad())))
261  calculateCXXStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
262  TryLow);
263  int CatchLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
264 
265  // catchpads are separate funclets in C++ EH due to the way rethrow works.
266  int TryHigh = CatchLow - 1;
267 
268  // MSVC FrameHandler3/4 on x64&Arm64 expect Catch Handlers in $tryMap$
269  // stored in pre-order (outer first, inner next), not post-order
270  // Add to map here. Fix the CatchHigh after children are processed
271  const Module *Mod = BB->getParent()->getParent();
272  bool IsPreOrder = Triple(Mod->getTargetTriple()).isArch64Bit();
273  if (IsPreOrder)
274  addTryBlockMapEntry(FuncInfo, TryLow, TryHigh, CatchLow, Handlers);
275  unsigned TBMEIdx = FuncInfo.TryBlockMap.size() - 1;
276 
277  for (const auto *CatchPad : Handlers) {
278  FuncInfo.FuncletBaseStateMap[CatchPad] = CatchLow;
279  for (const User *U : CatchPad->users()) {
280  const auto *UserI = cast<Instruction>(U);
281  if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
282  BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
283  if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
284  calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
285  }
286  if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
287  BasicBlock *UnwindDest = getCleanupRetUnwindDest(InnerCleanupPad);
288  // If a nested cleanup pad reports a null unwind destination and the
289  // enclosing catch pad doesn't it must be post-dominated by an
290  // unreachable instruction.
291  if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
292  calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
293  }
294  }
295  }
296  int CatchHigh = FuncInfo.getLastStateNumber();
297  // Now child Catches are processed, update CatchHigh
298  if (IsPreOrder)
299  FuncInfo.TryBlockMap[TBMEIdx].CatchHigh = CatchHigh;
300  else // PostOrder
301  addTryBlockMapEntry(FuncInfo, TryLow, TryHigh, CatchHigh, Handlers);
302 
303  LLVM_DEBUG(dbgs() << "TryLow[" << BB->getName() << "]: " << TryLow << '\n');
304  LLVM_DEBUG(dbgs() << "TryHigh[" << BB->getName() << "]: " << TryHigh
305  << '\n');
306  LLVM_DEBUG(dbgs() << "CatchHigh[" << BB->getName() << "]: " << CatchHigh
307  << '\n');
308  } else {
309  auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
310 
311  // It's possible for a cleanup to be visited twice: it might have multiple
312  // cleanupret instructions.
313  if (FuncInfo.EHPadStateMap.count(CleanupPad))
314  return;
315 
316  int CleanupState = addUnwindMapEntry(FuncInfo, ParentState, BB);
317  FuncInfo.EHPadStateMap[CleanupPad] = CleanupState;
318  LLVM_DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
319  << BB->getName() << '\n');
320  for (const BasicBlock *PredBlock : predecessors(BB)) {
321  if ((PredBlock = getEHPadFromPredecessor(PredBlock,
322  CleanupPad->getParentPad()))) {
323  calculateCXXStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
324  CleanupState);
325  }
326  }
327  for (const User *U : CleanupPad->users()) {
328  const auto *UserI = cast<Instruction>(U);
329  if (UserI->isEHPad())
330  report_fatal_error("Cleanup funclets for the MSVC++ personality cannot "
331  "contain exceptional actions");
332  }
333  }
334 }
335 
336 static int addSEHExcept(WinEHFuncInfo &FuncInfo, int ParentState,
337  const Function *Filter, const BasicBlock *Handler) {
338  SEHUnwindMapEntry Entry;
339  Entry.ToState = ParentState;
340  Entry.IsFinally = false;
341  Entry.Filter = Filter;
342  Entry.Handler = Handler;
343  FuncInfo.SEHUnwindMap.push_back(Entry);
344  return FuncInfo.SEHUnwindMap.size() - 1;
345 }
346 
347 static int addSEHFinally(WinEHFuncInfo &FuncInfo, int ParentState,
348  const BasicBlock *Handler) {
349  SEHUnwindMapEntry Entry;
350  Entry.ToState = ParentState;
351  Entry.IsFinally = true;
352  Entry.Filter = nullptr;
353  Entry.Handler = Handler;
354  FuncInfo.SEHUnwindMap.push_back(Entry);
355  return FuncInfo.SEHUnwindMap.size() - 1;
356 }
357 
358 // Starting from a EHPad, Backward walk through control-flow graph
359 // to produce two primary outputs:
360 // FuncInfo.EHPadStateMap[] and FuncInfo.SEHUnwindMap[]
362  const Instruction *FirstNonPHI,
363  int ParentState) {
364  const BasicBlock *BB = FirstNonPHI->getParent();
365  assert(BB->isEHPad() && "no a funclet!");
366 
367  if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
368  assert(FuncInfo.EHPadStateMap.count(CatchSwitch) == 0 &&
369  "shouldn't revist catch funclets!");
370 
371  // Extract the filter function and the __except basic block and create a
372  // state for them.
373  assert(CatchSwitch->getNumHandlers() == 1 &&
374  "SEH doesn't have multiple handlers per __try");
375  const auto *CatchPad =
376  cast<CatchPadInst>((*CatchSwitch->handler_begin())->getFirstNonPHI());
377  const BasicBlock *CatchPadBB = CatchPad->getParent();
378  const Constant *FilterOrNull =
379  cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts());
380  const Function *Filter = dyn_cast<Function>(FilterOrNull);
381  assert((Filter || FilterOrNull->isNullValue()) &&
382  "unexpected filter value");
383  int TryState = addSEHExcept(FuncInfo, ParentState, Filter, CatchPadBB);
384 
385  // Everything in the __try block uses TryState as its parent state.
386  FuncInfo.EHPadStateMap[CatchSwitch] = TryState;
387  LLVM_DEBUG(dbgs() << "Assigning state #" << TryState << " to BB "
388  << CatchPadBB->getName() << '\n');
389  for (const BasicBlock *PredBlock : predecessors(BB))
390  if ((PredBlock = getEHPadFromPredecessor(PredBlock,
391  CatchSwitch->getParentPad())))
392  calculateSEHStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
393  TryState);
394 
395  // Everything in the __except block unwinds to ParentState, just like code
396  // outside the __try.
397  for (const User *U : CatchPad->users()) {
398  const auto *UserI = cast<Instruction>(U);
399  if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
400  BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
401  if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
402  calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
403  }
404  if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
405  BasicBlock *UnwindDest = getCleanupRetUnwindDest(InnerCleanupPad);
406  // If a nested cleanup pad reports a null unwind destination and the
407  // enclosing catch pad doesn't it must be post-dominated by an
408  // unreachable instruction.
409  if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
410  calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
411  }
412  }
413  } else {
414  auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
415 
416  // It's possible for a cleanup to be visited twice: it might have multiple
417  // cleanupret instructions.
418  if (FuncInfo.EHPadStateMap.count(CleanupPad))
419  return;
420 
421  int CleanupState = addSEHFinally(FuncInfo, ParentState, BB);
422  FuncInfo.EHPadStateMap[CleanupPad] = CleanupState;
423  LLVM_DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
424  << BB->getName() << '\n');
425  for (const BasicBlock *PredBlock : predecessors(BB))
426  if ((PredBlock =
427  getEHPadFromPredecessor(PredBlock, CleanupPad->getParentPad())))
428  calculateSEHStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
429  CleanupState);
430  for (const User *U : CleanupPad->users()) {
431  const auto *UserI = cast<Instruction>(U);
432  if (UserI->isEHPad())
433  report_fatal_error("Cleanup funclets for the SEH personality cannot "
434  "contain exceptional actions");
435  }
436  }
437 }
438 
439 static bool isTopLevelPadForMSVC(const Instruction *EHPad) {
440  if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(EHPad))
441  return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) &&
442  CatchSwitch->unwindsToCaller();
443  if (auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad))
444  return isa<ConstantTokenNone>(CleanupPad->getParentPad()) &&
445  getCleanupRetUnwindDest(CleanupPad) == nullptr;
446  if (isa<CatchPadInst>(EHPad))
447  return false;
448  llvm_unreachable("unexpected EHPad!");
449 }
450 
452  WinEHFuncInfo &FuncInfo) {
453  // Don't compute state numbers twice.
454  if (!FuncInfo.SEHUnwindMap.empty())
455  return;
456 
457  for (const BasicBlock &BB : *Fn) {
458  if (!BB.isEHPad())
459  continue;
460  const Instruction *FirstNonPHI = BB.getFirstNonPHI();
461  if (!isTopLevelPadForMSVC(FirstNonPHI))
462  continue;
463  ::calculateSEHStateNumbers(FuncInfo, FirstNonPHI, -1);
464  }
465 
466  calculateStateNumbersForInvokes(Fn, FuncInfo);
467 }
468 
470  WinEHFuncInfo &FuncInfo) {
471  // Return if it's already been done.
472  if (!FuncInfo.EHPadStateMap.empty())
473  return;
474 
475  for (const BasicBlock &BB : *Fn) {
476  if (!BB.isEHPad())
477  continue;
478  const Instruction *FirstNonPHI = BB.getFirstNonPHI();
479  if (!isTopLevelPadForMSVC(FirstNonPHI))
480  continue;
481  calculateCXXStateNumbers(FuncInfo, FirstNonPHI, -1);
482  }
483 
484  calculateStateNumbersForInvokes(Fn, FuncInfo);
485 }
486 
487 static int addClrEHHandler(WinEHFuncInfo &FuncInfo, int HandlerParentState,
488  int TryParentState, ClrHandlerType HandlerType,
489  uint32_t TypeToken, const BasicBlock *Handler) {
490  ClrEHUnwindMapEntry Entry;
491  Entry.HandlerParentState = HandlerParentState;
492  Entry.TryParentState = TryParentState;
493  Entry.Handler = Handler;
494  Entry.HandlerType = HandlerType;
495  Entry.TypeToken = TypeToken;
496  FuncInfo.ClrEHUnwindMap.push_back(Entry);
497  return FuncInfo.ClrEHUnwindMap.size() - 1;
498 }
499 
501  WinEHFuncInfo &FuncInfo) {
502  // Return if it's already been done.
503  if (!FuncInfo.EHPadStateMap.empty())
504  return;
505 
506  // This numbering assigns one state number to each catchpad and cleanuppad.
507  // It also computes two tree-like relations over states:
508  // 1) Each state has a "HandlerParentState", which is the state of the next
509  // outer handler enclosing this state's handler (same as nearest ancestor
510  // per the ParentPad linkage on EH pads, but skipping over catchswitches).
511  // 2) Each state has a "TryParentState", which:
512  // a) for a catchpad that's not the last handler on its catchswitch, is
513  // the state of the next catchpad on that catchswitch
514  // b) for all other pads, is the state of the pad whose try region is the
515  // next outer try region enclosing this state's try region. The "try
516  // regions are not present as such in the IR, but will be inferred
517  // based on the placement of invokes and pads which reach each other
518  // by exceptional exits
519  // Catchswitches do not get their own states, but each gets mapped to the
520  // state of its first catchpad.
521 
522  // Step one: walk down from outermost to innermost funclets, assigning each
523  // catchpad and cleanuppad a state number. Add an entry to the
524  // ClrEHUnwindMap for each state, recording its HandlerParentState and
525  // handler attributes. Record the TryParentState as well for each catchpad
526  // that's not the last on its catchswitch, but initialize all other entries'
527  // TryParentStates to a sentinel -1 value that the next pass will update.
528 
529  // Seed a worklist with pads that have no parent.
531  for (const BasicBlock &BB : *Fn) {
532  const Instruction *FirstNonPHI = BB.getFirstNonPHI();
533  const Value *ParentPad;
534  if (const auto *CPI = dyn_cast<CleanupPadInst>(FirstNonPHI))
535  ParentPad = CPI->getParentPad();
536  else if (const auto *CSI = dyn_cast<CatchSwitchInst>(FirstNonPHI))
537  ParentPad = CSI->getParentPad();
538  else
539  continue;
540  if (isa<ConstantTokenNone>(ParentPad))
541  Worklist.emplace_back(FirstNonPHI, -1);
542  }
543 
544  // Use the worklist to visit all pads, from outer to inner. Record
545  // HandlerParentState for all pads. Record TryParentState only for catchpads
546  // that aren't the last on their catchswitch (setting all other entries'
547  // TryParentStates to an initial value of -1). This loop is also responsible
548  // for setting the EHPadStateMap entry for all catchpads, cleanuppads, and
549  // catchswitches.
550  while (!Worklist.empty()) {
551  const Instruction *Pad;
552  int HandlerParentState;
553  std::tie(Pad, HandlerParentState) = Worklist.pop_back_val();
554 
555  if (const auto *Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
556  // Create the entry for this cleanup with the appropriate handler
557  // properties. Finally and fault handlers are distinguished by arity.
558  ClrHandlerType HandlerType =
559  (Cleanup->getNumArgOperands() ? ClrHandlerType::Fault
561  int CleanupState = addClrEHHandler(FuncInfo, HandlerParentState, -1,
562  HandlerType, 0, Pad->getParent());
563  // Queue any child EH pads on the worklist.
564  for (const User *U : Cleanup->users())
565  if (const auto *I = dyn_cast<Instruction>(U))
566  if (I->isEHPad())
567  Worklist.emplace_back(I, CleanupState);
568  // Remember this pad's state.
569  FuncInfo.EHPadStateMap[Cleanup] = CleanupState;
570  } else {
571  // Walk the handlers of this catchswitch in reverse order since all but
572  // the last need to set the following one as its TryParentState.
573  const auto *CatchSwitch = cast<CatchSwitchInst>(Pad);
574  int CatchState = -1, FollowerState = -1;
575  SmallVector<const BasicBlock *, 4> CatchBlocks(CatchSwitch->handlers());
576  for (auto CBI = CatchBlocks.rbegin(), CBE = CatchBlocks.rend();
577  CBI != CBE; ++CBI, FollowerState = CatchState) {
578  const BasicBlock *CatchBlock = *CBI;
579  // Create the entry for this catch with the appropriate handler
580  // properties.
581  const auto *Catch = cast<CatchPadInst>(CatchBlock->getFirstNonPHI());
582  uint32_t TypeToken = static_cast<uint32_t>(
583  cast<ConstantInt>(Catch->getArgOperand(0))->getZExtValue());
584  CatchState =
585  addClrEHHandler(FuncInfo, HandlerParentState, FollowerState,
586  ClrHandlerType::Catch, TypeToken, CatchBlock);
587  // Queue any child EH pads on the worklist.
588  for (const User *U : Catch->users())
589  if (const auto *I = dyn_cast<Instruction>(U))
590  if (I->isEHPad())
591  Worklist.emplace_back(I, CatchState);
592  // Remember this catch's state.
593  FuncInfo.EHPadStateMap[Catch] = CatchState;
594  }
595  // Associate the catchswitch with the state of its first catch.
596  assert(CatchSwitch->getNumHandlers());
597  FuncInfo.EHPadStateMap[CatchSwitch] = CatchState;
598  }
599  }
600 
601  // Step two: record the TryParentState of each state. For cleanuppads that
602  // don't have cleanuprets, we may need to infer this from their child pads,
603  // so visit pads in descendant-most to ancestor-most order.
604  for (auto Entry = FuncInfo.ClrEHUnwindMap.rbegin(),
605  End = FuncInfo.ClrEHUnwindMap.rend();
606  Entry != End; ++Entry) {
607  const Instruction *Pad =
608  Entry->Handler.get<const BasicBlock *>()->getFirstNonPHI();
609  // For most pads, the TryParentState is the state associated with the
610  // unwind dest of exceptional exits from it.
611  const BasicBlock *UnwindDest;
612  if (const auto *Catch = dyn_cast<CatchPadInst>(Pad)) {
613  // If a catch is not the last in its catchswitch, its TryParentState is
614  // the state associated with the next catch in the switch, even though
615  // that's not the unwind dest of exceptions escaping the catch. Those
616  // cases were already assigned a TryParentState in the first pass, so
617  // skip them.
618  if (Entry->TryParentState != -1)
619  continue;
620  // Otherwise, get the unwind dest from the catchswitch.
621  UnwindDest = Catch->getCatchSwitch()->getUnwindDest();
622  } else {
623  const auto *Cleanup = cast<CleanupPadInst>(Pad);
624  UnwindDest = nullptr;
625  for (const User *U : Cleanup->users()) {
626  if (auto *CleanupRet = dyn_cast<CleanupReturnInst>(U)) {
627  // Common and unambiguous case -- cleanupret indicates cleanup's
628  // unwind dest.
629  UnwindDest = CleanupRet->getUnwindDest();
630  break;
631  }
632 
633  // Get an unwind dest for the user
634  const BasicBlock *UserUnwindDest = nullptr;
635  if (auto *Invoke = dyn_cast<InvokeInst>(U)) {
636  UserUnwindDest = Invoke->getUnwindDest();
637  } else if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(U)) {
638  UserUnwindDest = CatchSwitch->getUnwindDest();
639  } else if (auto *ChildCleanup = dyn_cast<CleanupPadInst>(U)) {
640  int UserState = FuncInfo.EHPadStateMap[ChildCleanup];
641  int UserUnwindState =
642  FuncInfo.ClrEHUnwindMap[UserState].TryParentState;
643  if (UserUnwindState != -1)
644  UserUnwindDest = FuncInfo.ClrEHUnwindMap[UserUnwindState]
645  .Handler.get<const BasicBlock *>();
646  }
647 
648  // Not having an unwind dest for this user might indicate that it
649  // doesn't unwind, so can't be taken as proof that the cleanup itself
650  // may unwind to caller (see e.g. SimplifyUnreachable and
651  // RemoveUnwindEdge).
652  if (!UserUnwindDest)
653  continue;
654 
655  // Now we have an unwind dest for the user, but we need to see if it
656  // unwinds all the way out of the cleanup or if it stays within it.
657  const Instruction *UserUnwindPad = UserUnwindDest->getFirstNonPHI();
658  const Value *UserUnwindParent;
659  if (auto *CSI = dyn_cast<CatchSwitchInst>(UserUnwindPad))
660  UserUnwindParent = CSI->getParentPad();
661  else
662  UserUnwindParent =
663  cast<CleanupPadInst>(UserUnwindPad)->getParentPad();
664 
665  // The unwind stays within the cleanup iff it targets a child of the
666  // cleanup.
667  if (UserUnwindParent == Cleanup)
668  continue;
669 
670  // This unwind exits the cleanup, so its dest is the cleanup's dest.
671  UnwindDest = UserUnwindDest;
672  break;
673  }
674  }
675 
676  // Record the state of the unwind dest as the TryParentState.
677  int UnwindDestState;
678 
679  // If UnwindDest is null at this point, either the pad in question can
680  // be exited by unwind to caller, or it cannot be exited by unwind. In
681  // either case, reporting such cases as unwinding to caller is correct.
682  // This can lead to EH tables that "look strange" -- if this pad's is in
683  // a parent funclet which has other children that do unwind to an enclosing
684  // pad, the try region for this pad will be missing the "duplicate" EH
685  // clause entries that you'd expect to see covering the whole parent. That
686  // should be benign, since the unwind never actually happens. If it were
687  // an issue, we could add a subsequent pass that pushes unwind dests down
688  // from parents that have them to children that appear to unwind to caller.
689  if (!UnwindDest) {
690  UnwindDestState = -1;
691  } else {
692  UnwindDestState = FuncInfo.EHPadStateMap[UnwindDest->getFirstNonPHI()];
693  }
694 
695  Entry->TryParentState = UnwindDestState;
696  }
697 
698  // Step three: transfer information from pads to invokes.
699  calculateStateNumbersForInvokes(Fn, FuncInfo);
700 }
701 
702 void WinEHPrepare::colorFunclets(Function &F) {
703  BlockColors = colorEHFunclets(F);
704 
705  // Invert the map from BB to colors to color to BBs.
706  for (BasicBlock &BB : F) {
707  ColorVector &Colors = BlockColors[&BB];
708  for (BasicBlock *Color : Colors)
709  FuncletBlocks[Color].push_back(&BB);
710  }
711 }
712 
713 void WinEHPrepare::demotePHIsOnFunclets(Function &F,
714  bool DemoteCatchSwitchPHIOnly) {
715  // Strip PHI nodes off of EH pads.
717  for (BasicBlock &BB : make_early_inc_range(F)) {
718  if (!BB.isEHPad())
719  continue;
720  if (DemoteCatchSwitchPHIOnly && !isa<CatchSwitchInst>(BB.getFirstNonPHI()))
721  continue;
722 
724  auto *PN = dyn_cast<PHINode>(&I);
725  // Stop at the first non-PHI.
726  if (!PN)
727  break;
728 
729  AllocaInst *SpillSlot = insertPHILoads(PN, F);
730  if (SpillSlot)
731  insertPHIStores(PN, SpillSlot);
732 
733  PHINodes.push_back(PN);
734  }
735  }
736 
737  for (auto *PN : PHINodes) {
738  // There may be lingering uses on other EH PHIs being removed
739  PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
740  PN->eraseFromParent();
741  }
742 }
743 
744 void WinEHPrepare::cloneCommonBlocks(Function &F) {
745  // We need to clone all blocks which belong to multiple funclets. Values are
746  // remapped throughout the funclet to propagate both the new instructions
747  // *and* the new basic blocks themselves.
748  for (auto &Funclets : FuncletBlocks) {
749  BasicBlock *FuncletPadBB = Funclets.first;
750  std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
751  Value *FuncletToken;
752  if (FuncletPadBB == &F.getEntryBlock())
753  FuncletToken = ConstantTokenNone::get(F.getContext());
754  else
755  FuncletToken = FuncletPadBB->getFirstNonPHI();
756 
757  std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
758  ValueToValueMapTy VMap;
759  for (BasicBlock *BB : BlocksInFunclet) {
760  ColorVector &ColorsForBB = BlockColors[BB];
761  // We don't need to do anything if the block is monochromatic.
762  size_t NumColorsForBB = ColorsForBB.size();
763  if (NumColorsForBB == 1)
764  continue;
765 
766  DEBUG_WITH_TYPE("winehprepare-coloring",
767  dbgs() << " Cloning block \'" << BB->getName()
768  << "\' for funclet \'" << FuncletPadBB->getName()
769  << "\'.\n");
770 
771  // Create a new basic block and copy instructions into it!
772  BasicBlock *CBB =
773  CloneBasicBlock(BB, VMap, Twine(".for.", FuncletPadBB->getName()));
774  // Insert the clone immediately after the original to ensure determinism
775  // and to keep the same relative ordering of any funclet's blocks.
776  CBB->insertInto(&F, BB->getNextNode());
777 
778  // Add basic block mapping.
779  VMap[BB] = CBB;
780 
781  // Record delta operations that we need to perform to our color mappings.
782  Orig2Clone.emplace_back(BB, CBB);
783  }
784 
785  // If nothing was cloned, we're done cloning in this funclet.
786  if (Orig2Clone.empty())
787  continue;
788 
789  // Update our color mappings to reflect that one block has lost a color and
790  // another has gained a color.
791  for (auto &BBMapping : Orig2Clone) {
792  BasicBlock *OldBlock = BBMapping.first;
793  BasicBlock *NewBlock = BBMapping.second;
794 
795  BlocksInFunclet.push_back(NewBlock);
796  ColorVector &NewColors = BlockColors[NewBlock];
797  assert(NewColors.empty() && "A new block should only have one color!");
798  NewColors.push_back(FuncletPadBB);
799 
800  DEBUG_WITH_TYPE("winehprepare-coloring",
801  dbgs() << " Assigned color \'" << FuncletPadBB->getName()
802  << "\' to block \'" << NewBlock->getName()
803  << "\'.\n");
804 
805  llvm::erase_value(BlocksInFunclet, OldBlock);
806  ColorVector &OldColors = BlockColors[OldBlock];
807  llvm::erase_value(OldColors, FuncletPadBB);
808 
809  DEBUG_WITH_TYPE("winehprepare-coloring",
810  dbgs() << " Removed color \'" << FuncletPadBB->getName()
811  << "\' from block \'" << OldBlock->getName()
812  << "\'.\n");
813  }
814 
815  // Loop over all of the instructions in this funclet, fixing up operand
816  // references as we go. This uses VMap to do all the hard work.
817  for (BasicBlock *BB : BlocksInFunclet)
818  // Loop over all instructions, fixing each one as we find it...
819  for (Instruction &I : *BB)
820  RemapInstruction(&I, VMap,
822 
823  // Catchrets targeting cloned blocks need to be updated separately from
824  // the loop above because they are not in the current funclet.
825  SmallVector<CatchReturnInst *, 2> FixupCatchrets;
826  for (auto &BBMapping : Orig2Clone) {
827  BasicBlock *OldBlock = BBMapping.first;
828  BasicBlock *NewBlock = BBMapping.second;
829 
830  FixupCatchrets.clear();
831  for (BasicBlock *Pred : predecessors(OldBlock))
832  if (auto *CatchRet = dyn_cast<CatchReturnInst>(Pred->getTerminator()))
833  if (CatchRet->getCatchSwitchParentPad() == FuncletToken)
834  FixupCatchrets.push_back(CatchRet);
835 
836  for (CatchReturnInst *CatchRet : FixupCatchrets)
837  CatchRet->setSuccessor(NewBlock);
838  }
839 
840  auto UpdatePHIOnClonedBlock = [&](PHINode *PN, bool IsForOldBlock) {
841  unsigned NumPreds = PN->getNumIncomingValues();
842  for (unsigned PredIdx = 0, PredEnd = NumPreds; PredIdx != PredEnd;
843  ++PredIdx) {
844  BasicBlock *IncomingBlock = PN->getIncomingBlock(PredIdx);
845  bool EdgeTargetsFunclet;
846  if (auto *CRI =
847  dyn_cast<CatchReturnInst>(IncomingBlock->getTerminator())) {
848  EdgeTargetsFunclet = (CRI->getCatchSwitchParentPad() == FuncletToken);
849  } else {
850  ColorVector &IncomingColors = BlockColors[IncomingBlock];
851  assert(!IncomingColors.empty() && "Block not colored!");
852  assert((IncomingColors.size() == 1 ||
853  llvm::all_of(IncomingColors,
854  [&](BasicBlock *Color) {
855  return Color != FuncletPadBB;
856  })) &&
857  "Cloning should leave this funclet's blocks monochromatic");
858  EdgeTargetsFunclet = (IncomingColors.front() == FuncletPadBB);
859  }
860  if (IsForOldBlock != EdgeTargetsFunclet)
861  continue;
862  PN->removeIncomingValue(IncomingBlock, /*DeletePHIIfEmpty=*/false);
863  // Revisit the next entry.
864  --PredIdx;
865  --PredEnd;
866  }
867  };
868 
869  for (auto &BBMapping : Orig2Clone) {
870  BasicBlock *OldBlock = BBMapping.first;
871  BasicBlock *NewBlock = BBMapping.second;
872  for (PHINode &OldPN : OldBlock->phis()) {
873  UpdatePHIOnClonedBlock(&OldPN, /*IsForOldBlock=*/true);
874  }
875  for (PHINode &NewPN : NewBlock->phis()) {
876  UpdatePHIOnClonedBlock(&NewPN, /*IsForOldBlock=*/false);
877  }
878  }
879 
880  // Check to see if SuccBB has PHI nodes. If so, we need to add entries to
881  // the PHI nodes for NewBB now.
882  for (auto &BBMapping : Orig2Clone) {
883  BasicBlock *OldBlock = BBMapping.first;
884  BasicBlock *NewBlock = BBMapping.second;
885  for (BasicBlock *SuccBB : successors(NewBlock)) {
886  for (PHINode &SuccPN : SuccBB->phis()) {
887  // Ok, we have a PHI node. Figure out what the incoming value was for
888  // the OldBlock.
889  int OldBlockIdx = SuccPN.getBasicBlockIndex(OldBlock);
890  if (OldBlockIdx == -1)
891  break;
892  Value *IV = SuccPN.getIncomingValue(OldBlockIdx);
893 
894  // Remap the value if necessary.
895  if (auto *Inst = dyn_cast<Instruction>(IV)) {
896  ValueToValueMapTy::iterator I = VMap.find(Inst);
897  if (I != VMap.end())
898  IV = I->second;
899  }
900 
901  SuccPN.addIncoming(IV, NewBlock);
902  }
903  }
904  }
905 
906  for (ValueToValueMapTy::value_type VT : VMap) {
907  // If there were values defined in BB that are used outside the funclet,
908  // then we now have to update all uses of the value to use either the
909  // original value, the cloned value, or some PHI derived value. This can
910  // require arbitrary PHI insertion, of which we are prepared to do, clean
911  // these up now.
912  SmallVector<Use *, 16> UsesToRename;
913 
914  auto *OldI = dyn_cast<Instruction>(const_cast<Value *>(VT.first));
915  if (!OldI)
916  continue;
917  auto *NewI = cast<Instruction>(VT.second);
918  // Scan all uses of this instruction to see if it is used outside of its
919  // funclet, and if so, record them in UsesToRename.
920  for (Use &U : OldI->uses()) {
921  Instruction *UserI = cast<Instruction>(U.getUser());
922  BasicBlock *UserBB = UserI->getParent();
923  ColorVector &ColorsForUserBB = BlockColors[UserBB];
924  assert(!ColorsForUserBB.empty());
925  if (ColorsForUserBB.size() > 1 ||
926  *ColorsForUserBB.begin() != FuncletPadBB)
927  UsesToRename.push_back(&U);
928  }
929 
930  // If there are no uses outside the block, we're done with this
931  // instruction.
932  if (UsesToRename.empty())
933  continue;
934 
935  // We found a use of OldI outside of the funclet. Rename all uses of OldI
936  // that are outside its funclet to be uses of the appropriate PHI node
937  // etc.
938  SSAUpdater SSAUpdate;
939  SSAUpdate.Initialize(OldI->getType(), OldI->getName());
940  SSAUpdate.AddAvailableValue(OldI->getParent(), OldI);
941  SSAUpdate.AddAvailableValue(NewI->getParent(), NewI);
942 
943  while (!UsesToRename.empty())
944  SSAUpdate.RewriteUseAfterInsertions(*UsesToRename.pop_back_val());
945  }
946  }
947 }
948 
949 void WinEHPrepare::removeImplausibleInstructions(Function &F) {
950  // Remove implausible terminators and replace them with UnreachableInst.
951  for (auto &Funclet : FuncletBlocks) {
952  BasicBlock *FuncletPadBB = Funclet.first;
953  std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
954  Instruction *FirstNonPHI = FuncletPadBB->getFirstNonPHI();
955  auto *FuncletPad = dyn_cast<FuncletPadInst>(FirstNonPHI);
956  auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad);
957  auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad);
958 
959  for (BasicBlock *BB : BlocksInFunclet) {
960  for (Instruction &I : *BB) {
961  auto *CB = dyn_cast<CallBase>(&I);
962  if (!CB)
963  continue;
964 
965  Value *FuncletBundleOperand = nullptr;
966  if (auto BU = CB->getOperandBundle(LLVMContext::OB_funclet))
967  FuncletBundleOperand = BU->Inputs.front();
968 
969  if (FuncletBundleOperand == FuncletPad)
970  continue;
971 
972  // Skip call sites which are nounwind intrinsics or inline asm.
973  auto *CalledFn =
974  dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());
975  if (CalledFn && ((CalledFn->isIntrinsic() && CB->doesNotThrow()) ||
976  CB->isInlineAsm()))
977  continue;
978 
979  // This call site was not part of this funclet, remove it.
980  if (isa<InvokeInst>(CB)) {
981  // Remove the unwind edge if it was an invoke.
983  // Get a pointer to the new call.
984  BasicBlock::iterator CallI =
985  std::prev(BB->getTerminator()->getIterator());
986  auto *CI = cast<CallInst>(&*CallI);
988  } else {
990  }
991 
992  // There are no more instructions in the block (except for unreachable),
993  // we are done.
994  break;
995  }
996 
997  Instruction *TI = BB->getTerminator();
998  // CatchPadInst and CleanupPadInst can't transfer control to a ReturnInst.
999  bool IsUnreachableRet = isa<ReturnInst>(TI) && FuncletPad;
1000  // The token consumed by a CatchReturnInst must match the funclet token.
1001  bool IsUnreachableCatchret = false;
1002  if (auto *CRI = dyn_cast<CatchReturnInst>(TI))
1003  IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
1004  // The token consumed by a CleanupReturnInst must match the funclet token.
1005  bool IsUnreachableCleanupret = false;
1006  if (auto *CRI = dyn_cast<CleanupReturnInst>(TI))
1007  IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
1008  if (IsUnreachableRet || IsUnreachableCatchret ||
1009  IsUnreachableCleanupret) {
1010  changeToUnreachable(TI);
1011  } else if (isa<InvokeInst>(TI)) {
1012  if (Personality == EHPersonality::MSVC_CXX && CleanupPad) {
1013  // Invokes within a cleanuppad for the MSVC++ personality never
1014  // transfer control to their unwind edge: the personality will
1015  // terminate the program.
1017  }
1018  }
1019  }
1020  }
1021 }
1022 
1023 void WinEHPrepare::cleanupPreparedFunclets(Function &F) {
1024  // Clean-up some of the mess we made by removing useles PHI nodes, trivial
1025  // branches, etc.
1028  ConstantFoldTerminator(&BB, /*DeleteDeadConditions=*/true);
1030  }
1031 
1032  // We might have some unreachable blocks after cleaning up some impossible
1033  // control flow.
1035 }
1036 
1037 #ifndef NDEBUG
1038 void WinEHPrepare::verifyPreparedFunclets(Function &F) {
1039  for (BasicBlock &BB : F) {
1040  size_t NumColors = BlockColors[&BB].size();
1041  assert(NumColors == 1 && "Expected monochromatic BB!");
1042  if (NumColors == 0)
1043  report_fatal_error("Uncolored BB!");
1044  if (NumColors > 1)
1045  report_fatal_error("Multicolor BB!");
1046  assert((DisableDemotion || !(BB.isEHPad() && isa<PHINode>(BB.begin()))) &&
1047  "EH Pad still has a PHI!");
1048  }
1049 }
1050 #endif
1051 
1052 bool WinEHPrepare::prepareExplicitEH(Function &F) {
1053  // Remove unreachable blocks. It is not valuable to assign them a color and
1054  // their existence can trick us into thinking values are alive when they are
1055  // not.
1057 
1058  // Determine which blocks are reachable from which funclet entries.
1059  colorFunclets(F);
1060 
1061  cloneCommonBlocks(F);
1062 
1063  if (!DisableDemotion)
1064  demotePHIsOnFunclets(F, DemoteCatchSwitchPHIOnly ||
1066 
1067  if (!DisableCleanups) {
1068  assert(!verifyFunction(F, &dbgs()));
1069  removeImplausibleInstructions(F);
1070 
1071  assert(!verifyFunction(F, &dbgs()));
1072  cleanupPreparedFunclets(F);
1073  }
1074 
1075  LLVM_DEBUG(verifyPreparedFunclets(F));
1076  // Recolor the CFG to verify that all is well.
1077  LLVM_DEBUG(colorFunclets(F));
1078  LLVM_DEBUG(verifyPreparedFunclets(F));
1079 
1080  BlockColors.clear();
1081  FuncletBlocks.clear();
1082 
1083  return true;
1084 }
1085 
1086 // TODO: Share loads when one use dominates another, or when a catchpad exit
1087 // dominates uses (needs dominators).
1088 AllocaInst *WinEHPrepare::insertPHILoads(PHINode *PN, Function &F) {
1089  BasicBlock *PHIBlock = PN->getParent();
1090  AllocaInst *SpillSlot = nullptr;
1091  Instruction *EHPad = PHIBlock->getFirstNonPHI();
1092 
1093  if (!EHPad->isTerminator()) {
1094  // If the EHPad isn't a terminator, then we can insert a load in this block
1095  // that will dominate all uses.
1096  SpillSlot = new AllocaInst(PN->getType(), DL->getAllocaAddrSpace(), nullptr,
1097  Twine(PN->getName(), ".wineh.spillslot"),
1098  &F.getEntryBlock().front());
1099  Value *V = new LoadInst(PN->getType(), SpillSlot,
1100  Twine(PN->getName(), ".wineh.reload"),
1101  &*PHIBlock->getFirstInsertionPt());
1102  PN->replaceAllUsesWith(V);
1103  return SpillSlot;
1104  }
1105 
1106  // Otherwise, we have a PHI on a terminator EHPad, and we give up and insert
1107  // loads of the slot before every use.
1109  for (Use &U : llvm::make_early_inc_range(PN->uses())) {
1110  auto *UsingInst = cast<Instruction>(U.getUser());
1111  if (isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
1112  // Use is on an EH pad phi. Leave it alone; we'll insert loads and
1113  // stores for it separately.
1114  continue;
1115  }
1116  replaceUseWithLoad(PN, U, SpillSlot, Loads, F);
1117  }
1118  return SpillSlot;
1119 }
1120 
1121 // TODO: improve store placement. Inserting at def is probably good, but need
1122 // to be careful not to introduce interfering stores (needs liveness analysis).
1123 // TODO: identify related phi nodes that can share spill slots, and share them
1124 // (also needs liveness).
1125 void WinEHPrepare::insertPHIStores(PHINode *OriginalPHI,
1126  AllocaInst *SpillSlot) {
1127  // Use a worklist of (Block, Value) pairs -- the given Value needs to be
1128  // stored to the spill slot by the end of the given Block.
1130 
1131  Worklist.push_back({OriginalPHI->getParent(), OriginalPHI});
1132 
1133  while (!Worklist.empty()) {
1134  BasicBlock *EHBlock;
1135  Value *InVal;
1136  std::tie(EHBlock, InVal) = Worklist.pop_back_val();
1137 
1138  PHINode *PN = dyn_cast<PHINode>(InVal);
1139  if (PN && PN->getParent() == EHBlock) {
1140  // The value is defined by another PHI we need to remove, with no room to
1141  // insert a store after the PHI, so each predecessor needs to store its
1142  // incoming value.
1143  for (unsigned i = 0, e = PN->getNumIncomingValues(); i < e; ++i) {
1144  Value *PredVal = PN->getIncomingValue(i);
1145 
1146  // Undef can safely be skipped.
1147  if (isa<UndefValue>(PredVal))
1148  continue;
1149 
1150  insertPHIStore(PN->getIncomingBlock(i), PredVal, SpillSlot, Worklist);
1151  }
1152  } else {
1153  // We need to store InVal, which dominates EHBlock, but can't put a store
1154  // in EHBlock, so need to put stores in each predecessor.
1155  for (BasicBlock *PredBlock : predecessors(EHBlock)) {
1156  insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
1157  }
1158  }
1159  }
1160 }
1161 
1162 void WinEHPrepare::insertPHIStore(
1163  BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
1164  SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist) {
1165 
1166  if (PredBlock->isEHPad() && PredBlock->getFirstNonPHI()->isTerminator()) {
1167  // Pred is unsplittable, so we need to queue it on the worklist.
1168  Worklist.push_back({PredBlock, PredVal});
1169  return;
1170  }
1171 
1172  // Otherwise, insert the store at the end of the basic block.
1173  new StoreInst(PredVal, SpillSlot, PredBlock->getTerminator());
1174 }
1175 
1176 void WinEHPrepare::replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
1178  Function &F) {
1179  // Lazilly create the spill slot.
1180  if (!SpillSlot)
1181  SpillSlot = new AllocaInst(V->getType(), DL->getAllocaAddrSpace(), nullptr,
1182  Twine(V->getName(), ".wineh.spillslot"),
1183  &F.getEntryBlock().front());
1184 
1185  auto *UsingInst = cast<Instruction>(U.getUser());
1186  if (auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) {
1187  // If this is a PHI node, we can't insert a load of the value before
1188  // the use. Instead insert the load in the predecessor block
1189  // corresponding to the incoming value.
1190  //
1191  // Note that if there are multiple edges from a basic block to this
1192  // PHI node that we cannot have multiple loads. The problem is that
1193  // the resulting PHI node will have multiple values (from each load)
1194  // coming in from the same block, which is illegal SSA form.
1195  // For this reason, we keep track of and reuse loads we insert.
1196  BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
1197  if (auto *CatchRet =
1198  dyn_cast<CatchReturnInst>(IncomingBlock->getTerminator())) {
1199  // Putting a load above a catchret and use on the phi would still leave
1200  // a cross-funclet def/use. We need to split the edge, change the
1201  // catchret to target the new block, and put the load there.
1202  BasicBlock *PHIBlock = UsingInst->getParent();
1203  BasicBlock *NewBlock = SplitEdge(IncomingBlock, PHIBlock);
1204  // SplitEdge gives us:
1205  // IncomingBlock:
1206  // ...
1207  // br label %NewBlock
1208  // NewBlock:
1209  // catchret label %PHIBlock
1210  // But we need:
1211  // IncomingBlock:
1212  // ...
1213  // catchret label %NewBlock
1214  // NewBlock:
1215  // br label %PHIBlock
1216  // So move the terminators to each others' blocks and swap their
1217  // successors.
1218  BranchInst *Goto = cast<BranchInst>(IncomingBlock->getTerminator());
1219  Goto->removeFromParent();
1220  CatchRet->removeFromParent();
1221  IncomingBlock->getInstList().push_back(CatchRet);
1222  NewBlock->getInstList().push_back(Goto);
1223  Goto->setSuccessor(0, PHIBlock);
1224  CatchRet->setSuccessor(NewBlock);
1225  // Update the color mapping for the newly split edge.
1226  // Grab a reference to the ColorVector to be inserted before getting the
1227  // reference to the vector we are copying because inserting the new
1228  // element in BlockColors might cause the map to be reallocated.
1229  ColorVector &ColorsForNewBlock = BlockColors[NewBlock];
1230  ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
1231  ColorsForNewBlock = ColorsForPHIBlock;
1232  for (BasicBlock *FuncletPad : ColorsForPHIBlock)
1233  FuncletBlocks[FuncletPad].push_back(NewBlock);
1234  // Treat the new block as incoming for load insertion.
1235  IncomingBlock = NewBlock;
1236  }
1237  Value *&Load = Loads[IncomingBlock];
1238  // Insert the load into the predecessor block
1239  if (!Load)
1240  Load = new LoadInst(V->getType(), SpillSlot,
1241  Twine(V->getName(), ".wineh.reload"),
1242  /*isVolatile=*/false, IncomingBlock->getTerminator());
1243 
1244  U.set(Load);
1245  } else {
1246  // Reload right before the old use.
1247  auto *Load = new LoadInst(V->getType(), SpillSlot,
1248  Twine(V->getName(), ".wineh.reload"),
1249  /*isVolatile=*/false, UsingInst);
1250  U.set(Load);
1251  }
1252 }
1253 
1255  MCSymbol *InvokeBegin,
1256  MCSymbol *InvokeEnd) {
1257  assert(InvokeStateMap.count(II) &&
1258  "should get invoke with precomputed state");
1259  LabelToStateMap[InvokeBegin] = std::make_pair(InvokeStateMap[II], InvokeEnd);
1260 }
1261 
llvm::EHPersonality::MSVC_CXX
@ MSVC_CXX
i
i
Definition: README.txt:29
llvm::SSAUpdater::Initialize
void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
Definition: SSAUpdater.cpp:53
llvm::Instruction::isTerminator
bool isTerminator() const
Definition: Instruction.h:163
llvm::predecessors
pred_range predecessors(BasicBlock *BB)
Definition: CFG.h:127
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:113
llvm::BasicBlock::iterator
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:90
llvm::BasicBlock::getParent
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:107
llvm::ValueMap::end
iterator end()
Definition: ValueMap.h:136
llvm::WinEHFuncInfo::CxxUnwindMap
SmallVector< CxxUnwindMapEntry, 4 > CxxUnwindMap
Definition: WinEHFuncInfo.h:95
INITIALIZE_PASS
INITIALIZE_PASS(WinEHPrepare, DEBUG_TYPE, "Prepare Windows exceptions", false, false) FunctionPass *llvm
Definition: WinEHPrepare.cpp:106
llvm::Function
Definition: Function.h:62
Pass.h
llvm::WinEHFuncInfo::ClrEHUnwindMap
SmallVector< ClrEHUnwindMapEntry, 4 > ClrEHUnwindMap
Definition: WinEHFuncInfo.h:98
llvm::WinEHFuncInfo::InvokeStateMap
DenseMap< const InvokeInst *, int > InvokeStateMap
Definition: WinEHFuncInfo.h:93
llvm::ClrEHUnwindMapEntry
Definition: WinEHFuncInfo.h:81
addSEHFinally
static int addSEHFinally(WinEHFuncInfo &FuncInfo, int ParentState, const BasicBlock *Handler)
Definition: WinEHPrepare.cpp:347
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::Function::getEntryBlock
const BasicBlock & getEntryBlock() const
Definition: Function.h:718
MapVector.h
llvm::WinEHFuncInfo::addIPToStateRange
void addIPToStateRange(const InvokeInst *II, MCSymbol *InvokeBegin, MCSymbol *InvokeEnd)
Definition: WinEHPrepare.cpp:1254
llvm::PHINode::removeIncomingValue
Value * removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty=true)
Remove an incoming value.
Definition: Instructions.cpp:113
llvm::WinEHHandlerType
Definition: WinEHFuncInfo.h:60
Local.h
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
MachineBasicBlock.h
llvm::verifyFunction
bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
Definition: Verifier.cpp:5817
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
llvm::SPII::Load
@ Load
Definition: SparcInstrInfo.h:32
llvm::WinEHFuncInfo::TryBlockMap
SmallVector< WinEHTryBlockMapEntry, 4 > TryBlockMap
Definition: WinEHFuncInfo.h:96
DenseMap.h
llvm::removeUnreachableBlocks
bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
Definition: Local.cpp:2447
EHPersonalities.h
llvm::TinyPtrVector::front
EltTy front() const
Definition: TinyPtrVector.h:230
isTopLevelPadForMSVC
static bool isTopLevelPadForMSVC(const Instruction *EHPad)
Definition: WinEHPrepare.cpp:439
llvm::TinyPtrVector::begin
iterator begin()
Definition: TinyPtrVector.h:185
llvm::MapVector
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:37
STLExtras.h
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:635
llvm::successors
succ_range successors(Instruction *I)
Definition: CFG.h:262
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::BranchInst::setSuccessor
void setSuccessor(unsigned idx, BasicBlock *NewSucc)
Definition: Instructions.h:3166
llvm::Triple::isArch64Bit
bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition: Triple.cpp:1342
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::CxxUnwindMapEntry::Cleanup
MBBOrBasicBlock Cleanup
Definition: WinEHFuncInfo.h:42
llvm::classifyEHPersonality
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
Definition: EHPersonalities.cpp:21
CommandLine.h
llvm::WinEHFuncInfo::FuncletBaseStateMap
DenseMap< const FuncletPadInst *, int > FuncletBaseStateMap
Definition: WinEHFuncInfo.h:92
llvm::all_of
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1551
DEBUG_WITH_TYPE
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
Definition: Debug.h:64
llvm::RemapInstruction
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
Definition: ValueMapper.h:253
llvm::SimplifyInstructionsInBlock
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:701
llvm::WinEHFuncInfo::getLastStateNumber
int getLastStateNumber() const
Definition: WinEHFuncInfo.h:102
llvm::WinEHHandlerType::Adjectives
int Adjectives
Definition: WinEHFuncInfo.h:61
llvm::PHINode::getIncomingValue
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
Definition: Instructions.h:2729
llvm::Constant::isNullValue
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Definition: Constants.cpp:74
llvm::WinEHHandlerType::CatchObj
union llvm::WinEHHandlerType::@225 CatchObj
The CatchObj starts out life as an LLVM alloca and is eventually turned frame index.
llvm::User
Definition: User.h:44
getCleanupRetUnwindDest
static BasicBlock * getCleanupRetUnwindDest(const CleanupPadInst *CleanupPad)
Definition: WinEHPrepare.cpp:168
calculateCXXStateNumbers
static void calculateCXXStateNumbers(WinEHFuncInfo &FuncInfo, const Instruction *FirstNonPHI, int ParentState)
Definition: WinEHPrepare.cpp:241
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::TinyPtrVector::push_back
void push_back(EltTy NewVal)
Definition: TinyPtrVector.h:244
MCSymbol.h
llvm::LLVMContext::OB_funclet
@ OB_funclet
Definition: LLVMContext.h:91
llvm::Value::uses
iterator_range< use_iterator > uses()
Definition: Value.h:377
llvm::BasicBlock::getFirstInsertionPt
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
Definition: BasicBlock.cpp:253
llvm::SSAUpdater::RewriteUseAfterInsertions
void RewriteUseAfterInsertions(Use &U)
Rewrite a use like RewriteUse but handling in-block definitions.
Definition: SSAUpdater.cpp:199
llvm::Instruction
Definition: Instruction.h:45
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
llvm::WinEHFuncInfo::WinEHFuncInfo
WinEHFuncInfo()
Definition: WinEHPrepare.cpp:1262
llvm::BasicBlock::phis
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
Definition: BasicBlock.h:354
llvm::Function::hasPersonalityFn
bool hasPersonalityFn() const
Check whether this function has a personality function.
Definition: Function.h:786
llvm::ClrHandlerType::Fault
@ Fault
llvm::UndefValue::get
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1796
llvm::Use::getUser
User * getUser() const
Returns the User that contains this Use.
Definition: Use.h:73
llvm::Instruction::removeFromParent
void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
Definition: Instruction.cpp:74
llvm::BasicBlock::getFirstNonPHI
const Instruction * getFirstNonPHI() const
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
Definition: BasicBlock.cpp:216
llvm::WinEHHandlerType::Alloca
const AllocaInst * Alloca
Definition: WinEHFuncInfo.h:65
llvm::PHINode::getNumIncomingValues
unsigned getNumIncomingValues() const
Return the number of incoming edges.
Definition: Instructions.h:2725
llvm::RF_NoModuleLevelChanges
@ RF_NoModuleLevelChanges
If this flag is set, the remapper knows that only local values within a function (such as an instruct...
Definition: ValueMapper.h:72
llvm::WinEHHandlerType::TypeDescriptor
GlobalVariable * TypeDescriptor
Definition: WinEHFuncInfo.h:68
llvm::erase_value
void erase_value(Container &C, ValueType V)
Wrapper function to remove a value from a container:
Definition: STLExtras.h:1740
llvm::InvokeInst
Invoke instruction.
Definition: Instructions.h:3749
Passes.h
llvm::Use::set
void set(Value *Val)
Definition: Value.h:864
llvm::CloneBasicBlock
BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr, DebugInfoFinder *DIFinder=nullptr)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
Definition: CloneFunction.cpp:43
llvm::cl::opt< bool >
llvm::ClrHandlerType::Filter
@ Filter
llvm::removeUnwindEdge
void removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU=nullptr)
Replace 'BB's terminator with one that does not have an unwind successor block.
Definition: Local.cpp:2408
llvm::WinEHTryBlockMapEntry
Definition: WinEHFuncInfo.h:72
llvm::CleanupPadInst
Definition: Instructions.h:4432
llvm::StoreInst
An instruction for storing to memory.
Definition: Instructions.h:304
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::WinEHFuncInfo
Definition: WinEHFuncInfo.h:90
llvm::colorEHFunclets
DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
Definition: EHPersonalities.cpp:81
llvm::CxxUnwindMapEntry::ToState
int ToState
Definition: WinEHFuncInfo.h:41
DisableCleanups
static cl::opt< bool > DisableCleanups("disable-cleanups", cl::Hidden, cl::desc("Do not remove implausible terminators or other similar cleanups"), cl::init(false))
llvm::CatchReturnInst
Definition: Instructions.h:4524
llvm::GlobalValue::getParent
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:578
getEHPadFromPredecessor
static const BasicBlock * getEHPadFromPredecessor(const BasicBlock *BB, Value *ParentPad)
Definition: WinEHPrepare.cpp:221
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
llvm::DenseMap
Definition: DenseMap.h:714
llvm::WinEHTryBlockMapEntry::HandlerArray
SmallVector< WinEHHandlerType, 1 > HandlerArray
Definition: WinEHFuncInfo.h:76
I
#define I(x, y, z)
Definition: MD5.cpp:59
Cloning.h
llvm::isScopedEHPersonality
bool isScopedEHPersonality(EHPersonality Pers)
Returns true if this personality uses scope-style EH IR instructions: catchswitch,...
Definition: EHPersonalities.h:80
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:441
llvm::make_early_inc_range
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:576
addSEHExcept
static int addSEHExcept(WinEHFuncInfo &FuncInfo, int ParentState, const Function *Filter, const BasicBlock *Handler)
Definition: WinEHPrepare.cpp:336
llvm::WinEHTryBlockMapEntry::TryHigh
int TryHigh
Definition: WinEHFuncInfo.h:74
llvm::WinEHFuncInfo::LabelToStateMap
DenseMap< MCSymbol *, std::pair< int, MCSymbol * > > LabelToStateMap
Definition: WinEHFuncInfo.h:94
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
DEBUG_TYPE
#define DEBUG_TYPE
Definition: WinEHPrepare.cpp:41
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
Triple.h
CFG.h
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::MergeBlockIntoPredecessor
bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr, bool PredecessorWithTwoSuccessors=false)
Attempts to merge a block into its predecessor, if possible.
Definition: BasicBlockUtils.cpp:173
llvm::TinyPtrVector::size
unsigned size() const
Definition: TinyPtrVector.h:172
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
DemoteCatchSwitchPHIOnlyOpt
static cl::opt< bool > DemoteCatchSwitchPHIOnlyOpt("demote-catchswitch-only", cl::Hidden, cl::desc("Demote catchswitch BBs only (for wasm EH)"), cl::init(false))
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
llvm::Value::replaceAllUsesWith
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:532
uint32_t
llvm::SEHUnwindMapEntry
Similar to CxxUnwindMapEntry, but supports SEH filters.
Definition: WinEHFuncInfo.h:46
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::createWinEHPass
FunctionPass * createWinEHPass(bool DemoteCatchSwitchPHIOnly=false)
createWinEHPass - Prepares personality functions used by MSVC on Windows, in addition to the Itanium ...
calculateStateNumbersForInvokes
static void calculateStateNumbersForInvokes(const Function *Fn, WinEHFuncInfo &FuncInfo)
Definition: WinEHPrepare.cpp:175
DisableDemotion
static cl::opt< bool > DisableDemotion("disable-demotion", cl::Hidden, cl::desc("Clone multicolor basic blocks but do not demote cross scopes"), cl::init(false))
SSAUpdater.h
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
llvm::ValueMap< const Value *, WeakTrackingVH >
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:175
llvm::EHPersonality
EHPersonality
Definition: EHPersonalities.h:22
llvm::BasicBlock::getTerminator
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.cpp:152
llvm::ClrHandlerType::Finally
@ Finally
llvm::Constant::stripPointerCasts
const Constant * stripPointerCasts() const
Definition: Constant.h:207
llvm::BasicBlock::front
const Instruction & front() const
Definition: BasicBlock.h:308
llvm::RF_IgnoreMissingLocals
@ RF_IgnoreMissingLocals
If this flag is set, the remapper ignores missing function-local entries (Argument,...
Definition: ValueMapper.h:90
llvm::WinEHFuncInfo::SEHUnwindMap
SmallVector< SEHUnwindMapEntry, 4 > SEHUnwindMap
Definition: WinEHFuncInfo.h:97
llvm::EHPersonality::Unknown
@ Unknown
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
llvm::WinEHTryBlockMapEntry::CatchHigh
int CatchHigh
Definition: WinEHFuncInfo.h:75
llvm::SplitEdge
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...
Definition: BasicBlockUtils.cpp:493
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::ConstantFoldTerminator
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:128
Verifier.h
llvm::ValueMapIterator
Definition: ValueMap.h:49
llvm::ClrHandlerType
ClrHandlerType
Definition: WinEHFuncInfo.h:79
llvm::ConstantTokenNone::get
static ConstantTokenNone * get(LLVMContext &Context)
Return the ConstantTokenNone.
Definition: Constants.cpp:1467
llvm::WinEHFuncInfo::EHPadStateMap
DenseMap< const Instruction *, int > EHPadStateMap
Definition: WinEHFuncInfo.h:91
llvm::CxxUnwindMapEntry
Definition: WinEHFuncInfo.h:40
llvm::WinEHTryBlockMapEntry::TryLow
int TryLow
Definition: WinEHFuncInfo.h:73
addTryBlockMapEntry
static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow, int TryHigh, int CatchHigh, ArrayRef< const CatchPadInst * > Handlers)
Definition: WinEHPrepare.cpp:141
llvm::ValueMap::find
iterator find(const KeyT &Val)
Definition: ValueMap.h:156
llvm::Instruction::isEHPad
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
Definition: Instruction.h:661
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:585
llvm::BasicBlock::insertInto
void insertInto(Function *Parent, BasicBlock *InsertBefore=nullptr)
Insert unlinked basic block into a function.
Definition: BasicBlock.cpp:61
llvm::Function::getPersonalityFn
Constant * getPersonalityFn() const
Get the personality function associated with this function.
Definition: Function.cpp:1823
addUnwindMapEntry
static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState, const BasicBlock *BB)
Definition: WinEHPrepare.cpp:132
WinEHFuncInfo.h
llvm::ClrHandlerType::Catch
@ Catch
llvm::CatchPadInst
Definition: Instructions.h:4473
addClrEHHandler
static int addClrEHHandler(WinEHFuncInfo &FuncInfo, int HandlerParentState, int TryParentState, ClrHandlerType HandlerType, uint32_t TypeToken, const BasicBlock *Handler)
Definition: WinEHPrepare.cpp:487
llvm::changeToUnreachable
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:2109
llvm::BasicBlock::getInstList
const InstListType & getInstList() const
Return the underlying instruction list container.
Definition: BasicBlock.h:363
llvm::TinyPtrVector::empty
bool empty() const
Definition: TinyPtrVector.h:163
llvm::Module::getTargetTriple
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
Definition: Module.h:257
llvm::Instruction::getParent
const BasicBlock * getParent() const
Definition: Instruction.h:94
llvm::PHINode::getIncomingBlock
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Definition: Instructions.h:2749
llvm::PHINode
Definition: Instructions.h:2633
llvm::ValueMap< const Value *, WeakTrackingVH >::value_type
std::pair< const Value *, WeakTrackingVH > value_type
Definition: ValueMap.h:100
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
llvm::Module::getDataLayout
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:401
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::WinEHHandlerType::Handler
MBBOrBasicBlock Handler
Definition: WinEHFuncInfo.h:69
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::AllocaInst
an instruction to allocate memory on the stack
Definition: Instructions.h:62
llvm::calculateSEHStateNumbers
void calculateSEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo)
Definition: WinEHPrepare.cpp:451
llvm::SSAUpdater::AddAvailableValue
void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value.
Definition: SSAUpdater.cpp:70
llvm::cl::desc
Definition: CommandLine.h:412
Mod
Module * Mod
Definition: PassBuilderBindings.cpp:54
llvm::BranchInst
Conditional or Unconditional Branch instruction.
Definition: Instructions.h:3068
raw_ostream.h
llvm::TinyPtrVector
TinyPtrVector - This class is specialized for cases where there are normally 0 or 1 element in a vect...
Definition: TinyPtrVector.h:30
llvm::SSAUpdater
Helper class for SSA formation on a set of values defined in multiple blocks.
Definition: SSAUpdater.h:38
BasicBlockUtils.h
llvm::calculateWinCXXEHStateNumbers
void calculateWinCXXEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo)
Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which describes the state number...
Definition: WinEHPrepare.cpp:469
InitializePasses.h
llvm::BasicBlock::isEHPad
bool isEHPad() const
Return true if this basic block is an exception handling block.
Definition: BasicBlock.h:465
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
Debug.h
llvm::Value::users
iterator_range< user_iterator > users()
Definition: Value.h:422
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44
llvm::SmallVectorImpl::emplace_back
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:908
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37
llvm::calculateClrEHStateNumbers
void calculateClrEHStateNumbers(const Function *Fn, WinEHFuncInfo &FuncInfo)
Definition: WinEHPrepare.cpp:500