aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp11
-rw-r--r--lib/CodeGen/MachineModuleInfo.cpp1
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp19
-rw-r--r--lib/CodeGen/SjLjEHPrepare.cpp11
4 files changed, 36 insertions, 6 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp
index d119b3cbd3..c762b70176 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp
@@ -579,7 +579,16 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
}
// Otherwise, create a new call-site.
- CallSites.push_back(Site);
+ if (MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf)
+ CallSites.push_back(Site);
+ else {
+ // SjLj EH must maintain the call sites in the order assigned
+ // to them by the SjLjPrepare pass.
+ unsigned SiteNo = MMI->getCallSiteBeginLabel(BeginLabel);
+ if (CallSites.size() < SiteNo)
+ CallSites.resize(SiteNo);
+ CallSites[SiteNo - 1] = Site;
+ }
PreviousIsInvoke = true;
} else {
// Create a gap.
diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp
index ed5bb5e541..dc26d9144f 100644
--- a/lib/CodeGen/MachineModuleInfo.cpp
+++ b/lib/CodeGen/MachineModuleInfo.cpp
@@ -71,6 +71,7 @@ void MachineModuleInfo::EndFunction() {
// Clean up exception info.
LandingPads.clear();
+ CallSiteMap.clear();
TypeInfos.clear();
FilterIds.clear();
FilterEnds.clear();
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 36059a5e85..23ebc7b17d 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4327,6 +4327,16 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
+ case Intrinsic::eh_sjlj_callsite: {
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+ ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1));
+ assert(CI && "Non-constant call site value in eh.sjlj.callsite!");
+ assert(MMI->getCurrentCallSite() == 0 && "Overlapping call sites!");
+
+ MMI->setCurrentCallSite(CI->getZExtValue());
+ return 0;
+ }
+
case Intrinsic::convertff:
case Intrinsic::convertfsi:
case Intrinsic::convertfui:
@@ -4784,6 +4794,15 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
// used to detect deletion of the invoke via the MachineModuleInfo.
BeginLabel = MMI->NextLabelID();
+ // For SjLj, keep track of which landing pads go with which invokes
+ // so as to maintain the ordering of pads in the LSDA.
+ unsigned CallSiteIndex = MMI->getCurrentCallSite();
+ if (CallSiteIndex) {
+ MMI->setCallSiteBeginLabel(BeginLabel, CallSiteIndex);
+ // Now that the call site is handled, stop tracking it.
+ MMI->setCurrentCallSite(0);
+ }
+
// Both PendingLoads and PendingExports must be flushed here;
// this call might not return.
(void)getRoot();
diff --git a/lib/CodeGen/SjLjEHPrepare.cpp b/lib/CodeGen/SjLjEHPrepare.cpp
index 95589331cf..8d4d1b21dd 100644
--- a/lib/CodeGen/SjLjEHPrepare.cpp
+++ b/lib/CodeGen/SjLjEHPrepare.cpp
@@ -51,6 +51,7 @@ namespace {
Value *PersonalityFn;
Constant *SelectorFn;
Constant *ExceptionFn;
+ Constant *CallSiteFn;
Value *CallSite;
public:
@@ -116,6 +117,7 @@ bool SjLjEHPass::doInitialization(Module &M) {
LSDAAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_lsda);
SelectorFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_selector);
ExceptionFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_exception);
+ CallSiteFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_callsite);
PersonalityFn = 0;
return true;
@@ -143,15 +145,14 @@ void SjLjEHPass::markInvokeCallSite(InvokeInst *II, unsigned InvokeNo,
}
}
- // Insert a store of the invoke num before the invoke and store zero into the
- // location afterward.
+ // Insert a store of the invoke num before the invoke
new StoreInst(CallSiteNoC, CallSite, true, II); // volatile
+ CallInst::Create(CallSiteFn, CallSiteNoC, "", II);
// Add a switch case to our unwind block.
CatchSwitch->addCase(SwitchValC, II->getUnwindDest());
- // We still want this to look like an invoke so we emit the LSDA properly
- // FIXME: ??? Or will this cause strangeness with mis-matched IDs like
- // when it was in the front end?
+ // We still want this to look like an invoke so we emit the LSDA properly,
+ // so we don't transform the invoke into a call here.
}
/// MarkBlocksLiveIn - Insert BB and all of its predescessors into LiveBBs until