diff options
author | Reid Kleckner <rnk@google.com> | 2015-09-16 22:14:46 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2015-09-16 22:14:46 +0000 |
commit | 813f1b65bc131b211ec5fef10ad47abc0488192d (patch) | |
tree | 50945af80e2c6413233a92517adee7ef46a14ba0 /llvm/lib | |
parent | e39bd407ba29cf8ba20ec4f02f6a84b17cee2cb3 (diff) | |
download | bcm5719-llvm-813f1b65bc131b211ec5fef10ad47abc0488192d.tar.gz bcm5719-llvm-813f1b65bc131b211ec5fef10ad47abc0488192d.zip |
[WinEH] Rip out the landingpad-based C++ EH state numbering code
It never really worked, and the new code is working better every day.
llvm-svn: 247860
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/WinException.cpp | 113 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/WinException.h | 3 | ||||
-rw-r--r-- | llvm/lib/CodeGen/PrologEpilogInserter.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/CodeGen/WinEHPrepare.cpp | 380 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 23 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86WinEHState.cpp | 17 |
6 files changed, 36 insertions, 506 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index 1b75051dd67..95947cb88c4 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -98,24 +98,6 @@ void WinException::beginFunction(const MachineFunction *MF) { return; } - // If this was an outlined handler, we need to define the label corresponding - // to the offset of the parent frame relative to the stack pointer after the - // prologue. - if (F != ParentF) { - WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(ParentF); - auto I = FuncInfo.CatchHandlerParentFrameObjOffset.find(F); - if (I != FuncInfo.CatchHandlerParentFrameObjOffset.end()) { - MCSymbol *HandlerTypeParentFrameOffset = - Asm->OutContext.getOrCreateParentFrameOffsetSymbol( - GlobalValue::getRealLinkageName(F->getName())); - - // Emit a symbol assignment. - Asm->OutStreamer->EmitAssignment( - HandlerTypeParentFrameOffset, - MCConstantExpr::create(I->second, Asm->OutContext)); - } - } - if (shouldEmitMoves || shouldEmitPersonality) Asm->OutStreamer->EmitWinCFIStartProc(Asm->CurrentFnSym); @@ -325,35 +307,21 @@ static MCSymbol *getMCSymbolForMBBOrGV(AsmPrinter *Asm, ValueOrMBB Handler) { void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { const Function *F = MF->getFunction(); - const Function *ParentF = MMI->getWinEHParent(F); auto &OS = *Asm->OutStreamer; - WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(ParentF); + WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F); - StringRef ParentLinkageName = - GlobalValue::getRealLinkageName(ParentF->getName()); + StringRef FuncLinkageName = GlobalValue::getRealLinkageName(F->getName()); MCSymbol *FuncInfoXData = nullptr; if (shouldEmitPersonality) { - FuncInfoXData = Asm->OutContext.getOrCreateSymbol( - Twine("$cppxdata$", ParentLinkageName)); + FuncInfoXData = + Asm->OutContext.getOrCreateSymbol(Twine("$cppxdata$", FuncLinkageName)); OS.EmitValue(create32bitRef(FuncInfoXData), 4); - extendIP2StateTable(MF, ParentF, FuncInfo); - - if (!MMI->hasEHFunclets()) { - // Defer emission until we've visited the parent function and all the - // catch handlers. Cleanups don't contribute to the ip2state table, so - // don't count them. - if (ParentF != F && !FuncInfo.CatchHandlerMaxState.count(F)) - return; - ++FuncInfo.NumIPToStateFuncsVisited; - if (FuncInfo.NumIPToStateFuncsVisited != - FuncInfo.CatchHandlerMaxState.size()) - return; - } + extendIP2StateTable(MF, FuncInfo); } else { - FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(ParentLinkageName); - emitEHRegistrationOffsetLabel(FuncInfo, ParentLinkageName); + FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(FuncLinkageName); + emitEHRegistrationOffsetLabel(FuncInfo, FuncLinkageName); } MCSymbol *UnwindMapXData = nullptr; @@ -361,13 +329,13 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { MCSymbol *IPToStateXData = nullptr; if (!FuncInfo.UnwindMap.empty()) UnwindMapXData = Asm->OutContext.getOrCreateSymbol( - Twine("$stateUnwindMap$", ParentLinkageName)); + Twine("$stateUnwindMap$", FuncLinkageName)); if (!FuncInfo.TryBlockMap.empty()) - TryBlockMapXData = Asm->OutContext.getOrCreateSymbol( - Twine("$tryMap$", ParentLinkageName)); + TryBlockMapXData = + Asm->OutContext.getOrCreateSymbol(Twine("$tryMap$", FuncLinkageName)); if (!FuncInfo.IPToStateList.empty()) - IPToStateXData = Asm->OutContext.getOrCreateSymbol( - Twine("$ip2state$", ParentLinkageName)); + IPToStateXData = + Asm->OutContext.getOrCreateSymbol(Twine("$ip2state$", FuncLinkageName)); // FuncInfo { // uint32_t MagicNumber @@ -423,29 +391,26 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { SmallVector<MCSymbol *, 1> HandlerMaps; for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) { WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I]; - MCSymbol *HandlerMapXData = nullptr; + MCSymbol *HandlerMapXData = nullptr; if (!TBME.HandlerArray.empty()) HandlerMapXData = Asm->OutContext.getOrCreateSymbol(Twine("$handlerMap$") .concat(Twine(I)) .concat("$") - .concat(ParentLinkageName)); - + .concat(FuncLinkageName)); HandlerMaps.push_back(HandlerMapXData); - int CatchHigh = TBME.CatchHigh; - if (CatchHigh == -1) { - for (WinEHHandlerType &HT : TBME.HandlerArray) - CatchHigh = - std::max(CatchHigh, FuncInfo.CatchHandlerMaxState[cast<Function>( - HT.Handler.get<const Value *>())]); - } + // TBMEs should form intervals. + assert(0 <= TBME.TryLow && "bad trymap interval"); + assert(TBME.TryLow <= TBME.TryHigh && "bad trymap interval"); + assert(TBME.TryHigh < TBME.CatchHigh && "bad trymap interval"); + assert(TBME.CatchHigh < int(FuncInfo.UnwindMap.size()) && + "bad trymap interval"); - assert(TBME.TryLow <= TBME.TryHigh); OS.EmitIntValue(TBME.TryLow, 4); // TryLow OS.EmitIntValue(TBME.TryHigh, 4); // TryHigh - OS.EmitIntValue(CatchHigh, 4); // CatchHigh + OS.EmitIntValue(TBME.CatchHigh, 4); // CatchHigh OS.EmitIntValue(TBME.HandlerArray.size(), 4); // NumCatches OS.EmitValue(create32bitRef(HandlerMapXData), 4); // HandlerArray } @@ -471,8 +436,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { if (HT.CatchObjRecoverIdx >= 0) { MCSymbol *FrameAllocOffset = Asm->OutContext.getOrCreateFrameAllocSymbol( - GlobalValue::getRealLinkageName(ParentF->getName()), - HT.CatchObjRecoverIdx); + FuncLinkageName, HT.CatchObjRecoverIdx); FrameAllocOffsetRef = MCSymbolRefExpr::create( FrameAllocOffset, MCSymbolRefExpr::VK_None, Asm->OutContext); } else if (HT.CatchObj.FrameOffset != INT_MAX) { @@ -497,21 +461,11 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { OS.EmitValue(create32bitRef(HandlerSym), 4); // Handler if (shouldEmitPersonality) { - if (FuncInfo.CatchHandlerParentFrameObjOffset.empty()) { - // With the new IR, this is always 16 + 8 + getMaxCallFrameSize(). - // Keep this in sync with X86FrameLowering::emitPrologue. - int ParentFrameOffset = - 16 + 8 + MF->getFrameInfo()->getMaxCallFrameSize(); - OS.EmitIntValue(ParentFrameOffset, 4); // ParentFrameOffset - } else { - MCSymbol *ParentFrameOffset = - Asm->OutContext.getOrCreateParentFrameOffsetSymbol( - GlobalValue::getRealLinkageName( - HT.Handler.get<const Value *>()->getName())); - const MCSymbolRefExpr *ParentFrameOffsetRef = - MCSymbolRefExpr::create(ParentFrameOffset, Asm->OutContext); - OS.EmitValue(ParentFrameOffsetRef, 4); // ParentFrameOffset - } + // With the new IR, this is always 16 + 8 + getMaxCallFrameSize(). + // Keep this in sync with X86FrameLowering::emitPrologue. + int ParentFrameOffset = + 16 + 8 + MF->getFrameInfo()->getMaxCallFrameSize(); + OS.EmitIntValue(ParentFrameOffset, 4); // ParentFrameOffset } } } @@ -531,10 +485,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { } void WinException::extendIP2StateTable(const MachineFunction *MF, - const Function *ParentF, WinEHFuncInfo &FuncInfo) { - const Function *F = MF->getFunction(); - // The Itanium LSDA table sorts similar landing pads together to simplify the // actions table, but we don't need that. SmallVector<const LandingPadInfo *, 64> LandingPads; @@ -560,14 +511,8 @@ void WinException::extendIP2StateTable(const MachineFunction *MF, // Include ip2state entries for the beginning of the main function and // for catch handler functions. - if (F == ParentF) { - FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel, -1)); - LastEHState = -1; - } else if (FuncInfo.HandlerBaseState.count(F)) { - FuncInfo.IPToStateList.push_back( - std::make_pair(LastLabel, FuncInfo.HandlerBaseState[F])); - LastEHState = FuncInfo.HandlerBaseState[F]; - } + FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel, -1)); + LastEHState = -1; for (const auto &MBB : *MF) { for (const auto &MI : MBB) { if (!MI.isEHLabel()) { diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.h b/llvm/lib/CodeGen/AsmPrinter/WinException.h index aa159f5cf6e..ac06db2a2fd 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.h +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.h @@ -47,8 +47,7 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer { /// tables. void emitExceptHandlerTable(const MachineFunction *MF); - void extendIP2StateTable(const MachineFunction *MF, const Function *ParentF, - WinEHFuncInfo &FuncInfo); + void extendIP2StateTable(const MachineFunction *MF, WinEHFuncInfo &FuncInfo); /// Emits the label used with llvm.x86.seh.recoverfp, which is used by /// outlined funclets. diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index 54f5553d3e1..585c7edc0f0 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -829,12 +829,6 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) { TFI.getFrameIndexReference(Fn, H.CatchObj.FrameIndex, UnusedReg); } } - } else if (MMI.hasWinEHFuncInfo(F)) { - WinEHFuncInfo &FuncInfo = MMI.getWinEHFuncInfo(Fn.getFunction()); - auto I = FuncInfo.CatchHandlerParentFrameObjIdx.find(F); - if (I != FuncInfo.CatchHandlerParentFrameObjIdx.end()) - FuncInfo.CatchHandlerParentFrameObjOffset[F] = - TFI.getFrameIndexReferenceFromSP(Fn, I->second, FrameReg); } // Store SPAdj at exit of a basic block. diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp index 3eed086a40d..06440e457a8 100644 --- a/llvm/lib/CodeGen/WinEHPrepare.cpp +++ b/llvm/lib/CodeGen/WinEHPrepare.cpp @@ -2576,33 +2576,6 @@ void llvm::parseEHActions( std::reverse(Actions.begin(), Actions.end()); } -namespace { -struct WinEHNumbering { - WinEHNumbering(WinEHFuncInfo &FuncInfo) : FuncInfo(FuncInfo), - CurrentBaseState(-1), NextState(0) {} - - WinEHFuncInfo &FuncInfo; - int CurrentBaseState; - int NextState; - - SmallVector<std::unique_ptr<ActionHandler>, 4> HandlerStack; - SmallPtrSet<const Function *, 4> VisitedHandlers; - - int currentEHNumber() const { - return HandlerStack.empty() ? CurrentBaseState : HandlerStack.back()->getEHState(); - } - - void createUnwindMapEntry(int ToState, ActionHandler *AH); - void createTryBlockMapEntry(int TryLow, int TryHigh, - ArrayRef<CatchHandler *> Handlers); - void processCallSite(MutableArrayRef<std::unique_ptr<ActionHandler>> Actions, - ImmutableCallSite CS); - void popUnmatchedActions(int FirstMismatch); - void calculateStateNumbers(const Function &F); - void findActionRootLPads(const Function &F); -}; -} - static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState, const Value *V) { WinEHUnwindMapEntry UME; @@ -2639,332 +2612,6 @@ static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow, FuncInfo.TryBlockMap.push_back(TBME); } -void WinEHNumbering::createUnwindMapEntry(int ToState, ActionHandler *AH) { - Value *V = nullptr; - if (auto *CH = dyn_cast_or_null<CleanupHandler>(AH)) - V = cast<Function>(CH->getHandlerBlockOrFunc()); - addUnwindMapEntry(FuncInfo, ToState, V); -} - -void WinEHNumbering::createTryBlockMapEntry(int TryLow, int TryHigh, - ArrayRef<CatchHandler *> Handlers) { - // See if we already have an entry for this set of handlers. - // This is using iterators rather than a range-based for loop because - // if we find the entry we're looking for we'll need the iterator to erase it. - int NumHandlers = Handlers.size(); - auto I = FuncInfo.TryBlockMap.begin(); - auto E = FuncInfo.TryBlockMap.end(); - for ( ; I != E; ++I) { - auto &Entry = *I; - if (Entry.HandlerArray.size() != (size_t)NumHandlers) - continue; - int N; - for (N = 0; N < NumHandlers; ++N) { - if (Entry.HandlerArray[N].Handler.get<const Value *>() != - Handlers[N]->getHandlerBlockOrFunc()) - break; // breaks out of inner loop - } - // If all the handlers match, this is what we were looking for. - if (N == NumHandlers) { - break; - } - } - - // If we found an existing entry for this set of handlers, extend the range - // but move the entry to the end of the map vector. The order of entries - // in the map is critical to the way that the runtime finds handlers. - // FIXME: Depending on what has happened with block ordering, this may - // incorrectly combine entries that should remain separate. - if (I != E) { - // Copy the existing entry. - WinEHTryBlockMapEntry Entry = *I; - Entry.TryLow = std::min(TryLow, Entry.TryLow); - Entry.TryHigh = std::max(TryHigh, Entry.TryHigh); - assert(Entry.TryLow <= Entry.TryHigh); - // Erase the old entry and add this one to the back. - FuncInfo.TryBlockMap.erase(I); - FuncInfo.TryBlockMap.push_back(Entry); - return; - } - - // If we didn't find an entry, create a new one. - WinEHTryBlockMapEntry TBME; - TBME.TryLow = TryLow; - TBME.TryHigh = TryHigh; - assert(TBME.TryLow <= TBME.TryHigh); - for (CatchHandler *CH : Handlers) { - WinEHHandlerType HT; - if (CH->getSelector()->isNullValue()) { - HT.Adjectives = 0x40; - HT.TypeDescriptor = nullptr; - } else { - auto *GV = cast<GlobalVariable>(CH->getSelector()->stripPointerCasts()); - // Selectors are always pointers to GlobalVariables with 'struct' type. - // The struct has two fields, adjectives and a type descriptor. - auto *CS = cast<ConstantStruct>(GV->getInitializer()); - HT.Adjectives = - cast<ConstantInt>(CS->getAggregateElement(0U))->getZExtValue(); - HT.TypeDescriptor = - cast<GlobalVariable>(CS->getAggregateElement(1)->stripPointerCasts()); - } - HT.Handler = cast<Function>(CH->getHandlerBlockOrFunc()); - HT.CatchObjRecoverIdx = CH->getExceptionVarIndex(); - HT.CatchObj.Alloca = nullptr; - TBME.HandlerArray.push_back(HT); - } - FuncInfo.TryBlockMap.push_back(TBME); -} - -static void print_name(const Value *V) { -#ifndef NDEBUG - if (!V) { - DEBUG(dbgs() << "null"); - return; - } - - if (const auto *F = dyn_cast<Function>(V)) - DEBUG(dbgs() << F->getName()); - else - DEBUG(V->dump()); -#endif -} - -void WinEHNumbering::processCallSite( - MutableArrayRef<std::unique_ptr<ActionHandler>> Actions, - ImmutableCallSite CS) { - DEBUG(dbgs() << "processCallSite (EH state = " << currentEHNumber() - << ") for: "); - print_name(CS ? CS.getCalledValue() : nullptr); - DEBUG(dbgs() << '\n'); - - DEBUG(dbgs() << "HandlerStack: \n"); - for (int I = 0, E = HandlerStack.size(); I < E; ++I) { - DEBUG(dbgs() << " "); - print_name(HandlerStack[I]->getHandlerBlockOrFunc()); - DEBUG(dbgs() << '\n'); - } - DEBUG(dbgs() << "Actions: \n"); - for (int I = 0, E = Actions.size(); I < E; ++I) { - DEBUG(dbgs() << " "); - print_name(Actions[I]->getHandlerBlockOrFunc()); - DEBUG(dbgs() << '\n'); - } - int FirstMismatch = 0; - for (int E = std::min(HandlerStack.size(), Actions.size()); FirstMismatch < E; - ++FirstMismatch) { - if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() != - Actions[FirstMismatch]->getHandlerBlockOrFunc()) - break; - } - - // Remove unmatched actions from the stack and process their EH states. - popUnmatchedActions(FirstMismatch); - - DEBUG(dbgs() << "Pushing actions for CallSite: "); - print_name(CS ? CS.getCalledValue() : nullptr); - DEBUG(dbgs() << '\n'); - - bool LastActionWasCatch = false; - const LandingPadInst *LastRootLPad = nullptr; - for (size_t I = FirstMismatch; I != Actions.size(); ++I) { - // We can reuse eh states when pushing two catches for the same invoke. - bool CurrActionIsCatch = isa<CatchHandler>(Actions[I].get()); - auto *Handler = cast<Function>(Actions[I]->getHandlerBlockOrFunc()); - // Various conditions can lead to a handler being popped from the - // stack and re-pushed later. That shouldn't create a new state. - // FIXME: Can code optimization lead to re-used handlers? - if (FuncInfo.HandlerEnclosedState.count(Handler)) { - // If we already assigned the state enclosed by this handler re-use it. - Actions[I]->setEHState(FuncInfo.HandlerEnclosedState[Handler]); - continue; - } - const LandingPadInst* RootLPad = FuncInfo.RootLPad[Handler]; - if (CurrActionIsCatch && LastActionWasCatch && RootLPad == LastRootLPad) { - DEBUG(dbgs() << "setEHState for handler to " << currentEHNumber() << "\n"); - Actions[I]->setEHState(currentEHNumber()); - } else { - DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber() << ", "); - print_name(Actions[I]->getHandlerBlockOrFunc()); - DEBUG(dbgs() << ") with EH state " << NextState << "\n"); - createUnwindMapEntry(currentEHNumber(), Actions[I].get()); - DEBUG(dbgs() << "setEHState for handler to " << NextState << "\n"); - Actions[I]->setEHState(NextState); - NextState++; - } - HandlerStack.push_back(std::move(Actions[I])); - LastActionWasCatch = CurrActionIsCatch; - LastRootLPad = RootLPad; - } - - // This is used to defer numbering states for a handler until after the - // last time it appears in an invoke action list. - if (CS.isInvoke()) { - for (int I = 0, E = HandlerStack.size(); I < E; ++I) { - auto *Handler = cast<Function>(HandlerStack[I]->getHandlerBlockOrFunc()); - if (FuncInfo.LastInvoke[Handler] != cast<InvokeInst>(CS.getInstruction())) - continue; - FuncInfo.LastInvokeVisited[Handler] = true; - DEBUG(dbgs() << "Last invoke of "); - print_name(Handler); - DEBUG(dbgs() << " has been visited.\n"); - } - } - - DEBUG(dbgs() << "In EHState " << currentEHNumber() << " for CallSite: "); - print_name(CS ? CS.getCalledValue() : nullptr); - DEBUG(dbgs() << '\n'); -} - -void WinEHNumbering::popUnmatchedActions(int FirstMismatch) { - // Don't recurse while we are looping over the handler stack. Instead, defer - // the numbering of the catch handlers until we are done popping. - SmallVector<CatchHandler *, 4> PoppedCatches; - for (int I = HandlerStack.size() - 1; I >= FirstMismatch; --I) { - std::unique_ptr<ActionHandler> Handler = HandlerStack.pop_back_val(); - if (isa<CatchHandler>(Handler.get())) - PoppedCatches.push_back(cast<CatchHandler>(Handler.release())); - } - - int TryHigh = NextState - 1; - int LastTryLowIdx = 0; - for (int I = 0, E = PoppedCatches.size(); I != E; ++I) { - CatchHandler *CH = PoppedCatches[I]; - DEBUG(dbgs() << "Popped handler with state " << CH->getEHState() << "\n"); - if (I + 1 == E || CH->getEHState() != PoppedCatches[I + 1]->getEHState()) { - int TryLow = CH->getEHState(); - auto Handlers = - makeArrayRef(&PoppedCatches[LastTryLowIdx], I - LastTryLowIdx + 1); - DEBUG(dbgs() << "createTryBlockMapEntry(" << TryLow << ", " << TryHigh); - for (size_t J = 0; J < Handlers.size(); ++J) { - DEBUG(dbgs() << ", "); - print_name(Handlers[J]->getHandlerBlockOrFunc()); - } - DEBUG(dbgs() << ")\n"); - createTryBlockMapEntry(TryLow, TryHigh, Handlers); - LastTryLowIdx = I + 1; - } - } - - for (CatchHandler *CH : PoppedCatches) { - if (auto *F = dyn_cast<Function>(CH->getHandlerBlockOrFunc())) { - if (FuncInfo.LastInvokeVisited[F]) { - DEBUG(dbgs() << "Assigning base state " << NextState << " to "); - print_name(F); - DEBUG(dbgs() << '\n'); - FuncInfo.HandlerBaseState[F] = NextState; - DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber() - << ", null)\n"); - createUnwindMapEntry(currentEHNumber(), nullptr); - ++NextState; - calculateStateNumbers(*F); - } - else { - DEBUG(dbgs() << "Deferring handling of "); - print_name(F); - DEBUG(dbgs() << " until last invoke visited.\n"); - } - } - delete CH; - } -} - -void WinEHNumbering::calculateStateNumbers(const Function &F) { - auto I = VisitedHandlers.insert(&F); - if (!I.second) - return; // We've already visited this handler, don't renumber it. - - int OldBaseState = CurrentBaseState; - if (FuncInfo.HandlerBaseState.count(&F)) { - CurrentBaseState = FuncInfo.HandlerBaseState[&F]; - } - - size_t SavedHandlerStackSize = HandlerStack.size(); - - DEBUG(dbgs() << "Calculating state numbers for: " << F.getName() << '\n'); - SmallVector<std::unique_ptr<ActionHandler>, 4> ActionList; - for (const BasicBlock &BB : F) { - for (const Instruction &I : BB) { - const auto *CI = dyn_cast<CallInst>(&I); - if (!CI || CI->doesNotThrow()) - continue; - processCallSite(None, CI); - } - const auto *II = dyn_cast<InvokeInst>(BB.getTerminator()); - if (!II) - continue; - const LandingPadInst *LPI = II->getLandingPadInst(); - auto *ActionsCall = dyn_cast<IntrinsicInst>(LPI->getNextNode()); - if (!ActionsCall) - continue; - parseEHActions(ActionsCall, ActionList); - if (ActionList.empty()) - continue; - processCallSite(ActionList, II); - ActionList.clear(); - FuncInfo.EHPadStateMap[LPI] = currentEHNumber(); - DEBUG(dbgs() << "Assigning state " << currentEHNumber() - << " to landing pad at " << LPI->getParent()->getName() - << '\n'); - } - - // Pop any actions that were pushed on the stack for this function. - popUnmatchedActions(SavedHandlerStackSize); - - DEBUG(dbgs() << "Assigning max state " << NextState - 1 - << " to " << F.getName() << '\n'); - FuncInfo.CatchHandlerMaxState[&F] = NextState - 1; - - CurrentBaseState = OldBaseState; -} - -// This function follows the same basic traversal as calculateStateNumbers -// but it is necessary to identify the root landing pad associated -// with each action before we start assigning state numbers. -void WinEHNumbering::findActionRootLPads(const Function &F) { - auto I = VisitedHandlers.insert(&F); - if (!I.second) - return; // We've already visited this handler, don't revisit it. - - SmallVector<std::unique_ptr<ActionHandler>, 4> ActionList; - for (const BasicBlock &BB : F) { - const auto *II = dyn_cast<InvokeInst>(BB.getTerminator()); - if (!II) - continue; - const LandingPadInst *LPI = II->getLandingPadInst(); - auto *ActionsCall = dyn_cast<IntrinsicInst>(LPI->getNextNode()); - if (!ActionsCall) - continue; - - assert(ActionsCall->getIntrinsicID() == Intrinsic::eh_actions); - parseEHActions(ActionsCall, ActionList); - if (ActionList.empty()) - continue; - for (int I = 0, E = ActionList.size(); I < E; ++I) { - if (auto *Handler - = dyn_cast<Function>(ActionList[I]->getHandlerBlockOrFunc())) { - FuncInfo.LastInvoke[Handler] = II; - // Don't replace the root landing pad if we previously saw this - // handler in a different function. - if (FuncInfo.RootLPad.count(Handler) && - FuncInfo.RootLPad[Handler]->getParent()->getParent() != &F) - continue; - DEBUG(dbgs() << "Setting root lpad for "); - print_name(Handler); - DEBUG(dbgs() << " to " << LPI->getParent()->getName() << '\n'); - FuncInfo.RootLPad[Handler] = LPI; - } - } - // Walk the actions again and look for nested handlers. This has to - // happen after all of the actions have been processed in the current - // function. - for (int I = 0, E = ActionList.size(); I < E; ++I) - if (auto *Handler - = dyn_cast<Function>(ActionList[I]->getHandlerBlockOrFunc())) - findActionRootLPads(*Handler); - ActionList.clear(); - } -} - static const CatchPadInst *getSingleCatchPadPredecessor(const BasicBlock *BB) { for (const BasicBlock *PredBlock : predecessors(BB)) if (auto *CPI = dyn_cast<CatchPadInst>(PredBlock->getFirstNonPHI())) @@ -3158,29 +2805,30 @@ static bool doesEHPadUnwindToCaller(const Instruction *EHPad) { return cast<CleanupEndPadInst>(User)->unwindsToCaller(); } -void llvm::calculateSEHStateNumbers(const Function *ParentFn, +void llvm::calculateSEHStateNumbers(const Function *Fn, WinEHFuncInfo &FuncInfo) { // Don't compute state numbers twice. if (!FuncInfo.SEHUnwindMap.empty()) return; - for (const BasicBlock &BB : *ParentFn) { + for (const BasicBlock &BB : *Fn) { if (!BB.isEHPad() || !doesEHPadUnwindToCaller(BB.getFirstNonPHI())) continue; calculateExplicitSEHStateNumbers(FuncInfo, BB, -1); } } -void llvm::calculateWinCXXEHStateNumbers(const Function *ParentFn, +void llvm::calculateWinCXXEHStateNumbers(const Function *Fn, WinEHFuncInfo &FuncInfo) { // Return if it's already been done. if (!FuncInfo.EHPadStateMap.empty()) return; - bool IsExplicit = false; - for (const BasicBlock &BB : *ParentFn) { + for (const BasicBlock &BB : *Fn) { if (!BB.isEHPad()) continue; + if (BB.isLandingPad()) + report_fatal_error("MSVC C++ EH cannot use landingpads"); const Instruction *FirstNonPHI = BB.getFirstNonPHI(); // Skip cleanupendpads; they are exits, not entries. if (isa<CleanupEndPadInst>(FirstNonPHI)) @@ -3188,23 +2836,7 @@ void llvm::calculateWinCXXEHStateNumbers(const Function *ParentFn, if (!doesEHPadUnwindToCaller(FirstNonPHI)) continue; calculateExplicitCXXStateNumbers(FuncInfo, BB, -1); - IsExplicit = true; } - - if (IsExplicit) - return; - - WinEHNumbering Num(FuncInfo); - Num.findActionRootLPads(*ParentFn); - // The VisitedHandlers list is used by both findActionRootLPads and - // calculateStateNumbers, but both functions need to visit all handlers. - Num.VisitedHandlers.clear(); - Num.calculateStateNumbers(*ParentFn); - // Pop everything on the handler stack. - // It may be necessary to call this more than once because a handler can - // be pushed on the stack as a result of clearing the stack. - while (!Num.HandlerStack.empty()) - Num.processCallSite(None, ImmutableCallSite()); } void WinEHPrepare::replaceTerminatePadWithCleanup(Function &F) { diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 00b88c68d5c..6f337984336 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -2656,7 +2656,6 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain, const Function *WinEHParent = nullptr; if (MMI.hasWinEHFuncInfo(Fn)) WinEHParent = MMI.getWinEHParent(Fn); - bool IsWinEHOutlined = WinEHParent && WinEHParent != Fn; bool IsWinEHParent = WinEHParent && WinEHParent == Fn; // Figure out if XMM registers are in use. @@ -2748,28 +2747,6 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain, if (!MemOps.empty()) Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps); - } else if (IsWin64 && IsWinEHOutlined) { - // Get to the caller-allocated home save location. Add 8 to account - // for the return address. - int HomeOffset = TFI.getOffsetOfLocalArea() + 8; - FuncInfo->setRegSaveFrameIndex(MFI->CreateFixedObject( - /*Size=*/1, /*SPOffset=*/HomeOffset + 8, /*Immutable=*/false)); - - MMI.getWinEHFuncInfo(Fn) - .CatchHandlerParentFrameObjIdx[const_cast<Function *>(Fn)] = - FuncInfo->getRegSaveFrameIndex(); - - // Store the second integer parameter (rdx) into rsp+16 relative to the - // stack pointer at the entry of the function. - SDValue RSFIN = DAG.getFrameIndex(FuncInfo->getRegSaveFrameIndex(), - getPointerTy(DAG.getDataLayout())); - unsigned GPR = MF.addLiveIn(X86::RDX, &X86::GR64RegClass); - SDValue Val = DAG.getCopyFromReg(Chain, dl, GPR, MVT::i64); - Chain = DAG.getStore( - Val.getValue(1), dl, Val, RSFIN, - MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), - FuncInfo->getRegSaveFrameIndex()), - /*isVolatile=*/true, /*isNonTemporal=*/false, /*Alignment=*/0); } if (isVarArg && MFI->hasMustTailInVarArgFunc()) { diff --git a/llvm/lib/Target/X86/X86WinEHState.cpp b/llvm/lib/Target/X86/X86WinEHState.cpp index d1206ec0ee0..d148be618ed 100644 --- a/llvm/lib/Target/X86/X86WinEHState.cpp +++ b/llvm/lib/Target/X86/X86WinEHState.cpp @@ -437,23 +437,6 @@ void WinEHStatePass::addCXXStateStores(Function &F, WinEHFuncInfo &FuncInfo) { // Set up RegNodeEscapeIndex int RegNodeEscapeIndex = escapeRegNode(F); FuncInfo.EHRegNodeEscapeIndex = RegNodeEscapeIndex; - - // Only insert stores in catch handlers. - Constant *FI8 = - ConstantExpr::getBitCast(&F, Type::getInt8PtrTy(TheModule->getContext())); - for (auto P : FuncInfo.HandlerBaseState) { - Function *Handler = const_cast<Function *>(P.first); - int BaseState = P.second; - IRBuilder<> Builder(&Handler->getEntryBlock(), - Handler->getEntryBlock().begin()); - // FIXME: Find and reuse such a call if present. - Value *ParentFP = Builder.CreateCall(FrameAddress, {Builder.getInt32(1)}); - Value *RecoveredRegNode = Builder.CreateCall( - FrameRecover, {FI8, ParentFP, Builder.getInt32(RegNodeEscapeIndex)}); - RecoveredRegNode = - Builder.CreateBitCast(RecoveredRegNode, RegNodeTy->getPointerTo(0)); - addStateStoresToFunclet(RecoveredRegNode, FuncInfo, *Handler, BaseState); - } } /// Escape RegNode so that we can access it from child handlers. Find the call |