diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfException.cpp | 11 | ||||
-rw-r--r-- | lib/CodeGen/MachineModuleInfo.cpp | 1 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 19 | ||||
-rw-r--r-- | lib/CodeGen/SjLjEHPrepare.cpp | 11 |
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 |