diff options
Diffstat (limited to 'llvm/lib/CodeGen/WinEHPrepare.cpp')
-rw-r--r-- | llvm/lib/CodeGen/WinEHPrepare.cpp | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp index f4e810d8173..848e8032e70 100644 --- a/llvm/lib/CodeGen/WinEHPrepare.cpp +++ b/llvm/lib/CodeGen/WinEHPrepare.cpp @@ -175,7 +175,11 @@ public: : Materializer(HandlerFn, VarInfo), SelectorIDType(Type::getInt32Ty(HandlerFn->getContext())), Int8PtrType(Type::getInt8PtrTy(HandlerFn->getContext())), - LPadMap(LPadMap) {} + LPadMap(LPadMap) { + auto AI = HandlerFn->getArgumentList().begin(); + ++AI; + EstablisherFrame = AI; + } CloningAction handleInstruction(ValueToValueMapTy &VMap, const Instruction *Inst, @@ -210,6 +214,9 @@ protected: Type *SelectorIDType; Type *Int8PtrType; LandingPadMap &LPadMap; + + /// The value representing the parent frame pointer. + Value *EstablisherFrame; }; class WinEHCatchDirector : public WinEHCloningDirectorBase { @@ -520,12 +527,24 @@ bool WinEHPrepare::prepareExceptionHandlers( Intrinsic::getDeclaration(M, Intrinsic::frameescape); Function *RecoverFrameFn = Intrinsic::getDeclaration(M, Intrinsic::framerecover); + SmallVector<Value *, 8> AllocasToEscape; + + // Scan the entry block for an existing call to llvm.frameescape. We need to + // keep escaping those objects. + for (Instruction &I : F.front()) { + auto *II = dyn_cast<IntrinsicInst>(&I); + if (II && II->getIntrinsicID() == Intrinsic::frameescape) { + auto Args = II->arg_operands(); + AllocasToEscape.append(Args.begin(), Args.end()); + II->eraseFromParent(); + break; + } + } // Finally, replace all of the temporary allocas for frame variables used in // the outlined handlers with calls to llvm.framerecover. BasicBlock::iterator II = Entry->getFirstInsertionPt(); Instruction *AllocaInsertPt = II; - SmallVector<Value *, 8> AllocasToEscape; for (auto &VarInfoEntry : FrameVarInfo) { Value *ParentVal = VarInfoEntry.first; TinyPtrVector<AllocaInst *> &Allocas = VarInfoEntry.second; @@ -1051,6 +1070,11 @@ void LandingPadMap::remapEHValues(ValueToValueMapTy &VMap, Value *EHPtrValue, VMap[Extract] = SelectorValue; } +static bool isFrameAddressCall(const Value *V) { + return match(const_cast<Value *>(V), + m_Intrinsic<Intrinsic::frameaddress>(m_SpecificInt(0))); +} + CloningDirector::CloningAction WinEHCloningDirectorBase::handleInstruction( ValueToValueMapTy &VMap, const Instruction *Inst, BasicBlock *NewBB) { // If this is one of the boilerplate landing pad instructions, skip it. @@ -1083,6 +1107,13 @@ CloningDirector::CloningAction WinEHCloningDirectorBase::handleInstruction( if (match(Inst, m_Intrinsic<Intrinsic::eh_typeid_for>())) return handleTypeIdFor(VMap, Inst, NewBB); + // When outlining llvm.frameaddress(i32 0), remap that to the second argument, + // which is the FP of the parent. + if (isFrameAddressCall(Inst)) { + VMap[Inst] = EstablisherFrame; + return CloningDirector::SkipInstruction; + } + // Continue with the default cloning behavior. return CloningDirector::CloneInstruction; } @@ -1584,10 +1615,6 @@ static void createCleanupHandler(LandingPadActions &Actions, << Action->getStartBlock()->getName() << "\n"); } -static bool isFrameAddressCall(Value *V) { - return match(V, m_Intrinsic<Intrinsic::frameaddress>(m_SpecificInt(0))); -} - static CallSite matchOutlinedFinallyCall(BasicBlock *BB, Instruction *MaybeCall) { // Look for finally blocks that Clang has already outlined for us. |