diff options
author | Jim Grosbach <grosbach@apple.com> | 2009-08-11 00:09:57 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2009-08-11 00:09:57 +0000 |
commit | 1b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3 (patch) | |
tree | 55ef4dc73ff823568dc8543cbb1b4cfa77191b0b /lib | |
parent | 3a1f0f6785e27eb8ede455a3583ca8c885d3911e (diff) | |
download | external_llvm-1b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3.zip external_llvm-1b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3.tar.gz external_llvm-1b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3.tar.bz2 |
SjLj based exception handling unwinding support. This patch is nasty, brutish
and short. Well, it's kinda short. Definitely nasty and brutish.
The front-end generates the register/unregister calls into the SjLj runtime,
call-site indices and landing pad dispatch. The back end fills in the LSDA
with the call-site information provided by the front end. Catch blocks are
not yet implemented.
Built on Darwin and verified no llvm-core "make check" regressions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78625 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfException.cpp | 166 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfException.h | 1 | ||||
-rw-r--r-- | lib/CodeGen/LLVMTargetMachine.cpp | 13 | ||||
-rw-r--r-- | lib/CodeGen/MachineFunction.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 1 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp | 11 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JITEmitter.cpp | 8 | ||||
-rw-r--r-- | lib/Target/ARM/ARMConstantPoolValue.cpp | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMConstantPoolValue.h | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 31 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 9 | ||||
-rw-r--r-- | lib/Target/ARM/ARMTargetAsmInfo.cpp | 6 | ||||
-rw-r--r-- | lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp | 2 | ||||
-rw-r--r-- | lib/Target/CellSPU/SPUTargetAsmInfo.cpp | 2 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCTargetAsmInfo.cpp | 6 | ||||
-rw-r--r-- | lib/Target/TargetAsmInfo.cpp | 2 | ||||
-rw-r--r-- | lib/Target/TargetMachine.cpp | 12 | ||||
-rw-r--r-- | lib/Target/X86/X86TargetAsmInfo.cpp | 4 |
18 files changed, 213 insertions, 68 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp index fec1ad7..a0cd456 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp @@ -364,6 +364,7 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads, /// try-range address. void DwarfException:: ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, + std::map<unsigned,CallSiteEntry*> &CallSiteIndexMap, const RangeMapType &PadMap, const SmallVectorImpl<const LandingPadInfo *> &LandingPads, const SmallVectorImpl<unsigned> &FirstActions) { @@ -405,10 +406,12 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && "Inconsistent landing pad map!"); + // For Dwarf exception handling (SjLj handling doesn't use this) // If some instruction between the previous try-range and this one may // throw, create a call-site entry with no landing pad for the region // between the try-ranges. - if (SawPotentiallyThrowing) { + if (SawPotentiallyThrowing && + TAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) { CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0}; CallSites.push_back(Site); PreviousIsInvoke = false; @@ -435,6 +438,12 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, // Otherwise, create a new call-site. CallSites.push_back(Site); + // For SjLj handling, map the call site entry to its index + if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj) { + unsigned Index = + MF->getLandingPadCallSiteIndex(LandingPad->LandingPadBlock); + CallSiteIndexMap[Index] = &CallSites.back(); + } PreviousIsInvoke = true; } else { // Create a gap. @@ -446,7 +455,8 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, // If some instruction between the previous try-range and the end of the // function may throw, create a call-site entry with no landing pad for the // region following the try-range. - if (SawPotentiallyThrowing) { + if (SawPotentiallyThrowing && + TAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) { CallSiteEntry Site = {LastLabel, 0, 0, 0}; CallSites.push_back(Site); } @@ -496,7 +506,7 @@ void DwarfException::EmitExceptionTable() { // Invokes and nounwind calls have entries in PadMap (due to being bracketed // by try-range labels when lowered). Ordinary calls do not, so appropriate - // try-ranges for them need be deduced. + // try-ranges for them need be deduced when using Dwarf exception handling. RangeMapType PadMap; for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { const LandingPadInfo *LandingPad = LandingPads[i]; @@ -510,7 +520,9 @@ void DwarfException::EmitExceptionTable() { // Compute the call-site table. SmallVector<CallSiteEntry, 64> CallSites; - ComputeCallSiteTable(CallSites, PadMap, LandingPads, FirstActions); + std::map<unsigned,CallSiteEntry*> CallSiteIndexMap; + ComputeCallSiteTable(CallSites, CallSiteIndexMap, PadMap, + LandingPads, FirstActions); // Final tallies. @@ -518,12 +530,19 @@ void DwarfException::EmitExceptionTable() { const unsigned SiteStartSize = sizeof(int32_t); // DW_EH_PE_udata4 const unsigned SiteLengthSize = sizeof(int32_t); // DW_EH_PE_udata4 const unsigned LandingPadSize = sizeof(int32_t); // DW_EH_PE_udata4 - unsigned SizeSites = CallSites.size() * (SiteStartSize + - SiteLengthSize + - LandingPadSize); - for (unsigned i = 0, e = CallSites.size(); i < e; ++i) + unsigned SizeSites; + if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj) { + SizeSites = (MF->getMaxCallSiteIndex() - CallSites.size()) * + TargetAsmInfo::getULEB128Size(0) * 2; + } else + SizeSites = CallSites.size() * + (SiteStartSize + SiteLengthSize + LandingPadSize); + for (unsigned i = 0, e = CallSites.size(); i < e; ++i) { SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action); - + if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj) + SizeSites += TargetAsmInfo::getULEB128Size(i); + // FIXME: 'i' above should be the landing pad index + } // Type infos. const unsigned TypeInfoSize = TD->getPointerSize(); // DW_EH_PE_absptr unsigned SizeTypes = TypeInfos.size() * TypeInfoSize; @@ -551,6 +570,11 @@ void DwarfException::EmitExceptionTable() { } EmitLabel("exception", SubprogramCount); + if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj) { + std::string SjLjName = "_lsda_"; + SjLjName += MF->getFunction()->getName().str(); + EmitLabel(SjLjName.c_str(), 0); + } // Emit the header. Asm->EmitInt8(dwarf::DW_EH_PE_omit); @@ -600,54 +624,102 @@ void DwarfException::EmitExceptionTable() { Asm->EOL("TType base offset"); } #else - Asm->EmitInt8(dwarf::DW_EH_PE_absptr); - Asm->EOL("TType format (DW_EH_PE_absptr)"); - Asm->EmitULEB128Bytes(TypeOffset); - Asm->EOL("TType base offset"); + // For SjLj exceptions, is there is no TypeInfo, then we just explicitly + // say that we're omitting that bit. + // FIXME: does this apply to Dwarf also? The above #if 0 implies yes? + if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj + && (TypeInfos.empty() || FilterIds.empty())) { + Asm->EmitInt8(dwarf::DW_EH_PE_omit); + Asm->EOL("TType format (DW_EH_PE_omit)"); + } else { + Asm->EmitInt8(dwarf::DW_EH_PE_absptr); + Asm->EOL("TType format (DW_EH_PE_absptr)"); + Asm->EmitULEB128Bytes(TypeOffset); + Asm->EOL("TType base offset"); + } #endif - Asm->EmitInt8(dwarf::DW_EH_PE_udata4); - Asm->EOL("Call site format (DW_EH_PE_udata4)"); - Asm->EmitULEB128Bytes(SizeSites); - Asm->EOL("Call-site table length"); + // SjLj Exception handilng + if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj) { + Asm->EmitInt8(dwarf::DW_EH_PE_udata4); + Asm->EOL("Call site format (DW_EH_PE_udata4)"); + Asm->EmitULEB128Bytes(SizeSites); + Asm->EOL("Call-site table length"); + + + assert(MF->getCallSiteCount() == CallSites.size()); + + // Emit the landing pad site information. + // SjLj handling assigned the call site indices in the front end, so + // we need to make sure the table here lines up with that. That's pretty + // horrible, and should be fixed ASAP to do that stuff in the back end + // instead. + std::map<unsigned, CallSiteEntry*>::const_iterator I, E; + I = CallSiteIndexMap.begin(); + E = CallSiteIndexMap.end(); + for (unsigned CurrIdx = 1; I != E; ++I) { + // paranoia. + assert(CurrIdx <= I->first); + // Fill in any gaps in the table + while (CurrIdx++ < I->first) { + Asm->EmitULEB128Bytes(0); + Asm->EOL("Filler landing pad"); + Asm->EmitULEB128Bytes(0); + Asm->EOL("Filler action"); + } + const CallSiteEntry &S = *(I->second); + Asm->EmitULEB128Bytes(I->first - 1); + Asm->EOL("Landing pad"); + Asm->EmitULEB128Bytes(S.Action); + Asm->EOL("Action"); + } + } else { + // DWARF Exception handling + assert(TAI->getExceptionHandlingType() == ExceptionHandling::Dwarf); + + Asm->EmitInt8(dwarf::DW_EH_PE_udata4); + Asm->EOL("Call site format (DW_EH_PE_udata4)"); + Asm->EmitULEB128Bytes(SizeSites); + Asm->EOL("Call-site table length"); - // Emit the landing pad site information. - for (SmallVectorImpl<CallSiteEntry>::const_iterator + // Emit the landing pad site information. + for (SmallVectorImpl<CallSiteEntry>::const_iterator I = CallSites.begin(), E = CallSites.end(); I != E; ++I) { - const CallSiteEntry &S = *I; - const char *BeginTag; - unsigned BeginNumber; + const CallSiteEntry &S = *I; + const char *BeginTag; + unsigned BeginNumber; - if (!S.BeginLabel) { - BeginTag = "eh_func_begin"; - BeginNumber = SubprogramCount; - } else { - BeginTag = "label"; - BeginNumber = S.BeginLabel; - } + if (!S.BeginLabel) { + BeginTag = "eh_func_begin"; + BeginNumber = SubprogramCount; + } else { + BeginTag = "label"; + BeginNumber = S.BeginLabel; + } - EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount, - true, true); - Asm->EOL("Region start"); + EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount, + true, true); + Asm->EOL("Region start"); - if (!S.EndLabel) - EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber, - true); - else - EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true); + if (!S.EndLabel) + EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber, + true); + else + EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true); - Asm->EOL("Region length"); + Asm->EOL("Region length"); - if (!S.PadLabel) - Asm->EmitInt32(0); - else - EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount, - true, true); + if (!S.PadLabel) + Asm->EmitInt32(0); + else + EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount, + true, true); - Asm->EOL("Landing pad"); + Asm->EOL("Landing pad"); - Asm->EmitULEB128Bytes(S.Action); - Asm->EOL("Action"); + Asm->EmitULEB128Bytes(S.Action); + Asm->EOL("Action"); + } } // Emit the actions. @@ -690,6 +762,8 @@ void DwarfException::EmitExceptionTable() { /// EndModule - Emit all exception information that should come after the /// content. void DwarfException::EndModule() { + if (TAI->getExceptionHandlingType() != ExceptionHandling::Dwarf) + return; if (TimePassesIsEnabled) ExceptionTimer->startTimer(); diff --git a/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h index e165df4..ee390cf 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.h +++ b/lib/CodeGen/AsmPrinter/DwarfException.h @@ -155,6 +155,7 @@ class VISIBILITY_HIDDEN DwarfException : public Dwarf { /// of any entry - they form gaps in the table. Entries must be ordered by /// try-range address. void ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, + std::map<unsigned,CallSiteEntry*> &CallSiteIndexMap, const RangeMapType &PadMap, const SmallVectorImpl<const LandingPadInfo *> &LPs, const SmallVectorImpl<unsigned> &FirstActions); diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index 8249501..c60f9c7 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -229,10 +229,17 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, // Turn exception handling constructs into something the code generators can // handle. - if (!getTargetAsmInfo()->doesSupportExceptionHandling()) - PM.add(createLowerInvokePass(getTargetLowering())); - else + switch (getTargetAsmInfo()->getExceptionHandlingType()) + { + // SjLj piggy-backs on dwarf for this bit + case ExceptionHandling::SjLj: + case ExceptionHandling::Dwarf: PM.add(createDwarfEHPass(getTargetLowering(), OptLevel==CodeGenOpt::None)); + break; + case ExceptionHandling::None: + PM.add(createLowerInvokePass(getTargetLowering())); + break; + } PM.add(createGCLoweringPass()); diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index 2e9303a..ab037c2 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -93,6 +93,9 @@ MachineFunction::MachineFunction(Function *F, MachineConstantPool(TM.getTargetData()); Alignment = TM.getTargetLowering()->getFunctionAlignment(F); + CallSiteIndex = 0; + MaxCallSiteIndex = 0; + // Set up jump table. const TargetData &TD = *TM.getTargetData(); bool IsPic = TM.getRelocationModel() == Reloc::PIC_; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 712feda..7297d60 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5198,6 +5198,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const { case ISD::FRAMEADDR: return "FRAMEADDR"; case ISD::FRAME_TO_ARGS_OFFSET: return "FRAME_TO_ARGS_OFFSET"; case ISD::EXCEPTIONADDR: return "EXCEPTIONADDR"; + case ISD::LSDAADDR: return "LSDAADDR"; case ISD::EHSELECTION: return "EHSELECTION"; case ISD::EH_RETURN: return "EH_RETURN"; case ISD::ConstantPool: return "ConstantPool"; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index 0180069..1d02bff 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -4087,7 +4087,11 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { Offset)); return 0; } - + case Intrinsic::eh_sjlj_callsite: { + MachineFunction &MF = DAG.getMachineFunction(); + MF.setCallSiteIndex(cast<ConstantSDNode>(getValue(I.getOperand(1)))->getZExtValue()); + return 0; + } case Intrinsic::convertff: case Intrinsic::convertfsi: case Intrinsic::convertfui: @@ -4451,9 +4455,14 @@ void SelectionDAGLowering::LowerCallTo(CallSite CS, SDValue Callee, } if (LandingPad && MMI) { + MachineFunction &MF = DAG.getMachineFunction(); // Insert a label before the invoke call to mark the try range. This can be // used to detect deletion of the invoke via the MachineModuleInfo. BeginLabel = MMI->NextLabelID(); + + // Map this landing pad to the current call site entry + MF.setLandingPadCallSiteIndex(LandingPad, MF.getCallSiteIndex()); + // Both PendingLoads and PendingExports must be flushed here; // this call might not return. (void)getRoot(); diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index af69ddf..c3e1651 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -511,11 +511,11 @@ namespace { DOUT << "JIT is managing a GOT\n"; } - if (ExceptionHandling) DE = new JITDwarfEmitter(jit); + if (DwarfExceptionHandling) DE = new JITDwarfEmitter(jit); } ~JITEmitter() { delete MemMgr; - if (ExceptionHandling) delete DE; + if (DwarfExceptionHandling) delete DE; } /// classof - Methods for support type inquiry through isa, cast, and @@ -603,7 +603,7 @@ namespace { virtual void setModuleInfo(MachineModuleInfo* Info) { MMI = Info; - if (ExceptionHandling) DE->setModuleInfo(Info); + if (DwarfExceptionHandling) DE->setModuleInfo(Info); } void setMemoryExecutable(void) { @@ -1125,7 +1125,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) { } } #endif - if (ExceptionHandling) { + if (DwarfExceptionHandling) { uintptr_t ActualSize = 0; SavedBufferBegin = BufferBegin; SavedBufferEnd = BufferEnd; diff --git a/lib/Target/ARM/ARMConstantPoolValue.cpp b/lib/Target/ARM/ARMConstantPoolValue.cpp index a75ed3b..adf03e0 100644 --- a/lib/Target/ARM/ARMConstantPoolValue.cpp +++ b/lib/Target/ARM/ARMConstantPoolValue.cpp @@ -34,7 +34,7 @@ ARMConstantPoolValue::ARMConstantPoolValue(const char *s, unsigned id, const char *Modif, bool AddCA) : MachineConstantPoolValue((const Type*)Type::Int32Ty), - GV(NULL), S(s), LabelId(id), Kind(k), PCAdjust(PCAdj), + GV(NULL), S(strdup(s)), LabelId(id), Kind(k), PCAdjust(PCAdj), Modifier(Modif), AddCurrentAddress(AddCA) {} ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv, diff --git a/lib/Target/ARM/ARMConstantPoolValue.h b/lib/Target/ARM/ARMConstantPoolValue.h index fcaf2e6..37a2c80 100644 --- a/lib/Target/ARM/ARMConstantPoolValue.h +++ b/lib/Target/ARM/ARMConstantPoolValue.h @@ -53,6 +53,8 @@ public: bool AddCurrentAddress = false); ARMConstantPoolValue(GlobalValue *GV, ARMCP::ARMCPKind Kind, const char *Modifier); + ARMConstantPoolValue(); + ~ARMConstantPoolValue() {free((void*)S);} GlobalValue *getGV() const { return GV; } diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index aedddaa..61722d4 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -1392,6 +1392,37 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) { EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT); } + case Intrinsic::eh_sjlj_lsda: { + // blah. horrible, horrible hack with the forced magic name. + // really need to clean this up. It belongs in the target-independent + // layer somehow that doesn't require the coupling with the asm + // printer. + MachineFunction &MF = DAG.getMachineFunction(); + EVT PtrVT = getPointerTy(); + DebugLoc dl = Op.getDebugLoc(); + Reloc::Model RelocM = getTargetMachine().getRelocationModel(); + SDValue CPAddr; + unsigned PCAdj = (RelocM != Reloc::PIC_) + ? 0 : (Subtarget->isThumb() ? 4 : 8); + ARMCP::ARMCPKind Kind = ARMCP::CPValue; + // Save off the LSDA name for the AsmPrinter to use when it's time + // to emit the table + std::string LSDAName = "L_lsda_"; + LSDAName += MF.getFunction()->getName(); + ARMConstantPoolValue *CPV = + new ARMConstantPoolValue(LSDAName.c_str(), ARMPCLabelIndex, Kind, PCAdj); + CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); + CPAddr = DAG.getNode(ARMISD::Wrapper, dl, EVT::i32, CPAddr); + SDValue Result = + DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, NULL, 0); + SDValue Chain = Result.getValue(1); + + if (RelocM == Reloc::PIC_) { + SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, EVT::i32); + Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel); + } + return Result; + } case Intrinsic::eh_sjlj_setjmp: return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, EVT::i32, Op.getOperand(1)); } diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 5190492..4a2ce4b 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -1427,9 +1427,12 @@ let Defs = def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src), AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, NoItinerary, - "add r0, pc, #4\n\t" - "str r0, [$src, #+4]\n\t" - "mov r0, #0 @ eh_setjmp", "", + "str sp, [$src, #+8] @ eh_setjmp begin\n\t" + "add ip, pc, #8\n\t" + "str ip, [$src, #+4]\n\t" + "mov r0, #0\n\t" + "add pc, pc, #0\n\t" + "mov r0, #1 @ eh_setjmp end\n\t", "", [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>; } diff --git a/lib/Target/ARM/ARMTargetAsmInfo.cpp b/lib/Target/ARM/ARMTargetAsmInfo.cpp index e3348a9..653219b 100644 --- a/lib/Target/ARM/ARMTargetAsmInfo.cpp +++ b/lib/Target/ARM/ARMTargetAsmInfo.cpp @@ -47,6 +47,12 @@ ARMDarwinTargetAsmInfo::ARMDarwinTargetAsmInfo() { ProtectedDirective = NULL; HasDotTypeDotSizeDirective = false; SupportsDebugInformation = true; + + // Exceptions handling + ExceptionsType = ExceptionHandling::SjLj; + GlobalEHDirective = "\t.globl\t"; + SupportsWeakOmittedEHFrame = false; + AbsoluteEHSectionOffsets = false; } ARMELFTargetAsmInfo::ARMELFTargetAsmInfo() { diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp index a909b66..9de9af6 100644 --- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp @@ -208,6 +208,8 @@ namespace { } else { if (GV) Name = Mang->getMangledName(GV); + else if (!strncmp(ACPV->getSymbol(), "L_lsda_", 7)) + Name = ACPV->getSymbol(); else Name = Mang->makeNameProper(ACPV->getSymbol()); } diff --git a/lib/Target/CellSPU/SPUTargetAsmInfo.cpp b/lib/Target/CellSPU/SPUTargetAsmInfo.cpp index 2dcb113..991afa0 100644 --- a/lib/Target/CellSPU/SPUTargetAsmInfo.cpp +++ b/lib/Target/CellSPU/SPUTargetAsmInfo.cpp @@ -37,6 +37,6 @@ SPULinuxTargetAsmInfo::SPULinuxTargetAsmInfo() { // Exception handling is not supported on CellSPU (think about it: you only // have 256K for code+data. Would you support exception handling?) - SupportsExceptionHandling = false; + ExceptionsType = ExceptionHandling::None; } diff --git a/lib/Target/PowerPC/PPCTargetAsmInfo.cpp b/lib/Target/PowerPC/PPCTargetAsmInfo.cpp index 2612017..52e2986 100644 --- a/lib/Target/PowerPC/PPCTargetAsmInfo.cpp +++ b/lib/Target/PowerPC/PPCTargetAsmInfo.cpp @@ -24,8 +24,8 @@ PPCDarwinTargetAsmInfo::PPCDarwinTargetAsmInfo(const PPCTargetMachine &TM) : PCSymbol = "."; CommentString = ";"; UsedDirective = "\t.no_dead_strip\t"; - SupportsExceptionHandling = true; - + ExceptionsType = ExceptionHandling::Dwarf; + GlobalEHDirective = "\t.globl\t"; SupportsWeakOmittedEHFrame = false; } @@ -49,7 +49,7 @@ PPCLinuxTargetAsmInfo::PPCLinuxTargetAsmInfo(const PPCTargetMachine &TM) : // Exceptions handling if (!TM.getSubtargetImpl()->isPPC64()) - SupportsExceptionHandling = true; + ExceptionsType = ExceptionHandling::Dwarf; AbsoluteEHSectionOffsets = false; } diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp index 6ac54e0..84a9771 100644 --- a/lib/Target/TargetAsmInfo.cpp +++ b/lib/Target/TargetAsmInfo.cpp @@ -72,7 +72,7 @@ TargetAsmInfo::TargetAsmInfo() { HasLEB128 = false; HasDotLocAndDotFile = false; SupportsDebugInformation = false; - SupportsExceptionHandling = false; + ExceptionsType = ExceptionHandling::None; DwarfRequiresFrameSection = true; DwarfUsesInlineInfoSection = false; Is_EHSymbolPrivate = true; diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp index fb95c52..b94fa68 100644 --- a/lib/Target/TargetMachine.cpp +++ b/lib/Target/TargetMachine.cpp @@ -33,7 +33,8 @@ namespace llvm { FloatABI::ABIType FloatABIType; bool NoImplicitFloat; bool NoZerosInBSS; - bool ExceptionHandling; + bool DwarfExceptionHandling; + bool SjLjExceptionHandling; bool UnwindTablesMandatory; Reloc::Model RelocationModel; CodeModel::Model CMModel; @@ -104,9 +105,14 @@ DontPlaceZerosInBSS("nozero-initialized-in-bss", cl::location(NoZerosInBSS), cl::init(false)); static cl::opt<bool, true> -EnableExceptionHandling("enable-eh", +EnableDwarfExceptionHandling("enable-eh", cl::desc("Emit DWARF exception handling (default if target supports)"), - cl::location(ExceptionHandling), + cl::location(DwarfExceptionHandling), + cl::init(false)); +static cl::opt<bool, true> +EnableSjLjExceptionHandling("enable-sjlj-eh", + cl::desc("Emit SJLJ exception handling (default if target supports)"), + cl::location(SjLjExceptionHandling), cl::init(false)); static cl::opt<bool, true> EnableUnwindTables("unwind-tables", diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp index 297ebf5..b702cbf 100644 --- a/lib/Target/X86/X86TargetAsmInfo.cpp +++ b/lib/Target/X86/X86TargetAsmInfo.cpp @@ -77,7 +77,7 @@ X86DarwinTargetAsmInfo::X86DarwinTargetAsmInfo(const X86TargetMachine &TM): DwarfUsesInlineInfoSection = true; // Exceptions handling - SupportsExceptionHandling = true; + ExceptionsType = ExceptionHandling::Dwarf; GlobalEHDirective = "\t.globl\t"; SupportsWeakOmittedEHFrame = false; AbsoluteEHSectionOffsets = false; @@ -99,7 +99,7 @@ X86ELFTargetAsmInfo::X86ELFTargetAsmInfo(const X86TargetMachine &TM) : SupportsDebugInformation = true; // Exceptions handling - SupportsExceptionHandling = true; + ExceptionsType = ExceptionHandling::Dwarf; AbsoluteEHSectionOffsets = false; // On Linux we must declare when we can use a non-executable stack. |