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