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