[AsmPrinter][TLOF] ARM64 MachO support for replacing GOT equivalents
[oota-llvm.git] / lib / CodeGen / WinEHPrepare.cpp
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. It snifs the personality function to see which kind of
12 // preparation is necessary. If the personality function uses the Itanium LSDA,
13 // this pass delegates to the DWARF EH preparation pass.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #include "llvm/CodeGen/Passes.h"
18 #include "llvm/ADT/MapVector.h"
19 #include "llvm/ADT/TinyPtrVector.h"
20 #include "llvm/Analysis/LibCallSemantics.h"
21 #include "llvm/IR/Function.h"
22 #include "llvm/IR/IRBuilder.h"
23 #include "llvm/IR/Instructions.h"
24 #include "llvm/IR/IntrinsicInst.h"
25 #include "llvm/IR/Module.h"
26 #include "llvm/IR/PatternMatch.h"
27 #include "llvm/Pass.h"
28 #include "llvm/Transforms/Utils/Cloning.h"
29 #include "llvm/Transforms/Utils/Local.h"
30 #include <memory>
31
32 using namespace llvm;
33 using namespace llvm::PatternMatch;
34
35 #define DEBUG_TYPE "winehprepare"
36
37 namespace {
38
39 // This map is used to model frame variable usage during outlining, to
40 // construct a structure type to hold the frame variables in a frame
41 // allocation block, and to remap the frame variable allocas (including
42 // spill locations as needed) to GEPs that get the variable from the
43 // frame allocation structure.
44 typedef MapVector<Value *, TinyPtrVector<AllocaInst *>> FrameVarInfoMap;
45
46 class WinEHPrepare : public FunctionPass {
47   std::unique_ptr<FunctionPass> DwarfPrepare;
48
49   enum HandlerType { Catch, Cleanup };
50
51 public:
52   static char ID; // Pass identification, replacement for typeid.
53   WinEHPrepare(const TargetMachine *TM = nullptr)
54       : FunctionPass(ID), DwarfPrepare(createDwarfEHPass(TM)) {}
55
56   bool runOnFunction(Function &Fn) override;
57
58   bool doFinalization(Module &M) override;
59
60   void getAnalysisUsage(AnalysisUsage &AU) const override;
61
62   const char *getPassName() const override {
63     return "Windows exception handling preparation";
64   }
65
66 private:
67   bool prepareCPPEHHandlers(Function &F,
68                             SmallVectorImpl<LandingPadInst *> &LPads);
69   bool outlineHandler(HandlerType CatchOrCleanup, Function *SrcFn,
70                       Constant *SelectorType, LandingPadInst *LPad,
71                       FrameVarInfoMap &VarInfo);
72 };
73
74 class WinEHFrameVariableMaterializer : public ValueMaterializer {
75 public:
76   WinEHFrameVariableMaterializer(Function *OutlinedFn,
77                                  FrameVarInfoMap &FrameVarInfo);
78   ~WinEHFrameVariableMaterializer() {}
79
80   virtual Value *materializeValueFor(Value *V) override;
81
82 private:
83   FrameVarInfoMap &FrameVarInfo;
84   IRBuilder<> Builder;
85 };
86
87 class WinEHCloningDirectorBase : public CloningDirector {
88 public:
89   WinEHCloningDirectorBase(LandingPadInst *LPI, Function *HandlerFn,
90                            FrameVarInfoMap &VarInfo)
91       : LPI(LPI), Materializer(HandlerFn, VarInfo),
92         SelectorIDType(Type::getInt32Ty(LPI->getContext())),
93         Int8PtrType(Type::getInt8PtrTy(LPI->getContext())),
94         ExtractedEHPtr(nullptr), ExtractedSelector(nullptr),
95         EHPtrStoreAddr(nullptr), SelectorStoreAddr(nullptr) {}
96
97   CloningAction handleInstruction(ValueToValueMapTy &VMap,
98                                   const Instruction *Inst,
99                                   BasicBlock *NewBB) override;
100
101   virtual CloningAction handleBeginCatch(ValueToValueMapTy &VMap,
102                                          const Instruction *Inst,
103                                          BasicBlock *NewBB) = 0;
104   virtual CloningAction handleEndCatch(ValueToValueMapTy &VMap,
105                                        const Instruction *Inst,
106                                        BasicBlock *NewBB) = 0;
107   virtual CloningAction handleTypeIdFor(ValueToValueMapTy &VMap,
108                                         const Instruction *Inst,
109                                         BasicBlock *NewBB) = 0;
110   virtual CloningAction handleResume(ValueToValueMapTy &VMap,
111                                      const ResumeInst *Resume,
112                                      BasicBlock *NewBB) = 0;
113
114   ValueMaterializer *getValueMaterializer() override { return &Materializer; }
115
116 protected:
117   LandingPadInst *LPI;
118   WinEHFrameVariableMaterializer Materializer;
119   Type *SelectorIDType;
120   Type *Int8PtrType;
121
122   const Value *ExtractedEHPtr;
123   const Value *ExtractedSelector;
124   const Value *EHPtrStoreAddr;
125   const Value *SelectorStoreAddr;
126 };
127
128 class WinEHCatchDirector : public WinEHCloningDirectorBase {
129 public:
130   WinEHCatchDirector(LandingPadInst *LPI, Function *CatchFn, Value *Selector,
131                      FrameVarInfoMap &VarInfo)
132       : WinEHCloningDirectorBase(LPI, CatchFn, VarInfo),
133         CurrentSelector(Selector->stripPointerCasts()) {}
134
135   CloningAction handleBeginCatch(ValueToValueMapTy &VMap,
136                                  const Instruction *Inst,
137                                  BasicBlock *NewBB) override;
138   CloningAction handleEndCatch(ValueToValueMapTy &VMap, const Instruction *Inst,
139                                BasicBlock *NewBB) override;
140   CloningAction handleTypeIdFor(ValueToValueMapTy &VMap,
141                                 const Instruction *Inst,
142                                 BasicBlock *NewBB) override;
143   CloningAction handleResume(ValueToValueMapTy &VMap, const ResumeInst *Resume,
144                              BasicBlock *NewBB) override;
145
146 private:
147   Value *CurrentSelector;
148 };
149
150 class WinEHCleanupDirector : public WinEHCloningDirectorBase {
151 public:
152   WinEHCleanupDirector(LandingPadInst *LPI, Function *CleanupFn,
153                        FrameVarInfoMap &VarInfo)
154       : WinEHCloningDirectorBase(LPI, CleanupFn, VarInfo) {}
155
156   CloningAction handleBeginCatch(ValueToValueMapTy &VMap,
157                                  const Instruction *Inst,
158                                  BasicBlock *NewBB) override;
159   CloningAction handleEndCatch(ValueToValueMapTy &VMap, const Instruction *Inst,
160                                BasicBlock *NewBB) override;
161   CloningAction handleTypeIdFor(ValueToValueMapTy &VMap,
162                                 const Instruction *Inst,
163                                 BasicBlock *NewBB) override;
164   CloningAction handleResume(ValueToValueMapTy &VMap, const ResumeInst *Resume,
165                              BasicBlock *NewBB) override;
166 };
167
168 } // end anonymous namespace
169
170 char WinEHPrepare::ID = 0;
171 INITIALIZE_TM_PASS(WinEHPrepare, "winehprepare", "Prepare Windows exceptions",
172                    false, false)
173
174 FunctionPass *llvm::createWinEHPass(const TargetMachine *TM) {
175   return new WinEHPrepare(TM);
176 }
177
178 static bool isMSVCPersonality(EHPersonality Pers) {
179   return Pers == EHPersonality::MSVC_Win64SEH ||
180          Pers == EHPersonality::MSVC_CXX;
181 }
182
183 bool WinEHPrepare::runOnFunction(Function &Fn) {
184   SmallVector<LandingPadInst *, 4> LPads;
185   SmallVector<ResumeInst *, 4> Resumes;
186   for (BasicBlock &BB : Fn) {
187     if (auto *LP = BB.getLandingPadInst())
188       LPads.push_back(LP);
189     if (auto *Resume = dyn_cast<ResumeInst>(BB.getTerminator()))
190       Resumes.push_back(Resume);
191   }
192
193   // No need to prepare functions that lack landing pads.
194   if (LPads.empty())
195     return false;
196
197   // Classify the personality to see what kind of preparation we need.
198   EHPersonality Pers = classifyEHPersonality(LPads.back()->getPersonalityFn());
199
200   // Delegate through to the DWARF pass if this is unrecognized.
201   if (!isMSVCPersonality(Pers))
202     return DwarfPrepare->runOnFunction(Fn);
203
204   // FIXME: This only returns true if the C++ EH handlers were outlined.
205   //        When that code is complete, it should always return whatever
206   //        prepareCPPEHHandlers returns.
207   if (Pers == EHPersonality::MSVC_CXX && prepareCPPEHHandlers(Fn, LPads))
208     return true;
209
210   // FIXME: SEH Cleanups are unimplemented. Replace them with unreachable.
211   if (Resumes.empty())
212     return false;
213
214   for (ResumeInst *Resume : Resumes) {
215     IRBuilder<>(Resume).CreateUnreachable();
216     Resume->eraseFromParent();
217   }
218
219   return true;
220 }
221
222 bool WinEHPrepare::doFinalization(Module &M) {
223   return DwarfPrepare->doFinalization(M);
224 }
225
226 void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {
227   DwarfPrepare->getAnalysisUsage(AU);
228 }
229
230 bool WinEHPrepare::prepareCPPEHHandlers(
231     Function &F, SmallVectorImpl<LandingPadInst *> &LPads) {
232   // These containers are used to re-map frame variables that are used in
233   // outlined catch and cleanup handlers.  They will be populated as the
234   // handlers are outlined.
235   FrameVarInfoMap FrameVarInfo;
236
237   bool HandlersOutlined = false;
238
239   for (LandingPadInst *LPad : LPads) {
240     // Look for evidence that this landingpad has already been processed.
241     bool LPadHasActionList = false;
242     BasicBlock *LPadBB = LPad->getParent();
243     for (Instruction &Inst : LPadBB->getInstList()) {
244       // FIXME: Make this an intrinsic.
245       if (auto *Call = dyn_cast<CallInst>(&Inst))
246         if (Call->getCalledFunction()->getName() == "llvm.eh.actions") {
247           LPadHasActionList = true;
248           break;
249         }
250     }
251
252     // If we've already outlined the handlers for this landingpad,
253     // there's nothing more to do here.
254     if (LPadHasActionList)
255       continue;
256
257     for (unsigned Idx = 0, NumClauses = LPad->getNumClauses(); Idx < NumClauses;
258          ++Idx) {
259       if (LPad->isCatch(Idx)) {
260         // Create a new instance of the handler data structure in the
261         // HandlerData vector.
262         bool Outlined = outlineHandler(Catch, &F, LPad->getClause(Idx), LPad,
263                                        FrameVarInfo);
264         if (Outlined) {
265           HandlersOutlined = true;
266         }
267       } // End if (isCatch)
268     }   // End for each clause
269
270     // FIXME: This only handles the simple case where there is a 1:1
271     //        correspondence between landing pad and cleanup blocks.
272     //        It does not handle cases where there are catch blocks between
273     //        cleanup blocks or the case where a cleanup block is shared by
274     //        multiple landing pads.  Those cases will be supported later
275     //        when landing pad block analysis is added.
276     if (LPad->isCleanup()) {
277       bool Outlined =
278           outlineHandler(Cleanup, &F, nullptr, LPad, FrameVarInfo);
279       if (Outlined) {
280         HandlersOutlined = true;
281       }
282     }
283   } // End for each landingpad
284
285   // If nothing got outlined, there is no more processing to be done.
286   if (!HandlersOutlined)
287     return false;
288
289   // FIXME: We will replace the landingpad bodies with llvm.eh.actions
290   //        calls and indirect branches here and then delete blocks
291   //        which are no longer reachable.  That will get rid of the
292   //        handlers that we have outlined.  There is code below
293   //        that looks for allocas with no uses in the parent function.
294   //        That will only happen after the pruning is implemented.
295
296   Module *M = F.getParent();
297   LLVMContext &Context = M->getContext();
298   BasicBlock *Entry = &F.getEntryBlock();
299   IRBuilder<> Builder(F.getParent()->getContext());
300   Builder.SetInsertPoint(Entry->getFirstInsertionPt());
301
302   Function *FrameEscapeFn =
303       Intrinsic::getDeclaration(M, Intrinsic::frameescape);
304   Function *RecoverFrameFn =
305       Intrinsic::getDeclaration(M, Intrinsic::framerecover);
306   Type *Int8PtrType = Type::getInt8PtrTy(Context);
307   Type *Int32Type = Type::getInt32Ty(Context);
308
309   // Finally, replace all of the temporary allocas for frame variables used in
310   // the outlined handlers with calls to llvm.framerecover.
311   BasicBlock::iterator II = Entry->getFirstInsertionPt();
312   Instruction *AllocaInsertPt = II;
313   SmallVector<Value *, 8> AllocasToEscape;
314   for (auto &VarInfoEntry : FrameVarInfo) {
315     Value *ParentVal = VarInfoEntry.first;
316     TinyPtrVector<AllocaInst *> &Allocas = VarInfoEntry.second;
317
318     // If the mapped value isn't already an alloca, we need to spill it if it
319     // is a computed value or copy it if it is an argument.
320     AllocaInst *ParentAlloca = dyn_cast<AllocaInst>(ParentVal);
321     if (!ParentAlloca) {
322       if (auto *Arg = dyn_cast<Argument>(ParentVal)) {
323         // Lower this argument to a copy and then demote that to the stack.
324         // We can't just use the argument location because the handler needs
325         // it to be in the frame allocation block.
326         // Use 'select i8 true, %arg, undef' to simulate a 'no-op' instruction.
327         Value *TrueValue = ConstantInt::getTrue(Context);
328         Value *UndefValue = UndefValue::get(Arg->getType());
329         Instruction *SI =
330             SelectInst::Create(TrueValue, Arg, UndefValue,
331                                Arg->getName() + ".tmp", AllocaInsertPt);
332         Arg->replaceAllUsesWith(SI);
333         // Reset the select operand, because it was clobbered by the RAUW above.
334         SI->setOperand(1, Arg);
335         ParentAlloca = DemoteRegToStack(*SI, true, SI);
336       } else if (auto *PN = dyn_cast<PHINode>(ParentVal)) {
337         ParentAlloca = DemotePHIToStack(PN, AllocaInsertPt);
338       } else {
339         Instruction *ParentInst = cast<Instruction>(ParentVal);
340         ParentAlloca = DemoteRegToStack(*ParentInst, true, ParentInst);
341       }
342     }
343
344     // If the parent alloca is no longer used and only one of the handlers used
345     // it, erase the parent and leave the copy in the outlined handler.
346     if (ParentAlloca->getNumUses() == 0 && Allocas.size() == 1) {
347       ParentAlloca->eraseFromParent();
348       continue;
349     }
350
351     // Add this alloca to the list of things to escape.
352     AllocasToEscape.push_back(ParentAlloca);
353
354     // Next replace all outlined allocas that are mapped to it.
355     for (AllocaInst *TempAlloca : Allocas) {
356       Function *HandlerFn = TempAlloca->getParent()->getParent();
357       // FIXME: Sink this GEP into the blocks where it is used.
358       Builder.SetInsertPoint(TempAlloca);
359       Builder.SetCurrentDebugLocation(TempAlloca->getDebugLoc());
360       Value *RecoverArgs[] = {
361           Builder.CreateBitCast(&F, Int8PtrType, ""),
362           &(HandlerFn->getArgumentList().back()),
363           llvm::ConstantInt::get(Int32Type, AllocasToEscape.size() - 1)};
364       Value *RecoveredAlloca =
365           Builder.CreateCall(RecoverFrameFn, RecoverArgs);
366       // Add a pointer bitcast if the alloca wasn't an i8.
367       if (RecoveredAlloca->getType() != TempAlloca->getType()) {
368         RecoveredAlloca->setName(Twine(TempAlloca->getName()) + ".i8");
369         RecoveredAlloca =
370             Builder.CreateBitCast(RecoveredAlloca, TempAlloca->getType());
371       }
372       TempAlloca->replaceAllUsesWith(RecoveredAlloca);
373       TempAlloca->removeFromParent();
374       RecoveredAlloca->takeName(TempAlloca);
375       delete TempAlloca;
376     }
377   }   // End for each FrameVarInfo entry.
378
379   // Insert 'call void (...)* @llvm.frameescape(...)' at the end of the entry
380   // block.
381   Builder.SetInsertPoint(&F.getEntryBlock().back());
382   Builder.CreateCall(FrameEscapeFn, AllocasToEscape);
383
384   return HandlersOutlined;
385 }
386
387 bool WinEHPrepare::outlineHandler(HandlerType CatchOrCleanup, Function *SrcFn,
388                                   Constant *SelectorType, LandingPadInst *LPad,
389                                   FrameVarInfoMap &VarInfo) {
390   Module *M = SrcFn->getParent();
391   LLVMContext &Context = M->getContext();
392
393   // Create a new function to receive the handler contents.
394   Type *Int8PtrType = Type::getInt8PtrTy(Context);
395   std::vector<Type *> ArgTys;
396   ArgTys.push_back(Int8PtrType);
397   ArgTys.push_back(Int8PtrType);
398   Function *Handler;
399   if (CatchOrCleanup == Catch) {
400     FunctionType *FnType = FunctionType::get(Int8PtrType, ArgTys, false);
401     Handler = Function::Create(FnType, GlobalVariable::InternalLinkage,
402                                SrcFn->getName() + ".catch", M);
403   } else {
404     FunctionType *FnType =
405         FunctionType::get(Type::getVoidTy(Context), ArgTys, false);
406     Handler = Function::Create(FnType, GlobalVariable::InternalLinkage,
407                                SrcFn->getName() + ".cleanup", M);
408   }
409
410   // Generate a standard prolog to setup the frame recovery structure.
411   IRBuilder<> Builder(Context);
412   BasicBlock *Entry = BasicBlock::Create(Context, "entry");
413   Handler->getBasicBlockList().push_front(Entry);
414   Builder.SetInsertPoint(Entry);
415   Builder.SetCurrentDebugLocation(LPad->getDebugLoc());
416
417   std::unique_ptr<WinEHCloningDirectorBase> Director;
418
419   if (CatchOrCleanup == Catch) {
420     Director.reset(
421         new WinEHCatchDirector(LPad, Handler, SelectorType, VarInfo));
422   } else {
423     Director.reset(new WinEHCleanupDirector(LPad, Handler, VarInfo));
424   }
425
426   ValueToValueMapTy VMap;
427
428   // FIXME: Map other values referenced in the filter handler.
429
430   SmallVector<ReturnInst *, 8> Returns;
431   ClonedCodeInfo InlinedFunctionInfo;
432
433   BasicBlock::iterator II = LPad;
434
435   CloneAndPruneIntoFromInst(
436       Handler, SrcFn, ++II, VMap,
437       /*ModuleLevelChanges=*/false, Returns, "", &InlinedFunctionInfo,
438       &SrcFn->getParent()->getDataLayout(), Director.get());
439
440   // Move all the instructions in the first cloned block into our entry block.
441   BasicBlock *FirstClonedBB = std::next(Function::iterator(Entry));
442   Entry->getInstList().splice(Entry->end(), FirstClonedBB->getInstList());
443   FirstClonedBB->eraseFromParent();
444
445   return true;
446 }
447
448 CloningDirector::CloningAction WinEHCloningDirectorBase::handleInstruction(
449     ValueToValueMapTy &VMap, const Instruction *Inst, BasicBlock *NewBB) {
450   // Intercept instructions which extract values from the landing pad aggregate.
451   if (auto *Extract = dyn_cast<ExtractValueInst>(Inst)) {
452     if (Extract->getAggregateOperand() == LPI) {
453       assert(Extract->getNumIndices() == 1 &&
454              "Unexpected operation: extracting both landing pad values");
455       assert((*(Extract->idx_begin()) == 0 || *(Extract->idx_begin()) == 1) &&
456              "Unexpected operation: extracting an unknown landing pad element");
457
458       if (*(Extract->idx_begin()) == 0) {
459         // Element 0 doesn't directly corresponds to anything in the WinEH
460         // scheme.
461         // It will be stored to a memory location, then later loaded and finally
462         // the loaded value will be used as the argument to an
463         // llvm.eh.begincatch
464         // call.  We're tracking it here so that we can skip the store and load.
465         ExtractedEHPtr = Inst;
466       } else {
467         // Element 1 corresponds to the filter selector.  We'll map it to 1 for
468         // matching purposes, but it will also probably be stored to memory and
469         // reloaded, so we need to track the instuction so that we can map the
470         // loaded value too.
471         VMap[Inst] = ConstantInt::get(SelectorIDType, 1);
472         ExtractedSelector = Inst;
473       }
474
475       // Tell the caller not to clone this instruction.
476       return CloningDirector::SkipInstruction;
477     }
478     // Other extract value instructions just get cloned.
479     return CloningDirector::CloneInstruction;
480   }
481
482   if (auto *Store = dyn_cast<StoreInst>(Inst)) {
483     // Look for and suppress stores of the extracted landingpad values.
484     const Value *StoredValue = Store->getValueOperand();
485     if (StoredValue == ExtractedEHPtr) {
486       EHPtrStoreAddr = Store->getPointerOperand();
487       return CloningDirector::SkipInstruction;
488     }
489     if (StoredValue == ExtractedSelector) {
490       SelectorStoreAddr = Store->getPointerOperand();
491       return CloningDirector::SkipInstruction;
492     }
493
494     // Any other store just gets cloned.
495     return CloningDirector::CloneInstruction;
496   }
497
498   if (auto *Load = dyn_cast<LoadInst>(Inst)) {
499     // Look for loads of (previously suppressed) landingpad values.
500     // The EHPtr load can be ignored (it should only be used as
501     // an argument to llvm.eh.begincatch), but the selector value
502     // needs to be mapped to a constant value of 1 to be used to
503     // simplify the branching to always flow to the current handler.
504     const Value *LoadAddr = Load->getPointerOperand();
505     if (LoadAddr == EHPtrStoreAddr) {
506       VMap[Inst] = UndefValue::get(Int8PtrType);
507       return CloningDirector::SkipInstruction;
508     }
509     if (LoadAddr == SelectorStoreAddr) {
510       VMap[Inst] = ConstantInt::get(SelectorIDType, 1);
511       return CloningDirector::SkipInstruction;
512     }
513
514     // Any other loads just get cloned.
515     return CloningDirector::CloneInstruction;
516   }
517
518   if (auto *Resume = dyn_cast<ResumeInst>(Inst))
519     return handleResume(VMap, Resume, NewBB);
520
521   if (match(Inst, m_Intrinsic<Intrinsic::eh_begincatch>()))
522     return handleBeginCatch(VMap, Inst, NewBB);
523   if (match(Inst, m_Intrinsic<Intrinsic::eh_endcatch>()))
524     return handleEndCatch(VMap, Inst, NewBB);
525   if (match(Inst, m_Intrinsic<Intrinsic::eh_typeid_for>()))
526     return handleTypeIdFor(VMap, Inst, NewBB);
527
528   // Continue with the default cloning behavior.
529   return CloningDirector::CloneInstruction;
530 }
531
532 CloningDirector::CloningAction WinEHCatchDirector::handleBeginCatch(
533     ValueToValueMapTy &VMap, const Instruction *Inst, BasicBlock *NewBB) {
534   // The argument to the call is some form of the first element of the
535   // landingpad aggregate value, but that doesn't matter.  It isn't used
536   // here.
537   // The second argument is an outparameter where the exception object will be
538   // stored. Typically the exception object is a scalar, but it can be an
539   // aggregate when catching by value.
540   // FIXME: Leave something behind to indicate where the exception object lives
541   // for this handler. Should it be part of llvm.eh.actions?
542   return CloningDirector::SkipInstruction;
543 }
544
545 CloningDirector::CloningAction
546 WinEHCatchDirector::handleEndCatch(ValueToValueMapTy &VMap,
547                                    const Instruction *Inst, BasicBlock *NewBB) {
548   auto *IntrinCall = dyn_cast<IntrinsicInst>(Inst);
549   // It might be interesting to track whether or not we are inside a catch
550   // function, but that might make the algorithm more brittle than it needs
551   // to be.
552
553   // The end catch call can occur in one of two places: either in a
554   // landingpad
555   // block that is part of the catch handlers exception mechanism, or at the
556   // end of the catch block.  If it occurs in a landing pad, we must skip it
557   // and continue so that the landing pad gets cloned.
558   // FIXME: This case isn't fully supported yet and shouldn't turn up in any
559   //        of the test cases until it is.
560   if (IntrinCall->getParent()->isLandingPad())
561     return CloningDirector::SkipInstruction;
562
563   // If an end catch occurs anywhere else the next instruction should be an
564   // unconditional branch instruction that we want to replace with a return
565   // to the the address of the branch target.
566   const BasicBlock *EndCatchBB = IntrinCall->getParent();
567   const TerminatorInst *Terminator = EndCatchBB->getTerminator();
568   const BranchInst *Branch = dyn_cast<BranchInst>(Terminator);
569   assert(Branch && Branch->isUnconditional());
570   assert(std::next(BasicBlock::const_iterator(IntrinCall)) ==
571          BasicBlock::const_iterator(Branch));
572
573   ReturnInst::Create(NewBB->getContext(),
574                      BlockAddress::get(Branch->getSuccessor(0)), NewBB);
575
576   // We just added a terminator to the cloned block.
577   // Tell the caller to stop processing the current basic block so that
578   // the branch instruction will be skipped.
579   return CloningDirector::StopCloningBB;
580 }
581
582 CloningDirector::CloningAction WinEHCatchDirector::handleTypeIdFor(
583     ValueToValueMapTy &VMap, const Instruction *Inst, BasicBlock *NewBB) {
584   auto *IntrinCall = dyn_cast<IntrinsicInst>(Inst);
585   Value *Selector = IntrinCall->getArgOperand(0)->stripPointerCasts();
586   // This causes a replacement that will collapse the landing pad CFG based
587   // on the filter function we intend to match.
588   if (Selector == CurrentSelector)
589     VMap[Inst] = ConstantInt::get(SelectorIDType, 1);
590   else
591     VMap[Inst] = ConstantInt::get(SelectorIDType, 0);
592   // Tell the caller not to clone this instruction.
593   return CloningDirector::SkipInstruction;
594 }
595
596 CloningDirector::CloningAction
597 WinEHCatchDirector::handleResume(ValueToValueMapTy &VMap,
598                                  const ResumeInst *Resume, BasicBlock *NewBB) {
599   // Resume instructions shouldn't be reachable from catch handlers.
600   // We still need to handle it, but it will be pruned.
601   BasicBlock::InstListType &InstList = NewBB->getInstList();
602   InstList.push_back(new UnreachableInst(NewBB->getContext()));
603   return CloningDirector::StopCloningBB;
604 }
605
606 CloningDirector::CloningAction WinEHCleanupDirector::handleBeginCatch(
607     ValueToValueMapTy &VMap, const Instruction *Inst, BasicBlock *NewBB) {
608   // Catch blocks within cleanup handlers will always be unreachable.
609   // We'll insert an unreachable instruction now, but it will be pruned
610   // before the cloning process is complete.
611   BasicBlock::InstListType &InstList = NewBB->getInstList();
612   InstList.push_back(new UnreachableInst(NewBB->getContext()));
613   return CloningDirector::StopCloningBB;
614 }
615
616 CloningDirector::CloningAction WinEHCleanupDirector::handleEndCatch(
617     ValueToValueMapTy &VMap, const Instruction *Inst, BasicBlock *NewBB) {
618   // Catch blocks within cleanup handlers will always be unreachable.
619   // We'll insert an unreachable instruction now, but it will be pruned
620   // before the cloning process is complete.
621   BasicBlock::InstListType &InstList = NewBB->getInstList();
622   InstList.push_back(new UnreachableInst(NewBB->getContext()));
623   return CloningDirector::StopCloningBB;
624 }
625
626 CloningDirector::CloningAction WinEHCleanupDirector::handleTypeIdFor(
627     ValueToValueMapTy &VMap, const Instruction *Inst, BasicBlock *NewBB) {
628   // This causes a replacement that will collapse the landing pad CFG
629   // to just the cleanup code.
630   VMap[Inst] = ConstantInt::get(SelectorIDType, 0);
631   // Tell the caller not to clone this instruction.
632   return CloningDirector::SkipInstruction;
633 }
634
635 CloningDirector::CloningAction WinEHCleanupDirector::handleResume(
636     ValueToValueMapTy &VMap, const ResumeInst *Resume, BasicBlock *NewBB) {
637   ReturnInst::Create(NewBB->getContext(), nullptr, NewBB);
638
639   // We just added a terminator to the cloned block.
640   // Tell the caller to stop processing the current basic block so that
641   // the branch instruction will be skipped.
642   return CloningDirector::StopCloningBB;
643 }
644
645 WinEHFrameVariableMaterializer::WinEHFrameVariableMaterializer(
646     Function *OutlinedFn, FrameVarInfoMap &FrameVarInfo)
647     : FrameVarInfo(FrameVarInfo), Builder(OutlinedFn->getContext()) {
648   Builder.SetInsertPoint(&OutlinedFn->getEntryBlock());
649   // FIXME: Do something with the FrameVarMapped so that it is shared across the
650   // function.
651 }
652
653 Value *WinEHFrameVariableMaterializer::materializeValueFor(Value *V) {
654   // If we're asked to materialize a value that is an instruction, we
655   // temporarily create an alloca in the outlined function and add this
656   // to the FrameVarInfo map.  When all the outlining is complete, we'll
657   // collect these into a structure, spilling non-alloca values in the
658   // parent frame as necessary, and replace these temporary allocas with
659   // GEPs referencing the frame allocation block.
660
661   // If the value is an alloca, the mapping is direct.
662   if (auto *AV = dyn_cast<AllocaInst>(V)) {
663     AllocaInst *NewAlloca = dyn_cast<AllocaInst>(AV->clone());
664     Builder.Insert(NewAlloca, AV->getName());
665     FrameVarInfo[AV].push_back(NewAlloca);
666     return NewAlloca;
667   }
668
669   // For other types of instructions or arguments, we need an alloca based on
670   // the value's type and a load of the alloca.  The alloca will be replaced
671   // by a GEP, but the load will stay.  In the parent function, the value will
672   // be spilled to a location in the frame allocation block.
673   if (isa<Instruction>(V) || isa<Argument>(V)) {
674     AllocaInst *NewAlloca =
675         Builder.CreateAlloca(V->getType(), nullptr, "eh.temp.alloca");
676     FrameVarInfo[V].push_back(NewAlloca);
677     LoadInst *NewLoad = Builder.CreateLoad(NewAlloca, V->getName() + ".reload");
678     return NewLoad;
679   }
680
681   // Don't materialize other values.
682   return nullptr;
683 }