summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp5
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/WinException.cpp58
-rw-r--r--llvm/lib/CodeGen/BranchFolding.cpp12
-rw-r--r--llvm/lib/CodeGen/LiveIntervalAnalysis.cpp2
-rw-r--r--llvm/lib/CodeGen/LiveVariables.cpp2
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIParser.cpp2
-rw-r--r--llvm/lib/CodeGen/MIRPrinter.cpp2
-rw-r--r--llvm/lib/CodeGen/MachineBasicBlock.cpp17
-rw-r--r--llvm/lib/CodeGen/MachineBlockPlacement.cpp2
-rw-r--r--llvm/lib/CodeGen/MachineLICM.cpp4
-rw-r--r--llvm/lib/CodeGen/MachineModuleInfo.cpp2
-rw-r--r--llvm/lib/CodeGen/MachineSink.cpp2
-rw-r--r--llvm/lib/CodeGen/MachineVerifier.cpp6
-rw-r--r--llvm/lib/CodeGen/PHIElimination.cpp2
-rw-r--r--llvm/lib/CodeGen/PHIEliminationUtils.cpp2
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp20
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp52
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp4
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp11
-rw-r--r--llvm/lib/CodeGen/WinEHPrepare.cpp4
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.cpp8
-rw-r--r--llvm/lib/Target/Hexagon/BitTracker.cpp2
-rw-r--r--llvm/lib/Target/Mips/MipsAsmPrinter.cpp2
-rw-r--r--llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp2
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp22
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.h3
-rw-r--r--llvm/lib/Target/X86/X86InstrCompiler.td9
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.td2
-rw-r--r--llvm/lib/Target/X86/X86MCInstLower.cpp6
-rw-r--r--llvm/lib/Target/X86/X86WinEHState.cpp10
30 files changed, 193 insertions, 84 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index e69febc6ad6..fdba2a92818 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -2485,7 +2485,8 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const {
}
// Print the main label for the block.
- if (MBB.pred_empty() || isBlockOnlyReachableByFallthrough(&MBB)) {
+ if (MBB.pred_empty() ||
+ (isBlockOnlyReachableByFallthrough(&MBB) && !MBB.isEHFuncletEntry())) {
if (isVerbose()) {
// NOTE: Want this comment at start of line, don't emit with AddComment.
OutStreamer->emitRawComment(" BB#" + Twine(MBB.getNumber()) + ":", false);
@@ -2523,7 +2524,7 @@ bool AsmPrinter::
isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
// If this is a landing pad, it isn't a fall through. If it has no preds,
// then nothing falls through to it.
- if (MBB->isLandingPad() || MBB->pred_empty())
+ if (MBB->isEHPad() || MBB->pred_empty())
return false;
// If there isn't exactly one predecessor, it can't be a fall through.
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
index 4151101e22b..547dc4cbdc3 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -62,6 +62,7 @@ void WinException::beginFunction(const MachineFunction *MF) {
// If any landing pads survive, we need an EH table.
bool hasLandingPads = !MMI->getLandingPads().empty();
+ bool hasEHFunclets = MMI->hasEHFunclets();
const Function *F = MF->getFunction();
const Function *ParentF = MMI->getWinEHParent(F);
@@ -78,19 +79,21 @@ void WinException::beginFunction(const MachineFunction *MF) {
F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
F->needsUnwindTableEntry();
- shouldEmitPersonality = forceEmitPersonality || (hasLandingPads &&
- PerEncoding != dwarf::DW_EH_PE_omit && Per);
+ shouldEmitPersonality =
+ forceEmitPersonality || ((hasLandingPads || hasEHFunclets) &&
+ PerEncoding != dwarf::DW_EH_PE_omit && Per);
unsigned LSDAEncoding = TLOF.getLSDAEncoding();
shouldEmitLSDA = shouldEmitPersonality &&
LSDAEncoding != dwarf::DW_EH_PE_omit;
- // If we're not using CFI, we don't want the CFI or the personality. If
- // WinEHPrepare outlined something, we should emit the LSDA.
+ // If we're not using CFI, we don't want the CFI or the personality, but we
+ // might want EH tables if we had EH pads.
+ // FIXME: If WinEHPrepare outlined something, we should emit the LSDA. Remove
+ // this once WinEHPrepare stops doing that.
if (!Asm->MAI->usesWindowsCFI()) {
- bool HasOutlinedChildren =
- F->hasFnAttribute("wineh-parent") && F == ParentF;
- shouldEmitLSDA = HasOutlinedChildren;
+ shouldEmitLSDA =
+ hasEHFunclets || (F->hasFnAttribute("wineh-parent") && F == ParentF);
shouldEmitPersonality = false;
return;
}
@@ -185,7 +188,10 @@ const MCExpr *WinException::create32bitRef(const MCSymbol *Value) {
const MCExpr *WinException::create32bitRef(const Value *V) {
if (!V)
return MCConstantExpr::create(0, Asm->OutContext);
- return create32bitRef(Asm->getSymbol(cast<GlobalValue>(V)));
+ // FIXME: Delete the GlobalValue case once the new IR is fully functional.
+ if (const auto *GV = dyn_cast<GlobalValue>(V))
+ return create32bitRef(Asm->getSymbol(GV));
+ return create32bitRef(MMI->getAddrLabelSymbol(cast<BasicBlock>(V)));
}
/// Emit the language-specific data that __C_specific_handler expects. This
@@ -320,14 +326,17 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
extendIP2StateTable(MF, ParentF, FuncInfo);
- // 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;
+ 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;
+ }
} else {
FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(ParentLinkageName);
emitEHRegistrationOffsetLabel(FuncInfo, ParentLinkageName);
@@ -410,11 +419,13 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
HandlerMaps.push_back(HandlerMapXData);
- int CatchHigh = -1;
- for (WinEHHandlerType &HT : TBME.HandlerArray)
- CatchHigh =
- std::max(CatchHigh,
- FuncInfo.CatchHandlerMaxState[cast<Function>(HT.Handler)]);
+ int CatchHigh = TBME.CatchHigh;
+ if (CatchHigh == -1) {
+ for (WinEHHandlerType &HT : TBME.HandlerArray)
+ CatchHigh = std::max(
+ CatchHigh,
+ FuncInfo.CatchHandlerMaxState[cast<Function>(HT.Handler)]);
+ }
assert(TBME.TryLow <= TBME.TryHigh);
OS.EmitIntValue(TBME.TryLow, 4); // TryLow
@@ -456,7 +467,10 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
OS.EmitIntValue(HT.Adjectives, 4); // Adjectives
OS.EmitValue(create32bitRef(HT.TypeDescriptor), 4); // Type
OS.EmitValue(FrameAllocOffsetRef, 4); // CatchObjOffset
- OS.EmitValue(create32bitRef(HT.Handler), 4); // Handler
+ if (HT.HandlerMBB) // Handler
+ OS.EmitValue(create32bitRef(HT.HandlerMBB->getSymbol()), 4);
+ else
+ OS.EmitValue(create32bitRef(HT.Handler), 4);
if (shouldEmitPersonality) {
MCSymbol *ParentFrameOffset =
diff --git a/llvm/lib/CodeGen/BranchFolding.cpp b/llvm/lib/CodeGen/BranchFolding.cpp
index 260ab537053..9102a3da123 100644
--- a/llvm/lib/CodeGen/BranchFolding.cpp
+++ b/llvm/lib/CodeGen/BranchFolding.cpp
@@ -1001,7 +1001,7 @@ bool BranchFolder::TailMergeBlocks(MachineFunction &MF) {
// Failing case: the only way IBB can be reached from PBB is via
// exception handling. Happens for landing pads. Would be nice to have
// a bit in the edge so we didn't have to do all this.
- if (IBB->isLandingPad()) {
+ if (IBB->isEHPad()) {
MachineFunction::iterator IP = PBB; IP++;
MachineBasicBlock *PredNextBB = nullptr;
if (IP != MF.end())
@@ -1178,13 +1178,13 @@ ReoptimizeBlock:
// explicitly. Landing pads should not do this since the landing-pad table
// points to this block. Blocks with their addresses taken shouldn't be
// optimized away.
- if (IsEmptyBlock(MBB) && !MBB->isLandingPad() && !MBB->hasAddressTaken()) {
+ if (IsEmptyBlock(MBB) && !MBB->isEHPad() && !MBB->hasAddressTaken()) {
// Dead block? Leave for cleanup later.
if (MBB->pred_empty()) return MadeChange;
if (FallThrough == MF.end()) {
// TODO: Simplify preds to not branch here if possible!
- } else if (FallThrough->isLandingPad()) {
+ } else if (FallThrough->isEHPad()) {
// Don't rewrite to a landing pad fallthough. That could lead to the case
// where a BB jumps to more than one landing pad.
// TODO: Is it ever worth rewriting predecessors which don't already
@@ -1241,7 +1241,7 @@ ReoptimizeBlock:
// AnalyzeBranch.
if (PriorCond.empty() && !PriorTBB && MBB->pred_size() == 1 &&
PrevBB.succ_size() == 1 &&
- !MBB->hasAddressTaken() && !MBB->isLandingPad()) {
+ !MBB->hasAddressTaken() && !MBB->isEHPad()) {
DEBUG(dbgs() << "\nMerging into block: " << PrevBB
<< "From MBB: " << *MBB);
// Remove redundant DBG_VALUEs first.
@@ -1472,7 +1472,7 @@ ReoptimizeBlock:
// see if it has a fall-through into its successor.
bool CurFallsThru = MBB->canFallThrough();
- if (!MBB->isLandingPad()) {
+ if (!MBB->isEHPad()) {
// Check all the predecessors of this block. If one of them has no fall
// throughs, move this block right after it.
for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
@@ -1523,7 +1523,7 @@ ReoptimizeBlock:
// fallthrough to happen.
if (SuccBB != MBB && &*SuccPrev != MBB &&
!SuccPrev->canFallThrough() && !CurUnAnalyzable &&
- !SuccBB->isLandingPad()) {
+ !SuccBB->isEHPad()) {
MBB->moveBefore(SuccBB);
MadeChange = true;
goto ReoptimizeBlock;
diff --git a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
index eaa4b5b238d..75e3a701d34 100644
--- a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -299,7 +299,7 @@ void LiveIntervals::computeLiveInRegUnits() {
const MachineBasicBlock *MBB = MFI;
// We only care about ABI blocks: Entry + landing pads.
- if ((MFI != MF->begin() && !MBB->isLandingPad()) || MBB->livein_empty())
+ if ((MFI != MF->begin() && !MBB->isEHPad()) || MBB->livein_empty())
continue;
// Create phi-defs at Begin for all live-in registers.
diff --git a/llvm/lib/CodeGen/LiveVariables.cpp b/llvm/lib/CodeGen/LiveVariables.cpp
index 1f5f3047e63..6e843b0d6f9 100644
--- a/llvm/lib/CodeGen/LiveVariables.cpp
+++ b/llvm/lib/CodeGen/LiveVariables.cpp
@@ -598,7 +598,7 @@ void LiveVariables::runOnBlock(MachineBasicBlock *MBB, const unsigned NumRegs) {
for (MachineBasicBlock::const_succ_iterator SI = MBB->succ_begin(),
SE = MBB->succ_end(); SI != SE; ++SI) {
MachineBasicBlock *SuccMBB = *SI;
- if (SuccMBB->isLandingPad())
+ if (SuccMBB->isEHPad())
continue;
for (unsigned LI : SuccMBB->liveins()) {
if (!TRI->isInAllocatableClass(LI))
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 83ba5a2c90b..c09f279a25f 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -368,7 +368,7 @@ bool MIParser::parseBasicBlockDefinition(
MBB->setAlignment(Alignment);
if (HasAddressTaken)
MBB->setHasAddressTaken();
- MBB->setIsLandingPad(IsLandingPad);
+ MBB->setIsEHPad(IsLandingPad);
return false;
}
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index 297e1f813a0..bfcc56f680e 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -439,7 +439,7 @@ void MIPrinter::print(const MachineBasicBlock &MBB) {
OS << "address-taken";
HasAttributes = true;
}
- if (MBB.isLandingPad()) {
+ if (MBB.isEHPad()) {
OS << (HasAttributes ? ", " : " (");
OS << "landing-pad";
HasAttributes = true;
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index c30b95a6b2d..b2bbe09176d 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -39,8 +39,7 @@ using namespace llvm;
#define DEBUG_TYPE "codegen"
MachineBasicBlock::MachineBasicBlock(MachineFunction &mf, const BasicBlock *bb)
- : BB(bb), Number(-1), xParent(&mf), Alignment(0), IsLandingPad(false),
- AddressTaken(false), CachedMCSymbol(nullptr) {
+ : BB(bb), Number(-1), xParent(&mf) {
Insts.Parent = this;
}
@@ -203,7 +202,7 @@ const MachineBasicBlock *MachineBasicBlock::getLandingPadSuccessor() const {
if (succ_size() > 2)
return nullptr;
for (const_succ_iterator I = succ_begin(), E = succ_end(); I != E; ++I)
- if ((*I)->isLandingPad())
+ if ((*I)->isEHPad())
return *I;
return nullptr;
}
@@ -266,7 +265,7 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
LBB->printAsOperand(OS, /*PrintType=*/false, MST);
Comma = ", ";
}
- if (isLandingPad()) { OS << Comma << "EH LANDING PAD"; Comma = ", "; }
+ if (isEHPad()) { OS << Comma << "EH LANDING PAD"; Comma = ", "; }
if (hasAddressTaken()) { OS << Comma << "ADDRESS TAKEN"; Comma = ", "; }
if (Alignment)
OS << Comma << "Align " << Alignment << " (" << (1u << Alignment)
@@ -338,7 +337,7 @@ MachineBasicBlock::addLiveIn(MCPhysReg PhysReg, const TargetRegisterClass *RC) {
assert(getParent() && "MBB must be inserted in function");
assert(TargetRegisterInfo::isPhysicalRegister(PhysReg) && "Expected physreg");
assert(RC && "Register class is required");
- assert((isLandingPad() || this == &getParent()->front()) &&
+ assert((isEHPad() || this == &getParent()->front()) &&
"Only the entry block and landing pads can have physreg live ins");
bool LiveIn = isLiveIn(PhysReg);
@@ -396,7 +395,7 @@ void MachineBasicBlock::updateTerminator() {
// its layout successor, insert a branch. First we have to locate the
// only non-landing-pad successor, as that is the fallthrough block.
for (succ_iterator SI = succ_begin(), SE = succ_end(); SI != SE; ++SI) {
- if ((*SI)->isLandingPad())
+ if ((*SI)->isEHPad())
continue;
assert(!TBB && "Found more than one non-landing-pad successor!");
TBB = *SI;
@@ -432,7 +431,7 @@ void MachineBasicBlock::updateTerminator() {
// as the fallthrough successor.
MachineBasicBlock *FallthroughBB = nullptr;
for (succ_iterator SI = succ_begin(), SE = succ_end(); SI != SE; ++SI) {
- if ((*SI)->isLandingPad() || *SI == TBB)
+ if ((*SI)->isEHPad() || *SI == TBB)
continue;
assert(!FallthroughBB && "Found more than one fallthrough successor.");
FallthroughBB = *SI;
@@ -662,7 +661,7 @@ MachineBasicBlock *
MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
// Splitting the critical edge to a landing pad block is non-trivial. Don't do
// it in this generic function.
- if (Succ->isLandingPad())
+ if (Succ->isEHPad())
return nullptr;
MachineFunction *MF = getParent();
@@ -1046,7 +1045,7 @@ bool MachineBasicBlock::CorrectExtraCFGEdges(MachineBasicBlock *DestA,
while (SI != succ_end()) {
const MachineBasicBlock *MBB = *SI;
if (!SeenMBBs.insert(MBB).second ||
- (MBB != DestA && MBB != DestB && !MBB->isLandingPad())) {
+ (MBB != DestA && MBB != DestB && !MBB->isEHPad())) {
// This is a superfluous edge, remove it.
SI = removeSuccessor(SI);
Changed = true;
diff --git a/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
index b77c803f77f..e515a89e782 100644
--- a/llvm/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
@@ -678,7 +678,7 @@ MachineBlockPlacement::findBestLoopExit(MachineFunction &F, MachineLoop &L,
uint32_t WeightScale = 0;
uint32_t SumWeight = MBPI->getSumForBlock(MBB, WeightScale);
for (MachineBasicBlock *Succ : MBB->successors()) {
- if (Succ->isLandingPad())
+ if (Succ->isEHPad())
continue;
if (Succ == MBB)
continue;
diff --git a/llvm/lib/CodeGen/MachineLICM.cpp b/llvm/lib/CodeGen/MachineLICM.cpp
index ebef22e462d..45501cbb01b 100644
--- a/llvm/lib/CodeGen/MachineLICM.cpp
+++ b/llvm/lib/CodeGen/MachineLICM.cpp
@@ -529,7 +529,7 @@ void MachineLICM::HoistRegionPostRA() {
// If the header of the loop containing this basic block is a landing pad,
// then don't try to hoist instructions out of this loop.
const MachineLoop *ML = MLI->getLoopFor(BB);
- if (ML && ML->getHeader()->isLandingPad()) continue;
+ if (ML && ML->getHeader()->isEHPad()) continue;
// Conservatively treat live-in's as an external def.
// FIXME: That means a reload that're reused in successor block(s) will not
@@ -725,7 +725,7 @@ void MachineLICM::HoistOutOfLoop(MachineDomTreeNode *HeaderN) {
// If the header of the loop containing this basic block is a landing pad,
// then don't try to hoist instructions out of this loop.
const MachineLoop *ML = MLI->getLoopFor(BB);
- if (ML && ML->getHeader()->isLandingPad())
+ if (ML && ML->getHeader()->isEHPad())
continue;
// If this subregion is not in the top level loop at all, exit.
diff --git a/llvm/lib/CodeGen/MachineModuleInfo.cpp b/llvm/lib/CodeGen/MachineModuleInfo.cpp
index 4d5bd83a032..6f9721a0d35 100644
--- a/llvm/lib/CodeGen/MachineModuleInfo.cpp
+++ b/llvm/lib/CodeGen/MachineModuleInfo.cpp
@@ -209,6 +209,7 @@ bool MachineModuleInfo::doInitialization(Module &M) {
CurCallSite = 0;
CallsEHReturn = false;
CallsUnwindInit = false;
+ HasEHFunclets = false;
DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false;
// Always emit some info, by default "no personality" info.
Personalities.push_back(nullptr);
@@ -249,6 +250,7 @@ void MachineModuleInfo::EndFunction() {
FilterEnds.clear();
CallsEHReturn = false;
CallsUnwindInit = false;
+ HasEHFunclets = false;
VariableDbgInfos.clear();
}
diff --git a/llvm/lib/CodeGen/MachineSink.cpp b/llvm/lib/CodeGen/MachineSink.cpp
index 1b9be50068a..f6b5f08036d 100644
--- a/llvm/lib/CodeGen/MachineSink.cpp
+++ b/llvm/lib/CodeGen/MachineSink.cpp
@@ -667,7 +667,7 @@ MachineBasicBlock *MachineSinking::FindSuccToSinkTo(MachineInstr *MI,
// It's not safe to sink instructions to EH landing pad. Control flow into
// landing pad is implicitly defined.
- if (SuccToSinkTo && SuccToSinkTo->isLandingPad())
+ if (SuccToSinkTo && SuccToSinkTo->isEHPad())
return nullptr;
return SuccToSinkTo;
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 078e5769f0a..6eb9d342ba2 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -508,7 +508,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
// If this block has allocatable physical registers live-in, check that
// it is an entry block or landing pad.
for (unsigned LI : MBB->liveins()) {
- if (isAllocatable(LI) && !MBB->isLandingPad() &&
+ if (isAllocatable(LI) && !MBB->isEHPad() &&
MBB != MBB->getParent()->begin()) {
report("MBB has allocable live-in, but isn't entry or landing-pad.", MBB);
}
@@ -519,7 +519,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
SmallPtrSet<MachineBasicBlock*, 4> LandingPadSuccs;
for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(),
E = MBB->succ_end(); I != E; ++I) {
- if ((*I)->isLandingPad())
+ if ((*I)->isEHPad())
LandingPadSuccs.insert(*I);
if (!FunctionBlocks.count(*I))
report("MBB has successor that isn't part of the function.", MBB);
@@ -1606,7 +1606,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
assert(LiveInts->isLiveInToMBB(LR, MFI));
// We don't know how to track physregs into a landing pad.
if (!TargetRegisterInfo::isVirtualRegister(Reg) &&
- MFI->isLandingPad()) {
+ MFI->isEHPad()) {
if (&*MFI == EndMBB)
break;
++MFI;
diff --git a/llvm/lib/CodeGen/PHIElimination.cpp b/llvm/lib/CodeGen/PHIElimination.cpp
index d3433018004..2c937926d0a 100644
--- a/llvm/lib/CodeGen/PHIElimination.cpp
+++ b/llvm/lib/CodeGen/PHIElimination.cpp
@@ -548,7 +548,7 @@ void PHIElimination::analyzePHINodes(const MachineFunction& MF) {
bool PHIElimination::SplitPHIEdges(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineLoopInfo *MLI) {
- if (MBB.empty() || !MBB.front().isPHI() || MBB.isLandingPad())
+ if (MBB.empty() || !MBB.front().isPHI() || MBB.isEHPad())
return false; // Quick exit for basic blocks without PHIs.
const MachineLoop *CurLoop = MLI ? MLI->getLoopFor(&MBB) : nullptr;
diff --git a/llvm/lib/CodeGen/PHIEliminationUtils.cpp b/llvm/lib/CodeGen/PHIEliminationUtils.cpp
index 99bbad1cc28..4cabc3a8c1f 100644
--- a/llvm/lib/CodeGen/PHIEliminationUtils.cpp
+++ b/llvm/lib/CodeGen/PHIEliminationUtils.cpp
@@ -28,7 +28,7 @@ llvm::findPHICopyInsertPoint(MachineBasicBlock* MBB, MachineBasicBlock* SuccMBB,
// Usually, we just want to insert the copy before the first terminator
// instruction. However, for the edge going to a landing pad, we must insert
// the copy before the call/invoke instruction.
- if (!SuccMBB->isLandingPad())
+ if (!SuccMBB->isEHPad())
return MBB->getFirstTerminator();
// Discover any defs/uses in this basic block.
diff --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index ec3dab55464..c0d14c1780d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -252,16 +252,17 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
// Mark landing pad blocks.
SmallVector<const LandingPadInst *, 4> LPads;
for (BB = Fn->begin(); BB != EB; ++BB) {
- if (const auto *Invoke = dyn_cast<InvokeInst>(BB->getTerminator()))
- MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
- if (BB->isLandingPad())
- LPads.push_back(BB->getLandingPadInst());
+ if (BB->isEHPad())
+ MBBMap[BB]->setIsEHPad();
+ const Instruction *FNP = BB->getFirstNonPHI();
+ if (const auto *LPI = dyn_cast<LandingPadInst>(FNP))
+ LPads.push_back(LPI);
}
// If this is an MSVC EH personality, we need to do a bit more work.
- EHPersonality Personality = EHPersonality::Unknown;
- if (Fn->hasPersonalityFn())
- Personality = classifyEHPersonality(Fn->getPersonalityFn());
+ if (!Fn->hasPersonalityFn())
+ return;
+ EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn());
if (!isMSVCEHPersonality(Personality))
return;
@@ -272,8 +273,13 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
WinEHFuncInfo &EHInfo = MMI.getWinEHFuncInfo(&fn);
if (Personality == EHPersonality::MSVC_CXX) {
+ // Calculate state numbers and then map from funclet BBs to MBBs.
const Function *WinEHParentFn = MMI.getWinEHParent(&fn);
calculateWinCXXEHStateNumbers(WinEHParentFn, EHInfo);
+ for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap)
+ for (WinEHHandlerType &H : TBME.HandlerArray)
+ if (const auto *BB = dyn_cast<BasicBlock>(H.Handler))
+ H.HandlerMBB = MBBMap[BB];
}
// Copy the state numbers to LandingPadInfo for the current function, which
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 48811bdea59..63328200f8d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1158,30 +1158,56 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
llvm_unreachable("Can't get register for value!");
}
-void SelectionDAGBuilder::visitCleanupRet(const CleanupReturnInst &I) {
- report_fatal_error("visitCleanupRet not yet implemented!");
-}
+void SelectionDAGBuilder::visitCatchPad(const CatchPadInst &I) {
+ // Update machine-CFG edges.
+ MachineBasicBlock *PadMBB = FuncInfo.MBB;
+ MachineBasicBlock *CatchingMBB = FuncInfo.MBBMap[I.getNormalDest()];
+ MachineBasicBlock *UnwindMBB = FuncInfo.MBBMap[I.getUnwindDest()];
+ PadMBB->addSuccessor(CatchingMBB);
+ PadMBB->addSuccessor(UnwindMBB);
-void SelectionDAGBuilder::visitCatchEndPad(const CatchEndPadInst &I) {
- report_fatal_error("visitCatchEndPad not yet implemented!");
+ CatchingMBB->setIsEHFuncletEntry();
+ MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
+ MMI.setHasEHFunclets(true);
}
void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) {
- report_fatal_error("visitCatchRet not yet implemented!");
-}
+ // Update machine-CFG edge.
+ MachineBasicBlock *PadMBB = FuncInfo.MBB;
+ MachineBasicBlock *TargetMBB = FuncInfo.MBBMap[I.getSuccessor()];
+ PadMBB->addSuccessor(TargetMBB);
-void SelectionDAGBuilder::visitCatchPad(const CatchPadInst &I) {
- report_fatal_error("visitCatchPad not yet implemented!");
+ // Create the terminator node.
+ SDValue Ret = DAG.getNode(ISD::CATCHRET, getCurSDLoc(), MVT::Other,
+ getControlRoot(), DAG.getBasicBlock(TargetMBB));
+ DAG.setRoot(Ret);
}
-void SelectionDAGBuilder::visitTerminatePad(const TerminatePadInst &TPI) {
- report_fatal_error("visitTerminatePad not yet implemented!");
+void SelectionDAGBuilder::visitCatchEndPad(const CatchEndPadInst &I) {
+ // If this unwinds to caller, we don't need a DAG node hanging around.
+ if (!I.hasUnwindDest())
+ return;
+
+ // Update machine-CFG edge.
+ MachineBasicBlock *PadMBB = FuncInfo.MBB;
+ MachineBasicBlock *UnwindMBB = FuncInfo.MBBMap[I.getUnwindDest()];
+ PadMBB->addSuccessor(UnwindMBB);
}
void SelectionDAGBuilder::visitCleanupPad(const CleanupPadInst &CPI) {
+ MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
+ MMI.setHasEHFunclets(true);
report_fatal_error("visitCleanupPad not yet implemented!");
}
+void SelectionDAGBuilder::visitCleanupRet(const CleanupReturnInst &I) {
+ report_fatal_error("visitCleanupRet not yet implemented!");
+}
+
+void SelectionDAGBuilder::visitTerminatePad(const TerminatePadInst &TPI) {
+ report_fatal_error("visitTerminatePad not yet implemented!");
+}
+
void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
auto &DL = DAG.getDataLayout();
@@ -2021,7 +2047,7 @@ void SelectionDAGBuilder::visitResume(const ResumeInst &RI) {
}
void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &LP) {
- assert(FuncInfo.MBB->isLandingPad() &&
+ assert(FuncInfo.MBB->isEHPad() &&
"Call to landingpad not in landing pad!");
MachineBasicBlock *MBB = FuncInfo.MBB;
@@ -5094,7 +5120,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
assert(Reg && "cannot get exception code on this platform");
MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
const TargetRegisterClass *PtrRC = TLI.getRegClassFor(PtrVT);
- assert(FuncInfo.MBB->isLandingPad() && "eh.exceptioncode in non-lpad");
+ assert(FuncInfo.MBB->isEHPad() && "eh.exceptioncode in non-lpad");
unsigned VReg = FuncInfo.MBB->addLiveIn(Reg, PtrRC);
SDValue N =
DAG.getCopyFromReg(DAG.getEntryNode(), getCurSDLoc(), VReg, PtrVT);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 4c8658e51ca..a625e4973fd 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -278,6 +278,10 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::CALLSEQ_START: return "callseq_start";
case ISD::CALLSEQ_END: return "callseq_end";
+ // EH instructions
+ case ISD::CATCHRET: return "catchret";
+ case ISD::CLEANUPRET: return "cleanupret";
+
// Other operators
case ISD::LOAD: return "load";
case ISD::STORE: return "store";
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 7419ce547e0..be6ccb3ac61 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -19,6 +19,7 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/CFG.h"
+#include "llvm/Analysis/LibCallSemantics.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/FastISel.h"
@@ -969,7 +970,7 @@ bool SelectionDAGISel::PrepareEHLandingPad() {
InvokeBB->addSuccessor(ClauseBB);
// Mark the clause as a landing pad or MI passes will delete it.
- ClauseBB->setIsLandingPad();
+ ClauseBB->setIsEHPad();
}
}
@@ -998,9 +999,9 @@ bool SelectionDAGISel::PrepareEHLandingPad() {
static bool isFoldedOrDeadInstruction(const Instruction *I,
FunctionLoweringInfo *FuncInfo) {
return !I->mayWriteToMemory() && // Side-effecting instructions aren't folded.
- !isa<TerminatorInst>(I) && // Terminators aren't folded.
+ !isa<TerminatorInst>(I) && // Terminators aren't folded.
!isa<DbgInfoIntrinsic>(I) && // Debug instructions aren't folded.
- !isa<LandingPadInst>(I) && // Landingpad instructions aren't folded.
+ !I->isEHPad() && // EH pad instructions aren't folded.
!FuncInfo->isExportedInst(I); // Exported instrs must be computed.
}
@@ -1163,6 +1164,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
if (!PrepareEHLandingPad())
continue;
+
// Before doing SelectionDAG ISel, see if FastISel has been requested.
if (FastIS) {
FastIS->startNewBlock();
@@ -1251,7 +1253,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
// For the purpose of debugging, just abort.
report_fatal_error("FastISel didn't select the entire block");
- if (!Inst->getType()->isVoidTy() && !Inst->use_empty()) {
+ if (!Inst->getType()->isVoidTy() && !Inst->getType()->isTokenTy() &&
+ !Inst->use_empty()) {
unsigned &R = FuncInfo->ValueMap[Inst];
if (!R)
R = FuncInfo->CreateRegs(Inst->getType());
diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp
index 3cc9c395c22..df2d5db8c67 100644
--- a/llvm/lib/CodeGen/WinEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -2608,7 +2608,8 @@ static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow,
HT.TypeDescriptor =
cast<GlobalVariable>(CS->getAggregateElement(1)->stripPointerCasts());
}
- HT.Handler = CPI->getParent();
+ HT.Handler = CPI->getNormalDest();
+ HT.HandlerMBB = nullptr;
// FIXME: Pass CPI->getArgOperand(1).
HT.CatchObjRecoverIdx = -1;
TBME.HandlerArray.push_back(HT);
@@ -2684,6 +2685,7 @@ void WinEHNumbering::createTryBlockMapEntry(int TryLow, int TryHigh,
cast<GlobalVariable>(CS->getAggregateElement(1)->stripPointerCasts());
}
HT.Handler = cast<Function>(CH->getHandlerBlockOrFunc());
+ HT.HandlerMBB = nullptr;
HT.CatchObjRecoverIdx = CH->getExceptionVarIndex();
TBME.HandlerArray.push_back(HT);
}
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index ea842a68020..d7ce7fc7552 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -6931,7 +6931,7 @@ void ARMTargetLowering::EmitSjLjDispatchBlock(MachineInstr *MI,
MachineModuleInfo &MMI = MF->getMMI();
for (MachineFunction::iterator BB = MF->begin(), E = MF->end(); BB != E;
++BB) {
- if (!BB->isLandingPad()) continue;
+ if (!BB->isEHPad()) continue;
// FIXME: We should assert that the EH_LABEL is the first MI in the landing
// pad.
@@ -6979,7 +6979,7 @@ void ARMTargetLowering::EmitSjLjDispatchBlock(MachineInstr *MI,
// Shove the dispatch's address into the return slot in the function context.
MachineBasicBlock *DispatchBB = MF->CreateMachineBasicBlock();
- DispatchBB->setIsLandingPad();
+ DispatchBB->setIsEHPad();
MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
unsigned trap_opcode;
@@ -7245,7 +7245,7 @@ void ARMTargetLowering::EmitSjLjDispatchBlock(MachineInstr *MI,
BB->succ_end());
while (!Successors.empty()) {
MachineBasicBlock *SMBB = Successors.pop_back_val();
- if (SMBB->isLandingPad()) {
+ if (SMBB->isEHPad()) {
BB->removeSuccessor(SMBB);
MBBLPads.push_back(SMBB);
}
@@ -7293,7 +7293,7 @@ void ARMTargetLowering::EmitSjLjDispatchBlock(MachineInstr *MI,
// landing pad now.
for (SmallVectorImpl<MachineBasicBlock*>::iterator
I = MBBLPads.begin(), E = MBBLPads.end(); I != E; ++I)
- (*I)->setIsLandingPad(false);
+ (*I)->setIsEHPad(false);
// The instruction is gone now.
MI->eraseFromParent();
diff --git a/llvm/lib/Target/Hexagon/BitTracker.cpp b/llvm/lib/Target/Hexagon/BitTracker.cpp
index 111d3b4d01f..ec08ccc629b 100644
--- a/llvm/lib/Target/Hexagon/BitTracker.cpp
+++ b/llvm/lib/Target/Hexagon/BitTracker.cpp
@@ -951,7 +951,7 @@ void BT::visitBranchesFrom(const MachineInstr *BI) {
// be processed.
for (succ_iterator I = B.succ_begin(), E = B.succ_end(); I != E; ++I) {
const MachineBasicBlock *SB = *I;
- if (SB->isLandingPad())
+ if (SB->isEHPad())
Targets.insert(SB);
}
if (FallsThrough) {
diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index 88b54b5209d..c2e176c2c6a 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -405,7 +405,7 @@ bool MipsAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock*
// If this is a landing pad, it isn't a fall through. If it has no preds,
// then nothing falls through to it.
- if (MBB->isLandingPad() || MBB->pred_empty())
+ if (MBB->isEHPad() || MBB->pred_empty())
return false;
// If there isn't exactly one predecessor, it can't be a fall through.
diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index 664508fc7d7..c81555116d7 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -806,7 +806,7 @@ MachineBasicBlock *Filler::selectSuccBB(MachineBasicBlock &B) const {
const MachineBasicBlock *Dst1) {
return Prob.getEdgeWeight(&B, Dst0) < Prob.getEdgeWeight(&B, Dst1);
});
- return S->isLandingPad() ? nullptr : S;
+ return S->isEHPad() ? nullptr : S;
}
std::pair<MipsInstrInfo::BranchType, MachineInstr *>
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 0f8736f311e..f9f79955828 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -407,6 +407,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::SETCC , MVT::i64 , Custom);
}
setOperationAction(ISD::EH_RETURN , MVT::Other, Custom);
+ setOperationAction(ISD::CATCHRET , MVT::Other, Custom);
// NOTE: EH_SJLJ_SETJMP/_LONGJMP supported here is NOT intended to support
// SjLj exception handling but a light-weight setjmp/longjmp replacement to
// support continuation, user-level threading, and etc.. As a result, no
@@ -16664,6 +16665,25 @@ SDValue X86TargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const {
DAG.getRegister(StoreAddrReg, PtrVT));
}
+SDValue X86TargetLowering::LowerCATCHRET(SDValue Op, SelectionDAG &DAG) const {
+ SDValue Chain = Op.getOperand(0);
+ SDValue Dest = Op.getOperand(1);
+ SDLoc DL(Op);
+
+ MVT PtrVT = getPointerTy(DAG.getDataLayout());
+ unsigned ReturnReg = (PtrVT == MVT::i64 ? X86::RAX : X86::EAX);
+
+ // Load the address of the destination block.
+ MachineBasicBlock *DestMBB = cast<BasicBlockSDNode>(Dest)->getBasicBlock();
+ SDValue BlockPtr = DAG.getMCSymbol(DestMBB->getSymbol(), PtrVT);
+ unsigned WrapperKind =
+ Subtarget->isPICStyleRIPRel() ? X86ISD::WrapperRIP : X86ISD::Wrapper;
+ SDValue WrappedPtr = DAG.getNode(WrapperKind, DL, PtrVT, BlockPtr);
+ Chain = DAG.getCopyToReg(Chain, DL, ReturnReg, WrappedPtr);
+ return DAG.getNode(X86ISD::CATCHRET, DL, MVT::Other, Chain,
+ DAG.getRegister(ReturnReg, PtrVT));
+}
+
SDValue X86TargetLowering::lowerEH_SJLJ_SETJMP(SDValue Op,
SelectionDAG &DAG) const {
SDLoc DL(Op);
@@ -18903,6 +18923,7 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
return LowerFRAME_TO_ARGS_OFFSET(Op, DAG);
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG);
+ case ISD::CATCHRET: return LowerCATCHRET(Op, DAG);
case ISD::EH_SJLJ_SETJMP: return lowerEH_SJLJ_SETJMP(Op, DAG);
case ISD::EH_SJLJ_LONGJMP: return lowerEH_SJLJ_LONGJMP(Op, DAG);
case ISD::INIT_TRAMPOLINE: return LowerINIT_TRAMPOLINE(Op, DAG);
@@ -19238,6 +19259,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
case X86ISD::EH_SJLJ_SETJMP: return "X86ISD::EH_SJLJ_SETJMP";
case X86ISD::EH_SJLJ_LONGJMP: return "X86ISD::EH_SJLJ_LONGJMP";
case X86ISD::EH_RETURN: return "X86ISD::EH_RETURN";
+ case X86ISD::CATCHRET: return "X86ISD::CATCHRET";
case X86ISD::TC_RETURN: return "X86ISD::TC_RETURN";
case X86ISD::FNSTCW16m: return "X86ISD::FNSTCW16m";
case X86ISD::FNSTSW16r: return "X86ISD::FNSTSW16r";
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 824cd736ad7..69bb0e3b0e4 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -261,6 +261,8 @@ namespace llvm {
// Exception Handling helpers.
EH_RETURN,
+ CATCHRET,
+
// SjLj exception handling setjmp.
EH_SJLJ_SETJMP,
@@ -998,6 +1000,7 @@ namespace llvm {
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFRAME_TO_ARGS_OFFSET(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerCATCHRET(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td
index 28219dc7788..18c8d7d61f3 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -152,6 +152,15 @@ def EH_RETURN64 : I<0xC3, RawFrm, (outs), (ins GR64:$addr),
}
+let isTerminator = 1, isBarrier = 1, hasCtrlDep = 1, isCodeGenOnly = 1 in {
+def CATCHRET : I<0xC3, RawFrm, (outs), (ins GR32:$addr),
+ "ret{l}\t# CATCHRET",
+ [(X86catchret GR32:$addr)], IIC_RET>, Sched<[WriteJumpLd]>;
+def CATCHRET64 : I<0xC3, RawFrm, (outs), (ins GR64:$addr),
+ "ret{q}\t# CATCHRET",
+ [(X86catchret GR64:$addr)], IIC_RET>, Sched<[WriteJumpLd]>;
+}
+
let hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1,
usesCustomInserter = 1 in {
def EH_SjLj_SetJmp32 : I<0, Pseudo, (outs GR32:$dst), (ins i32mem:$buf),
diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td
index 9e61ba3aa17..5618c779608 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.td
+++ b/llvm/lib/Target/X86/X86InstrInfo.td
@@ -205,6 +205,8 @@ def X86tlsbaseaddr : SDNode<"X86ISD::TLSBASEADDR", SDT_X86TLSBASEADDR,
def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
[SDNPHasChain]>;
+def X86catchret : SDNode<"X86ISD::CATCHRET", SDT_X86EHRET, [SDNPHasChain]>;
+
def X86eh_sjlj_setjmp : SDNode<"X86ISD::EH_SJLJ_SETJMP",
SDTypeProfile<1, 1, [SDTCisInt<0>,
SDTCisPtrTy<1>]>,
diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp
index 36c74023d7b..c190bbe722e 100644
--- a/llvm/lib/Target/X86/X86MCInstLower.cpp
+++ b/llvm/lib/Target/X86/X86MCInstLower.cpp
@@ -531,6 +531,12 @@ ReSimplify:
break;
}
+ case X86::CATCHRET: {
+ OutMI = MCInst();
+ OutMI.setOpcode(getRetOpcode(AsmPrinter.getSubtarget()));
+ break;
+ }
+
// TAILJMPd, TAILJMPd64 - Lower to the correct jump instructions.
case X86::TAILJMPr:
case X86::TAILJMPd:
diff --git a/llvm/lib/Target/X86/X86WinEHState.cpp b/llvm/lib/Target/X86/X86WinEHState.cpp
index d039a0d4ca6..19f574ad746 100644
--- a/llvm/lib/Target/X86/X86WinEHState.cpp
+++ b/llvm/lib/Target/X86/X86WinEHState.cpp
@@ -471,6 +471,8 @@ int WinEHStatePass::escapeRegNode(Function &F) {
void WinEHStatePass::addCXXStateStoresToFunclet(Value *ParentRegNode,
WinEHFuncInfo &FuncInfo,
Function &F, int BaseState) {
+ Function *RestoreFrame =
+ Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_restoreframe);
// Iterate all the instructions and emit state number stores.
for (BasicBlock &BB : F) {
for (Instruction &I : BB) {
@@ -489,6 +491,14 @@ void WinEHStatePass::addCXXStateStoresToFunclet(Value *ParentRegNode,
insertStateNumberStore(ParentRegNode, II, State);
}
}
+
+ // Insert calls to llvm.x86.seh.restoreframe at catchret destinations.
+ if (auto *CR = dyn_cast<CatchReturnInst>(BB.getTerminator())) {
+ //llvm::errs() << "BB: " << BB << '\n';
+ //llvm::errs() << "CR->getSuccessor(): " << *CR->getSuccessor() << '\n';
+ IRBuilder<> Builder(CR->getSuccessor()->begin());
+ Builder.CreateCall(RestoreFrame, {});
+ }
}
}
OpenPOWER on IntegriCloud