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