summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2015-09-16 22:14:46 +0000
committerReid Kleckner <rnk@google.com>2015-09-16 22:14:46 +0000
commit813f1b65bc131b211ec5fef10ad47abc0488192d (patch)
tree50945af80e2c6413233a92517adee7ef46a14ba0 /llvm/lib
parente39bd407ba29cf8ba20ec4f02f6a84b17cee2cb3 (diff)
downloadbcm5719-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.cpp113
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/WinException.h3
-rw-r--r--llvm/lib/CodeGen/PrologEpilogInserter.cpp6
-rw-r--r--llvm/lib/CodeGen/WinEHPrepare.cpp380
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp23
-rw-r--r--llvm/lib/Target/X86/X86WinEHState.cpp17
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
OpenPOWER on IntegriCloud