1 //===-- WinEHPrepare - Prepare exception handling for code generation ---===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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.
15 //===----------------------------------------------------------------------===//
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"
33 using namespace llvm::PatternMatch;
35 #define DEBUG_TYPE "winehprepare"
39 struct HandlerAllocas {
40 TinyPtrVector<AllocaInst *> Allocas;
41 int ParentFrameAllocationIndex;
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;
51 class WinEHPrepare : public FunctionPass {
52 std::unique_ptr<FunctionPass> DwarfPrepare;
54 enum HandlerType { Catch, Cleanup };
57 static char ID; // Pass identification, replacement for typeid.
58 WinEHPrepare(const TargetMachine *TM = nullptr)
59 : FunctionPass(ID), DwarfPrepare(createDwarfEHPass(TM)) {}
61 bool runOnFunction(Function &Fn) override;
63 bool doFinalization(Module &M) override;
65 void getAnalysisUsage(AnalysisUsage &AU) const override;
67 const char *getPassName() const override {
68 return "Windows exception handling preparation";
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);
79 class WinEHFrameVariableMaterializer : public ValueMaterializer {
81 WinEHFrameVariableMaterializer(Function *OutlinedFn,
82 FrameVarInfoMap &FrameVarInfo);
83 ~WinEHFrameVariableMaterializer() {}
85 virtual Value *materializeValueFor(Value *V) override;
88 FrameVarInfoMap &FrameVarInfo;
92 class WinEHCloningDirectorBase : public CloningDirector {
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())) {}
100 CloningAction handleInstruction(ValueToValueMapTy &VMap,
101 const Instruction *Inst,
102 BasicBlock *NewBB) override;
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;
117 ValueMaterializer *getValueMaterializer() override { return &Materializer; }
121 WinEHFrameVariableMaterializer Materializer;
122 Type *SelectorIDType;
125 const Value *ExtractedEHPtr;
126 const Value *ExtractedSelector;
127 const Value *EHPtrStoreAddr;
128 const Value *SelectorStoreAddr;
131 class WinEHCatchDirector : public WinEHCloningDirectorBase {
133 WinEHCatchDirector(LandingPadInst *LPI, Function *CatchFn, Value *Selector,
134 FrameVarInfoMap &VarInfo)
135 : WinEHCloningDirectorBase(LPI, CatchFn, VarInfo),
136 CurrentSelector(Selector->stripPointerCasts()) {}
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;
150 Value *CurrentSelector;
153 class WinEHCleanupDirector : public WinEHCloningDirectorBase {
155 WinEHCleanupDirector(LandingPadInst *LPI, Function *CleanupFn,
156 FrameVarInfoMap &VarInfo)
157 : WinEHCloningDirectorBase(LPI, CleanupFn, VarInfo) {}
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;
171 } // end anonymous namespace
173 char WinEHPrepare::ID = 0;
174 INITIALIZE_TM_PASS(WinEHPrepare, "winehprepare", "Prepare Windows exceptions",
177 FunctionPass *llvm::createWinEHPass(const TargetMachine *TM) {
178 return new WinEHPrepare(TM);
181 static bool isMSVCPersonality(EHPersonality Pers) {
182 return Pers == EHPersonality::MSVC_Win64SEH ||
183 Pers == EHPersonality::MSVC_CXX;
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())
192 if (auto *Resume = dyn_cast<ResumeInst>(BB.getTerminator()))
193 Resumes.push_back(Resume);
196 // No need to prepare functions that lack landing pads.
200 // Classify the personality to see what kind of preparation we need.
201 EHPersonality Pers = classifyEHPersonality(LPads.back()->getPersonalityFn());
203 // Delegate through to the DWARF pass if this is unrecognized.
204 if (!isMSVCPersonality(Pers))
205 return DwarfPrepare->runOnFunction(Fn);
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))
213 // FIXME: SEH Cleanups are unimplemented. Replace them with unreachable.
217 for (ResumeInst *Resume : Resumes) {
218 IRBuilder<>(Resume).CreateUnreachable();
219 Resume->eraseFromParent();
225 bool WinEHPrepare::doFinalization(Module &M) {
226 return DwarfPrepare->doFinalization(M);
229 void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {
230 DwarfPrepare->getAnalysisUsage(AU);
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;
241 bool HandlersOutlined = false;
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;
256 // If we've already outlined the handlers for this landingpad,
257 // there's nothing more to do here.
258 if (LPadHasActionList)
261 for (unsigned Idx = 0, NumClauses = LPad->getNumClauses(); Idx < NumClauses;
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);
270 HandlersOutlined = true;
271 // These values must be resolved after all handlers have been
274 HandlerAllocs.push_back(EHAlloc);
276 } // End if (isCatch)
277 } // End for each clause
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;
288 outlineHandler(Cleanup, &F, nullptr, LPad, EHAlloc, FrameVarInfo);
290 HandlersOutlined = true;
291 // This value must be resolved after all handlers have been outlined.
293 HandlerAllocs.push_back(EHAlloc);
296 } // End for each landingpad
298 // If nothing got outlined, there is no more processing to be done.
299 if (!HandlersOutlined)
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.
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
314 // Start the index at two since we always have the above fields at 0 and 1.
317 // FIXME: Sort the FrameVarInfo vector by the ParentAlloca size and alignment
318 // and add padding as necessary to provide the proper alignment.
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
330 for (auto &VarInfoEntry : FrameVarInfo) {
331 Value *ParentVal = VarInfoEntry.first;
332 HandlerAllocas &AllocaInfo = VarInfoEntry.second;
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
338 if (ParentAlloca->getNumUses() != 0 || AllocaInfo.Allocas.size() > 1) {
339 Type *VarTy = ParentAlloca->getAllocatedType();
340 StructTys.push_back(VarTy);
341 AllocaInfo.ParentFrameAllocationIndex = Idx++;
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;
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
353 Type *VarTy = ParentVal->getType();
354 StructTys.push_back(VarTy);
355 AllocaInfo.ParentFrameAllocationIndex = Idx++;
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());
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");
378 Value *FrameEHData = Builder.CreateBitCast(
379 FrameAlloc, EHDataStructTy->getPointerTo(), "eh.data");
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;
389 Builder.SetInsertPoint(cast<Instruction>(II));
390 Value *EHData = Builder.CreateBitCast(
391 EHAlloc, EHDataStructTy->getPointerTo(), "eh.data");
392 EHDataMap[EHAlloc->getParent()->getParent()] = EHData;
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;
401 Instruction *AllocaInsertPt = II;
402 for (auto &VarInfoEntry : FrameVarInfo) {
403 Value *ParentVal = VarInfoEntry.first;
404 HandlerAllocas &AllocaInfo = VarInfoEntry.second;
405 int Idx = AllocaInfo.ParentFrameAllocationIndex;
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);
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());
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);
428 Instruction *ParentInst = cast<Instruction>(ParentVal);
429 ParentAlloca = DemoteRegToStack(*ParentInst, true, ParentInst);
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.
437 ParentAlloca->eraseFromParent();
439 // Otherwise, we replace the parent alloca and all outlined allocas
440 // which map to it with GEP instructions.
442 // First replace the original alloca.
443 Builder.SetInsertPoint(ParentAlloca);
444 Builder.SetCurrentDebugLocation(ParentAlloca->getDebugLoc());
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);
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);
466 } // end else of if (Idx == -1)
467 } // End for each FrameVarInfo entry.
469 return HandlersOutlined;
472 bool WinEHPrepare::outlineHandler(HandlerType CatchOrCleanup, Function *SrcFn,
473 Constant *SelectorType, LandingPadInst *LPad,
475 FrameVarInfoMap &VarInfo) {
476 Module *M = SrcFn->getParent();
477 LLVMContext &Context = M->getContext();
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);
485 if (CatchOrCleanup == Catch) {
486 FunctionType *FnType = FunctionType::get(Int8PtrType, ArgTys, false);
487 Handler = Function::Create(FnType, GlobalVariable::InternalLinkage,
488 SrcFn->getName() + ".catch", M);
490 FunctionType *FnType =
491 FunctionType::get(Type::getVoidTy(Context), ArgTys, false);
492 Handler = Function::Create(FnType, GlobalVariable::InternalLinkage,
493 SrcFn->getName() + ".cleanup", M);
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());
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.
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");
520 std::unique_ptr<WinEHCloningDirectorBase> Director;
522 if (CatchOrCleanup == Catch) {
524 new WinEHCatchDirector(LPad, Handler, SelectorType, VarInfo));
526 Director.reset(new WinEHCleanupDirector(LPad, Handler, VarInfo));
529 ValueToValueMapTy VMap;
531 // FIXME: Map other values referenced in the filter handler.
533 SmallVector<ReturnInst *, 8> Returns;
534 ClonedCodeInfo InlinedFunctionInfo;
536 BasicBlock::iterator II = LPad;
538 CloneAndPruneIntoFromInst(
539 Handler, SrcFn, ++II, VMap,
540 /*ModuleLevelChanges=*/false, Returns, "", &InlinedFunctionInfo,
541 &SrcFn->getParent()->getDataLayout(), Director.get());
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();
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");
561 if (*(Extract->idx_begin()) == 0) {
562 // Element 0 doesn't directly corresponds to anything in the WinEH
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;
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
574 VMap[Inst] = ConstantInt::get(SelectorIDType, 1);
575 ExtractedSelector = Inst;
578 // Tell the caller not to clone this instruction.
579 return CloningDirector::SkipInstruction;
581 // Other extract value instructions just get cloned.
582 return CloningDirector::CloneInstruction;
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;
592 if (StoredValue == ExtractedSelector) {
593 SelectorStoreAddr = Store->getPointerOperand();
594 return CloningDirector::SkipInstruction;
597 // Any other store just gets cloned.
598 return CloningDirector::CloneInstruction;
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;
612 if (LoadAddr == SelectorStoreAddr) {
613 VMap[Inst] = ConstantInt::get(SelectorIDType, 1);
614 return CloningDirector::SkipInstruction;
617 // Any other loads just get cloned.
618 return CloningDirector::CloneInstruction;
621 if (auto *Resume = dyn_cast<ResumeInst>(Inst))
622 return handleResume(VMap, Resume, NewBB);
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);
631 // Continue with the default cloning behavior.
632 return CloningDirector::CloneInstruction;
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
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;
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
656 // The end catch call can occur in one of two places: either in a
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;
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));
676 ReturnInst::Create(NewBB->getContext(),
677 BlockAddress::get(Branch->getSuccessor(0)), NewBB);
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;
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);
694 VMap[Inst] = ConstantInt::get(SelectorIDType, 0);
695 // Tell the caller not to clone this instruction.
696 return CloningDirector::SkipInstruction;
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;
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;
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;
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;
738 CloningDirector::CloningAction WinEHCleanupDirector::handleResume(
739 ValueToValueMapTy &VMap, const ResumeInst *Resume, BasicBlock *NewBB) {
740 ReturnInst::Create(NewBB->getContext(), nullptr, NewBB);
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;
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
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.
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);
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");
784 // Don't materialize other values.