llvm.org GIT mirror llvm / 1b747ad
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 Jim Grosbach 11 years ago
25 changed file(s) with 340 addition(s) and 87 deletion(s). Raw diff Collapse all Expand all
3232
  • llvm.eh.typeid.for
  • 3333
  • llvm.eh.sjlj.setjmp
  • 3434
  • llvm.eh.sjlj.longjmp
  • 35
  • llvm.eh.sjlj.lsda
  • 36
  • llvm.eh.sjlj.callsite
  • 3537
    3638
  • Asm Table Formats
  • 3739
    413415
    414416

    The SJLJ exception handling uses this intrinsic to force register saving

    415417 for the current function and to store the address of the following instruction
    416 for use as a destination address by
    418 for use as a destination address by
    417419 llvm.eh.sjlj.longjmp. The buffer format and the overall functioning
    418420 of this intrinsic is compatible with the GCC __builtin_setjmp
    419421 implementation, allowing code built with the two compilers to interoperate.

    428430
    429431
    430432
    433
    434 llvm.eh.sjlj.lsda
    435
    436
    437
    438
    
                      
                    
    439 i8* %llvm.eh.sjlj.lsda( )
    440
    441
    442

    Used for SJLJ based exception handling, the

    443 llvm.eh.sjlj.lsda intrinsic returns the address of the Language
    444 Specific Data Area (LSDA) for the current function. The SJLJ front-end code
    445 stores this address in the exception handling function context for use by
    446 the runtime.

    447
    448
    449
    450
    451
    452 llvm.eh.sjlj.callsite
    453
    454
    455
    456
    
                      
                    
    457 void %llvm.eh.sjlj.callsite(i32)
    458
    459
    460

    The SJLJ front-end allocates call site indices for invoke instrucitons.

    461 These values are passed to the back-end via the
    462 llvm.eh.sjlj.callsite
    463 intrinsic, where they are used to build the LSDA call-site table.

    464
    465
    466
    467
    431468
    432469 Asm Table Formats
    433470
    1717 #ifndef LLVM_CODEGEN_MACHINEFUNCTION_H
    1818 #define LLVM_CODEGEN_MACHINEFUNCTION_H
    1919
    20 #include
    2021 #include "llvm/ADT/ilist.h"
    2122 #include "llvm/Support/DebugLoc.h"
    2223 #include "llvm/CodeGen/Dump.h"
    113114 // The alignment of the function.
    114115 unsigned Alignment;
    115116
    117 // The currently active call_site value
    118 unsigned CallSiteIndex;
    119
    120 // The largest call_site value encountered
    121 unsigned MaxCallSiteIndex;
    122
    123 // Call sites mapped to corresponding landing pads
    124 std::map LandingPadCallSiteIndexMap;
    125
    116126 public:
    117127 MachineFunction(Function *Fn, const TargetMachine &TM);
    118128 ~MachineFunction();
    157167 /// setAlignment - Set the alignment (log2, not bytes) of the function.
    158168 ///
    159169 void setAlignment(unsigned A) { Alignment = A; }
    170
    171 /// getCallSiteIndex() - Get the current call site index
    172 ///
    173 unsigned getCallSiteIndex() { return CallSiteIndex; }
    174
    175 /// setCallSiteIndex() - Set the current call site index
    176 ///
    177 void setCallSiteIndex(unsigned Idx) {
    178 CallSiteIndex = Idx;
    179 if (CallSiteIndex > MaxCallSiteIndex)
    180 MaxCallSiteIndex = CallSiteIndex;
    181 }
    182
    183 /// getMaxCallSiteIndex() - Get the largest call site index issued
    184 ///
    185 unsigned getMaxCallSiteIndex() { return MaxCallSiteIndex; }
    186
    187 /// setCallSiteIndexLandingPad() - Map the call site to a landing pad
    188 ///
    189 void setLandingPadCallSiteIndex(MachineBasicBlock *LandingPad,
    190 unsigned CallSite) {
    191 LandingPadCallSiteIndexMap[LandingPad] = CallSite;
    192 }
    193
    194 /// getCallSiteIndexLandingPad() - Get landing pad for the call site index
    195 ///
    196 unsigned getLandingPadCallSiteIndex(MachineBasicBlock *LandingPad) {
    197 return LandingPadCallSiteIndexMap[LandingPad];
    198 }
    199
    200 /// getCallSiteCount() - Get the count of call site entries
    201 ///
    202 unsigned getCallSiteCount() {
    203 return LandingPadCallSiteIndexMap.size();
    204 }
    160205
    161206 /// MachineFunctionInfo - Keep track of various per-function pieces of
    162207 /// information for backends that would like to do so.
    119119 // RESULT, OUTCHAIN = EXCEPTIONADDR(INCHAIN) - This node represents the
    120120 // address of the exception block on entry to an landing pad block.
    121121 EXCEPTIONADDR,
    122
    123 // RESULT, OUTCHAIN = LSDAADDR(INCHAIN) - This node represents the
    124 // address of the Language Specific Data Area for the enclosing function.
    125 LSDAADDR,
    122126
    123127 // RESULT, OUTCHAIN = EHSELECTION(INCHAIN, EXCEPTION) - This node represents
    124128 // the selection index of the exception thrown.
    304304 def int_eh_dwarf_cfa : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>;
    305305
    306306 let Properties = [IntrNoMem] in {
    307 def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
    308 def int_eh_sjlj_longjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_i32_ty]>;
    307 def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
    308 def int_eh_sjlj_longjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty]>;
    309 def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>;
    310 def int_eh_sjlj_callsite: Intrinsic<[llvm_void_ty], [llvm_i32_ty]>;
    309311 }
    310312
    311313 //===---------------- Generic Variable Attribute Intrinsics----------------===//
    2424
    2525 /// TargetAsmInfo - This class is intended to be used as a base class for asm
    2626 /// properties and features specific to the target.
    27 namespace ExceptionHandling { enum ExceptionsType { None, Dwarf, SjLj }; }
    28
    2729 class TargetAsmInfo {
    2830 protected:
    2931 //===------------------------------------------------------------------===//
    268270 /// SupportsExceptionHandling - True if target supports
    269271 /// exception handling.
    270272 ///
    271 bool SupportsExceptionHandling; // Defaults to false.
    273 // Defaults to None
    274 ExceptionHandling::ExceptionsType ExceptionsType;
    272275
    273276 /// RequiresFrameSection - true if the Dwarf2 output needs a frame section
    274277 ///
    481484 return SupportsDebugInformation;
    482485 }
    483486 bool doesSupportExceptionHandling() const {
    484 return SupportsExceptionHandling;
    487 return ExceptionsType != ExceptionHandling::None;
    488 }
    489 ExceptionHandling::ExceptionsType getExceptionHandlingType() const {
    490 return ExceptionsType;
    485491 }
    486492 bool doesDwarfRequireFrameSection() const {
    487493 return DwarfRequiresFrameSection;
    9393 /// .bss section. This flag disables such behaviour (necessary, e.g. for
    9494 /// crt*.o compiling).
    9595 extern bool NoZerosInBSS;
    96
    97 /// ExceptionHandling - This flag indicates that exception information should
    98 /// be emitted.
    99 extern bool ExceptionHandling;
    96
    97 /// DwarfExceptionHandling - This flag indicates that Dwarf exception
    98 /// information should be emitted.
    99 extern bool DwarfExceptionHandling;
    100
    101 /// SjLjExceptionHandling - This flag indicates that SJLJ exception
    102 /// information should be emitted.
    103 extern bool SjLjExceptionHandling;
    100104
    101105 /// UnwindTablesMandatory - This flag indicates that unwind tables should
    102106 /// be emitted for all functions.
    363363 /// try-range address.
    364364 void DwarfException::
    365365 ComputeCallSiteTable(SmallVectorImpl &CallSites,
    366 std::map &CallSiteIndexMap,
    366367 const RangeMapType &PadMap,
    367368 const SmallVectorImpl &LandingPads,
    368369 const SmallVectorImpl &FirstActions) {
    404405 assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
    405406 "Inconsistent landing pad map!");
    406407
    408 // For Dwarf exception handling (SjLj handling doesn't use this)
    407409 // If some instruction between the previous try-range and this one may
    408410 // throw, create a call-site entry with no landing pad for the region
    409411 // between the try-ranges.
    410 if (SawPotentiallyThrowing) {
    412 if (SawPotentiallyThrowing &&
    413 TAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
    411414 CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
    412415 CallSites.push_back(Site);
    413416 PreviousIsInvoke = false;
    434437
    435438 // Otherwise, create a new call-site.
    436439 CallSites.push_back(Site);
    440 // For SjLj handling, map the call site entry to its index
    441 if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj) {
    442 unsigned Index =
    443 MF->getLandingPadCallSiteIndex(LandingPad->LandingPadBlock);
    444 CallSiteIndexMap[Index] = &CallSites.back();
    445 }
    437446 PreviousIsInvoke = true;
    438447 } else {
    439448 // Create a gap.
    445454 // If some instruction between the previous try-range and the end of the
    446455 // function may throw, create a call-site entry with no landing pad for the
    447456 // region following the try-range.
    448 if (SawPotentiallyThrowing) {
    457 if (SawPotentiallyThrowing &&
    458 TAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
    449459 CallSiteEntry Site = {LastLabel, 0, 0, 0};
    450460 CallSites.push_back(Site);
    451461 }
    495505
    496506 // Invokes and nounwind calls have entries in PadMap (due to being bracketed
    497507 // by try-range labels when lowered). Ordinary calls do not, so appropriate
    498 // try-ranges for them need be deduced.
    508 // try-ranges for them need be deduced when using Dwarf exception handling.
    499509 RangeMapType PadMap;
    500510 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
    501511 const LandingPadInfo *LandingPad = LandingPads[i];
    509519
    510520 // Compute the call-site table.
    511521 SmallVector CallSites;
    512 ComputeCallSiteTable(CallSites, PadMap, LandingPads, FirstActions);
    522 std::map CallSiteIndexMap;
    523 ComputeCallSiteTable(CallSites, CallSiteIndexMap, PadMap,
    524 LandingPads, FirstActions);
    513525
    514526 // Final tallies.
    515527
    517529 const unsigned SiteStartSize = sizeof(int32_t); // DW_EH_PE_udata4
    518530 const unsigned SiteLengthSize = sizeof(int32_t); // DW_EH_PE_udata4
    519531 const unsigned LandingPadSize = sizeof(int32_t); // DW_EH_PE_udata4
    520 unsigned SizeSites = CallSites.size() * (SiteStartSize +
    521 SiteLengthSize +
    522 LandingPadSize);
    523 for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
    532 unsigned SizeSites;
    533 if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj) {
    534 SizeSites = (MF->getMaxCallSiteIndex() - CallSites.size()) *
    535 TargetAsmInfo::getULEB128Size(0) * 2;
    536 } else
    537 SizeSites = CallSites.size() *
    538 (SiteStartSize + SiteLengthSize + LandingPadSize);
    539 for (unsigned i = 0, e = CallSites.size(); i < e; ++i) {
    524540 SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action);
    525
    541 if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj)
    542 SizeSites += TargetAsmInfo::getULEB128Size(i);
    543 // FIXME: 'i' above should be the landing pad index
    544 }
    526545 // Type infos.
    527546 const unsigned TypeInfoSize = TD->getPointerSize(); // DW_EH_PE_absptr
    528547 unsigned SizeTypes = TypeInfos.size() * TypeInfoSize;
    550569 }
    551570
    552571 EmitLabel("exception", SubprogramCount);
    572 if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj) {
    573 std::string SjLjName = "_lsda_";
    574 SjLjName += MF->getFunction()->getName().str();
    575 EmitLabel(SjLjName.c_str(), 0);
    576 }
    553577
    554578 // Emit the header.
    555579 Asm->EmitInt8(dwarf::DW_EH_PE_omit);
    599623 Asm->EOL("TType base offset");
    600624 }
    601625 #else
    602 Asm->EmitInt8(dwarf::DW_EH_PE_absptr);
    603 Asm->EOL("TType format (DW_EH_PE_absptr)");
    604 Asm->EmitULEB128Bytes(TypeOffset);
    605 Asm->EOL("TType base offset");
    626 // For SjLj exceptions, is there is no TypeInfo, then we just explicitly
    627 // say that we're omitting that bit.
    628 // FIXME: does this apply to Dwarf also? The above #if 0 implies yes?
    629 if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj
    630 && (TypeInfos.empty() || FilterIds.empty())) {
    631 Asm->EmitInt8(dwarf::DW_EH_PE_omit);
    632 Asm->EOL("TType format (DW_EH_PE_omit)");
    633 } else {
    634 Asm->EmitInt8(dwarf::DW_EH_PE_absptr);
    635 Asm->EOL("TType format (DW_EH_PE_absptr)");
    636 Asm->EmitULEB128Bytes(TypeOffset);
    637 Asm->EOL("TType base offset");
    638 }
    606639 #endif
    607640
    608 Asm->EmitInt8(dwarf::DW_EH_PE_udata4);
    609 Asm->EOL("Call site format (DW_EH_PE_udata4)");
    610 Asm->EmitULEB128Bytes(SizeSites);
    611 Asm->EOL("Call-site table length");
    612
    613 // Emit the landing pad site information.
    614 for (SmallVectorImpl::const_iterator
    641 // SjLj Exception handilng
    642 if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj) {
    643 Asm->EmitInt8(dwarf::DW_EH_PE_udata4);
    644 Asm->EOL("Call site format (DW_EH_PE_udata4)");
    645 Asm->EmitULEB128Bytes(SizeSites);
    646 Asm->EOL("Call-site table length");
    647
    648
    649 assert(MF->getCallSiteCount() == CallSites.size());
    650
    651 // Emit the landing pad site information.
    652 // SjLj handling assigned the call site indices in the front end, so
    653 // we need to make sure the table here lines up with that. That's pretty
    654 // horrible, and should be fixed ASAP to do that stuff in the back end
    655 // instead.
    656 std::map::const_iterator I, E;
    657 I = CallSiteIndexMap.begin();
    658 E = CallSiteIndexMap.end();
    659 for (unsigned CurrIdx = 1; I != E; ++I) {
    660 // paranoia.
    661 assert(CurrIdx <= I->first);
    662 // Fill in any gaps in the table
    663 while (CurrIdx++ < I->first) {
    664 Asm->EmitULEB128Bytes(0);
    665 Asm->EOL("Filler landing pad");
    666 Asm->EmitULEB128Bytes(0);
    667 Asm->EOL("Filler action");
    668 }
    669 const CallSiteEntry &S = *(I->second);
    670 Asm->EmitULEB128Bytes(I->first - 1);
    671 Asm->EOL("Landing pad");
    672 Asm->EmitULEB128Bytes(S.Action);
    673 Asm->EOL("Action");
    674 }
    675 } else {
    676 // DWARF Exception handling
    677 assert(TAI->getExceptionHandlingType() == ExceptionHandling::Dwarf);
    678
    679 Asm->EmitInt8(dwarf::DW_EH_PE_udata4);
    680 Asm->EOL("Call site format (DW_EH_PE_udata4)");
    681 Asm->EmitULEB128Bytes(SizeSites);
    682 Asm->EOL("Call-site table length");
    683
    684 // Emit the landing pad site information.
    685 for (SmallVectorImpl::const_iterator
    615686 I = CallSites.begin(), E = CallSites.end(); I != E; ++I) {
    616 const CallSiteEntry &S = *I;
    617 const char *BeginTag;
    618 unsigned BeginNumber;
    619
    620 if (!S.BeginLabel) {
    621 BeginTag = "eh_func_begin";
    622 BeginNumber = SubprogramCount;
    623 } else {
    624 BeginTag = "label";
    625 BeginNumber = S.BeginLabel;
    687 const CallSiteEntry &S = *I;
    688 const char *BeginTag;
    689 unsigned BeginNumber;
    690
    691 if (!S.BeginLabel) {
    692 BeginTag = "eh_func_begin";
    693 BeginNumber = SubprogramCount;
    694 } else {
    695 BeginTag = "label";
    696 BeginNumber = S.BeginLabel;
    697 }
    698
    699 EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount,
    700 true, true);
    701 Asm->EOL("Region start");
    702
    703 if (!S.EndLabel)
    704 EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber,
    705 true);
    706 else
    707 EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true);
    708
    709 Asm->EOL("Region length");
    710
    711 if (!S.PadLabel)
    712 Asm->EmitInt32(0);
    713 else
    714 EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount,
    715 true, true);
    716
    717 Asm->EOL("Landing pad");
    718
    719 Asm->EmitULEB128Bytes(S.Action);
    720 Asm->EOL("Action");
    626721 }
    627
    628 EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount,
    629 true, true);
    630 Asm->EOL("Region start");
    631
    632 if (!S.EndLabel)
    633 EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber,
    634 true);
    635 else
    636 EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true);
    637
    638 Asm->EOL("Region length");
    639
    640 if (!S.PadLabel)
    641 Asm->EmitInt32(0);
    642 else
    643 EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount,
    644 true, true);
    645
    646 Asm->EOL("Landing pad");
    647
    648 Asm->EmitULEB128Bytes(S.Action);
    649 Asm->EOL("Action");
    650722 }
    651723
    652724 // Emit the actions.
    689761 /// EndModule - Emit all exception information that should come after the
    690762 /// content.
    691763 void DwarfException::EndModule() {
    764 if (TAI->getExceptionHandlingType() != ExceptionHandling::Dwarf)
    765 return;
    692766 if (TimePassesIsEnabled)
    693767 ExceptionTimer->startTimer();
    694768
    154154 /// of any entry - they form gaps in the table. Entries must be ordered by
    155155 /// try-range address.
    156156 void ComputeCallSiteTable(SmallVectorImpl &CallSites,
    157 std::map &CallSiteIndexMap,
    157158 const RangeMapType &PadMap,
    158159 const SmallVectorImpl &LPs,
    159160 const SmallVectorImpl &FirstActions);
    228228
    229229 // Turn exception handling constructs into something the code generators can
    230230 // handle.
    231 if (!getTargetAsmInfo()->doesSupportExceptionHandling())
    231 switch (getTargetAsmInfo()->getExceptionHandlingType())
    232 {
    233 // SjLj piggy-backs on dwarf for this bit
    234 case ExceptionHandling::SjLj:
    235 case ExceptionHandling::Dwarf:
    236 PM.add(createDwarfEHPass(getTargetLowering(), OptLevel==CodeGenOpt::None));
    237 break;
    238 case ExceptionHandling::None:
    232239 PM.add(createLowerInvokePass(getTargetLowering()));
    233 else
    234 PM.add(createDwarfEHPass(getTargetLowering(), OptLevel==CodeGenOpt::None));
    240 break;
    241 }
    235242
    236243 PM.add(createGCLoweringPass());
    237244
    9292 MachineConstantPool(TM.getTargetData());
    9393 Alignment = TM.getTargetLowering()->getFunctionAlignment(F);
    9494
    95 CallSiteIndex = 0;
    96 MaxCallSiteIndex = 0;
    97
    9598 // Set up jump table.
    9699 const TargetData &TD = *TM.getTargetData();
    97100 bool IsPic = TM.getRelocationModel() == Reloc::PIC_;
    51975197 case ISD::FRAMEADDR: return "FRAMEADDR";
    51985198 case ISD::FRAME_TO_ARGS_OFFSET: return "FRAME_TO_ARGS_OFFSET";
    51995199 case ISD::EXCEPTIONADDR: return "EXCEPTIONADDR";
    5200 case ISD::LSDAADDR: return "LSDAADDR";
    52005201 case ISD::EHSELECTION: return "EHSELECTION";
    52015202 case ISD::EH_RETURN: return "EH_RETURN";
    52025203 case ISD::ConstantPool: return "ConstantPool";
    40864086 Offset));
    40874087 return 0;
    40884088 }
    4089
    4089 case Intrinsic::eh_sjlj_callsite: {
    4090 MachineFunction &MF = DAG.getMachineFunction();
    4091 MF.setCallSiteIndex(cast(getValue(I.getOperand(1)))->getZExtValue());
    4092 return 0;
    4093 }
    40904094 case Intrinsic::convertff:
    40914095 case Intrinsic::convertfsi:
    40924096 case Intrinsic::convertfui:
    44504454 }
    44514455
    44524456 if (LandingPad && MMI) {
    4457 MachineFunction &MF = DAG.getMachineFunction();
    44534458 // Insert a label before the invoke call to mark the try range. This can be
    44544459 // used to detect deletion of the invoke via the MachineModuleInfo.
    44554460 BeginLabel = MMI->NextLabelID();
    4461
    4462 // Map this landing pad to the current call site entry
    4463 MF.setLandingPadCallSiteIndex(LandingPad, MF.getCallSiteIndex());
    4464
    44564465 // Both PendingLoads and PendingExports must be flushed here;
    44574466 // this call might not return.
    44584467 (void)getRoot();
    510510 DOUT << "JIT is managing a GOT\n";
    511511 }
    512512
    513 if (ExceptionHandling) DE = new JITDwarfEmitter(jit);
    513 if (DwarfExceptionHandling) DE = new JITDwarfEmitter(jit);
    514514 }
    515515 ~JITEmitter() {
    516516 delete MemMgr;
    517 if (ExceptionHandling) delete DE;
    517 if (DwarfExceptionHandling) delete DE;
    518518 }
    519519
    520520 /// classof - Methods for support type inquiry through isa, cast, and
    602602
    603603 virtual void setModuleInfo(MachineModuleInfo* Info) {
    604604 MMI = Info;
    605 if (ExceptionHandling) DE->setModuleInfo(Info);
    605 if (DwarfExceptionHandling) DE->setModuleInfo(Info);
    606606 }
    607607
    608608 void setMemoryExecutable(void) {
    11241124 }
    11251125 }
    11261126 #endif
    1127 if (ExceptionHandling) {
    1127 if (DwarfExceptionHandling) {
    11281128 uintptr_t ActualSize = 0;
    11291129 SavedBufferBegin = BufferBegin;
    11301130 SavedBufferEnd = BufferEnd;
    3333 const char *Modif,
    3434 bool AddCA)
    3535 : MachineConstantPoolValue((const Type*)Type::Int32Ty),
    36 GV(NULL), S(s), LabelId(id), Kind(k), PCAdjust(PCAdj),
    36 GV(NULL), S(strdup(s)), LabelId(id), Kind(k), PCAdjust(PCAdj),
    3737 Modifier(Modif), AddCurrentAddress(AddCA) {}
    3838
    3939 ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv,
    5252 bool AddCurrentAddress = false);
    5353 ARMConstantPoolValue(GlobalValue *GV, ARMCP::ARMCPKind Kind,
    5454 const char *Modifier);
    55 ARMConstantPoolValue();
    56 ~ARMConstantPoolValue() {free((void*)S);}
    5557
    5658
    5759 GlobalValue *getGV() const { return GV; }
    13911391 EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
    13921392 return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
    13931393 }
    1394 case Intrinsic::eh_sjlj_lsda: {
    1395 // blah. horrible, horrible hack with the forced magic name.
    1396 // really need to clean this up. It belongs in the target-independent
    1397 // layer somehow that doesn't require the coupling with the asm
    1398 // printer.
    1399 MachineFunction &MF = DAG.getMachineFunction();
    1400 EVT PtrVT = getPointerTy();
    1401 DebugLoc dl = Op.getDebugLoc();
    1402 Reloc::Model RelocM = getTargetMachine().getRelocationModel();
    1403 SDValue CPAddr;
    1404 unsigned PCAdj = (RelocM != Reloc::PIC_)
    1405 ? 0 : (Subtarget->isThumb() ? 4 : 8);
    1406 ARMCP::ARMCPKind Kind = ARMCP::CPValue;
    1407 // Save off the LSDA name for the AsmPrinter to use when it's time
    1408 // to emit the table
    1409 std::string LSDAName = "L_lsda_";
    1410 LSDAName += MF.getFunction()->getName();
    1411 ARMConstantPoolValue *CPV =
    1412 new ARMConstantPoolValue(LSDAName.c_str(), ARMPCLabelIndex, Kind, PCAdj);
    1413 CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4);
    1414 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, EVT::i32, CPAddr);
    1415 SDValue Result =
    1416 DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, NULL, 0);
    1417 SDValue Chain = Result.getValue(1);
    1418
    1419 if (RelocM == Reloc::PIC_) {
    1420 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, EVT::i32);
    1421 Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel);
    1422 }
    1423 return Result;
    1424 }
    13941425 case Intrinsic::eh_sjlj_setjmp:
    13951426 return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, EVT::i32, Op.getOperand(1));
    13961427 }
    14261426 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src),
    14271427 AddrModeNone, SizeSpecial, IndexModeNone,
    14281428 Pseudo, NoItinerary,
    1429 "add r0, pc, #4\n\t"
    1430 "str r0, [$src, #+4]\n\t"
    1431 "mov r0, #0 @ eh_setjmp", "",
    1429 "str sp, [$src, #+8] @ eh_setjmp begin\n\t"
    1430 "add ip, pc, #8\n\t"
    1431 "str ip, [$src, #+4]\n\t"
    1432 "mov r0, #0\n\t"
    1433 "add pc, pc, #0\n\t"
    1434 "mov r0, #1 @ eh_setjmp end\n\t", "",
    14321435 [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
    14331436 }
    14341437
    4646 ProtectedDirective = NULL;
    4747 HasDotTypeDotSizeDirective = false;
    4848 SupportsDebugInformation = true;
    49
    50 // Exceptions handling
    51 ExceptionsType = ExceptionHandling::SjLj;
    52 GlobalEHDirective = "\t.globl\t";
    53 SupportsWeakOmittedEHFrame = false;
    54 AbsoluteEHSectionOffsets = false;
    4955 }
    5056
    5157 ARMELFTargetAsmInfo::ARMELFTargetAsmInfo() {
    207207 } else {
    208208 if (GV)
    209209 Name = Mang->getMangledName(GV);
    210 else if (!strncmp(ACPV->getSymbol(), "L_lsda_", 7))
    211 Name = ACPV->getSymbol();
    210212 else
    211213 Name = Mang->makeNameProper(ACPV->getSymbol());
    212214 }
    3636
    3737 // Exception handling is not supported on CellSPU (think about it: you only
    3838 // have 256K for code+data. Would you support exception handling?)
    39 SupportsExceptionHandling = false;
    39 ExceptionsType = ExceptionHandling::None;
    4040 }
    4141
    2323 PCSymbol = ".";
    2424 CommentString = ";";
    2525 UsedDirective = "\t.no_dead_strip\t";
    26 SupportsExceptionHandling = true;
    27
    26 ExceptionsType = ExceptionHandling::Dwarf;
    27
    2828 GlobalEHDirective = "\t.globl\t";
    2929 SupportsWeakOmittedEHFrame = false;
    3030 }
    4848
    4949 // Exceptions handling
    5050 if (!TM.getSubtargetImpl()->isPPC64())
    51 SupportsExceptionHandling = true;
    51 ExceptionsType = ExceptionHandling::Dwarf;
    5252 AbsoluteEHSectionOffsets = false;
    5353 }
    5454
    7171 HasLEB128 = false;
    7272 HasDotLocAndDotFile = false;
    7373 SupportsDebugInformation = false;
    74 SupportsExceptionHandling = false;
    74 ExceptionsType = ExceptionHandling::None;
    7575 DwarfRequiresFrameSection = true;
    7676 DwarfUsesInlineInfoSection = false;
    7777 Is_EHSymbolPrivate = true;
    3232 FloatABI::ABIType FloatABIType;
    3333 bool NoImplicitFloat;
    3434 bool NoZerosInBSS;
    35 bool ExceptionHandling;
    35 bool DwarfExceptionHandling;
    36 bool SjLjExceptionHandling;
    3637 bool UnwindTablesMandatory;
    3738 Reloc::Model RelocationModel;
    3839 CodeModel::Model CMModel;
    103104 cl::location(NoZerosInBSS),
    104105 cl::init(false));
    105106 static cl::opt
    106 EnableExceptionHandling("enable-eh",
    107 EnableDwarfExceptionHandling("enable-eh",
    107108 cl::desc("Emit DWARF exception handling (default if target supports)"),
    108 cl::location(ExceptionHandling),
    109 cl::location(DwarfExceptionHandling),
    110 cl::init(false));
    111 static cl::opt
    112 EnableSjLjExceptionHandling("enable-sjlj-eh",
    113 cl::desc("Emit SJLJ exception handling (default if target supports)"),
    114 cl::location(SjLjExceptionHandling),
    109115 cl::init(false));
    110116 static cl::opt
    111117 EnableUnwindTables("unwind-tables",
    7676 DwarfUsesInlineInfoSection = true;
    7777
    7878 // Exceptions handling
    79 SupportsExceptionHandling = true;
    79 ExceptionsType = ExceptionHandling::Dwarf;
    8080 GlobalEHDirective = "\t.globl\t";
    8181 SupportsWeakOmittedEHFrame = false;
    8282 AbsoluteEHSectionOffsets = false;
    9898 SupportsDebugInformation = true;
    9999
    100100 // Exceptions handling
    101 SupportsExceptionHandling = true;
    101 ExceptionsType = ExceptionHandling::Dwarf;
    102102 AbsoluteEHSectionOffsets = false;
    103103
    104104 // On Linux we must declare when we can use a non-executable stack.
    393393
    394394 Module* mergedModule = _linker.getModule();
    395395
    396 // If target supports exception handling then enable it now.
    397 if ( _target->getTargetAsmInfo()->doesSupportExceptionHandling() )
    398 llvm::ExceptionHandling = true;
    396 // If target supports exception handling then enable it now.
    397 switch (_target->getTargetAsmInfo()->getExceptionHandlingType()) {
    398 case ExceptionHandling::Dwarf:
    399 llvm::DwarfExceptionHandling = true;
    400 break;
    401 case ExceptionHandling::SjLj:
    402 llvm::SjLjExceptionHandling = true;
    403 break;
    404 case ExceptionHandling::None:
    405 break;
    406 default:
    407 assert (0 && "Unknown exception handling model!");
    408 }
    399409
    400410 // if options were requested, set them
    401411 if ( !_codegenOptions.empty() )