diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 00a455c3609..a899651dbdf 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -32,6 +32,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/DebugLoc.h" +#include "llvm/Support/Dwarf.h" #include "llvm/Target/TargetMachine.h" #include #include @@ -750,7 +751,7 @@ public: /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC /// jumptable. virtual SDValue getPICJumpTableRelocBase(SDValue Table, - SelectionDAG &DAG) const; + SelectionDAG &DAG) const; /// isOffsetFoldingLegal - Return true if folding a constant offset /// with the given GlobalAddress is legal. It is frequently not legal in @@ -760,6 +761,18 @@ public: /// getFunctionAlignment - Return the Log2 alignment of this function. virtual unsigned getFunctionAlignment(const Function *) const = 0; + /// getPreferredLSDADataFormat - Return the preferred exception handling data + /// format for the LSDA. + virtual unsigned getPreferredLSDADataFormat() const { + return dwarf::DW_EH_PE_absptr; + } + + /// getPreferredFDEDataFormat - Return the preferred exception handling data + /// format for the FDE. + virtual unsigned getPreferredFDEDataFormat() const { + return dwarf::DW_EH_PE_absptr; + } + //===--------------------------------------------------------------------===// // TargetLowering Optimization Methods // diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp index a8d8bfd7590..e32447392f4 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp @@ -22,6 +22,7 @@ #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetLoweringObjectFile.h" +#include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/Dwarf.h" @@ -80,6 +81,7 @@ void DwarfException::EmitCIE(const Function *Personality, unsigned Index) { EmitLabel("eh_frame_common_begin", Index); Asm->EmitInt32((int)0); Asm->EOL("CIE Identifier Tag"); + Asm->EmitInt8(dwarf::DW_CIE_VERSION); Asm->EOL("CIE Version"); @@ -91,23 +93,29 @@ void DwarfException::EmitCIE(const Function *Personality, unsigned Index) { // Round out reader. Asm->EmitULEB128Bytes(1); Asm->EOL("CIE Code Alignment Factor"); + Asm->EmitSLEB128Bytes(stackGrowth); Asm->EOL("CIE Data Alignment Factor"); + Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true)); Asm->EOL("CIE Return Address Column"); + unsigned Encoding = 0; + // If there is a personality, we need to indicate the function's location. if (Personality) { Asm->EmitULEB128Bytes(7); Asm->EOL("Augmentation Size"); if (MAI->getNeedsIndirectEncoding()) { - Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 | - dwarf::DW_EH_PE_indirect); - Asm->EOL("Personality (pcrel sdata4 indirect)"); + Encoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 | + dwarf::DW_EH_PE_indirect; + Asm->EmitInt8(Encoding); + Asm->EOL("Personality", Encoding); } else { - Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); - Asm->EOL("Personality (pcrel sdata4)"); + Encoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; + Asm->EmitInt8(Encoding); + Asm->EOL("Personality", Encoding); } PrintRelDirective(true); @@ -118,17 +126,20 @@ void DwarfException::EmitCIE(const Function *Personality, unsigned Index) { O << "-" << MAI->getPCSymbol(); Asm->EOL("Personality"); - Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); - Asm->EOL("LSDA Encoding (pcrel sdata4)"); + Encoding = Asm->TM.getTargetLowering()->getPreferredLSDADataFormat(); + Asm->EmitInt8(Encoding); + Asm->EOL("LSDA Encoding", Encoding); - Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); - Asm->EOL("FDE Encoding (pcrel sdata4)"); + Encoding = Asm->TM.getTargetLowering()->getPreferredFDEDataFormat(); + Asm->EmitInt8(Encoding); + Asm->EOL("FDE Encoding", Encoding); } else { Asm->EmitULEB128Bytes(1); Asm->EOL("Augmentation Size"); - Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); - Asm->EOL("FDE Encoding (pcrel sdata4)"); + Encoding = Asm->TM.getTargetLowering()->getPreferredFDEDataFormat(); + Asm->EmitInt8(Encoding); + Asm->EOL("FDE Encoding", Encoding); } // Indicate locations of general callee saved registers in frame. @@ -152,6 +163,7 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { "Should not emit 'available externally' functions at all"); const Function *TheFunc = EHFrameInfo.function; + bool is4Byte = TD->getPointerSize() == sizeof(int32_t); Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getEHFrameSection()); @@ -195,23 +207,22 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { Asm->EOL("FDE CIE offset"); - EmitReference("eh_func_begin", EHFrameInfo.Number, true, true); + EmitReference("eh_func_begin", EHFrameInfo.Number, true, is4Byte); Asm->EOL("FDE initial location"); + EmitDifference("eh_func_end", EHFrameInfo.Number, - "eh_func_begin", EHFrameInfo.Number, true); + "eh_func_begin", EHFrameInfo.Number, is4Byte); Asm->EOL("FDE address range"); // If there is a personality and landing pads then point to the language // specific data area in the exception table. if (MMI->getPersonalities()[0] != NULL) { - bool is4Byte = TD->getPointerSize() == sizeof(int32_t); - Asm->EmitULEB128Bytes(is4Byte ? 4 : 8); Asm->EOL("Augmentation size"); - if (EHFrameInfo.hasLandingPads) + if (EHFrameInfo.hasLandingPads) { EmitReference("exception", EHFrameInfo.Number, true, false); - else { + } else { if (is4Byte) Asm->EmitInt32((int)0); else @@ -918,6 +929,8 @@ void DwarfException::EndFunction() { MF->getFunction())); } + MF = 0; + if (TimePassesIsEnabled) ExceptionTimer->stopTimer(); } diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index ad9bbe1d311..1f51d048597 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -464,6 +464,40 @@ unsigned PPCTargetLowering::getFunctionAlignment(const Function *F) const { return 2; } +/// getPreferredLSDADataFormat - Return the preferred exception handling data +/// format for the LSDA. +unsigned PPCTargetLowering::getPreferredLSDADataFormat() const { + if (getTargetMachine().getSubtarget().isDarwin()) + return dwarf::DW_EH_PE_pcrel; + + if (PPCSubTarget.isPPC64() || + getTargetMachine().getRelocationModel() == Reloc::PIC_) { + unsigned DataTy = + (PPCSubTarget.isPPC64() ? + dwarf::DW_EH_PE_udata8 : dwarf::DW_EH_PE_udata4); + return dwarf::DW_EH_PE_pcrel | DataTy; + } + + return dwarf::DW_EH_PE_absptr; +} + +/// getPreferredFDEDataFormat - Return the preferred exception handling data +/// format for the FDE. +unsigned PPCTargetLowering::getPreferredFDEDataFormat() const { + if (getTargetMachine().getSubtarget().isDarwin()) + return dwarf::DW_EH_PE_pcrel; + + if (PPCSubTarget.isPPC64() || + getTargetMachine().getRelocationModel() == Reloc::PIC_) { + unsigned DataTy = + (PPCSubTarget.isPPC64() ? + dwarf::DW_EH_PE_udata8 : dwarf::DW_EH_PE_udata4); + return dwarf::DW_EH_PE_pcrel | DataTy; + } + + return dwarf::DW_EH_PE_absptr; +} + //===----------------------------------------------------------------------===// // Node matching predicates, for use by the tblgen matching code. //===----------------------------------------------------------------------===// diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index 19fef4da0b4..9e5e36ad14e 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -346,6 +346,14 @@ namespace llvm { /// getFunctionAlignment - Return the Log2 alignment of this function. virtual unsigned getFunctionAlignment(const Function *F) const; + /// getPreferredLSDADataFormat - Return the preferred exception handling data + /// format for the LSDA. + virtual unsigned getPreferredLSDADataFormat() const; + + /// getPreferredFDEDataFormat - Return the preferred exception handling data + /// format for the FDE. + virtual unsigned getPreferredFDEDataFormat() const; + private: SDValue getFramePointerFrameIndex(SelectionDAG & DAG) const; SDValue getReturnAddrFrameIndex(SelectionDAG & DAG) const; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 15af42e8c48..3600987f26a 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1055,6 +1055,49 @@ unsigned X86TargetLowering::getFunctionAlignment(const Function *F) const { return F->hasFnAttr(Attribute::OptimizeForSize) ? 0 : 4; } +/// getPreferredLSDADataFormat - Return the preferred exception handling data +/// format for the LSDA. +unsigned X86TargetLowering::getPreferredLSDADataFormat() const { + if (Subtarget->isTargetDarwin()) + return dwarf::DW_EH_PE_pcrel; + + CodeModel::Model M = getTargetMachine().getCodeModel(); + + if (getTargetMachine().getRelocationModel() == Reloc::PIC_) { + if (!Subtarget->is64Bit() || M == CodeModel::Small) + return dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; + + return dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8; + } + + if (M == CodeModel::Small) + return dwarf::DW_EH_PE_sdata4; + + return dwarf::DW_EH_PE_absptr; +} + +/// getPreferredFDEDataFormat - Return the preferred exception handling data +/// format for the FDE. +unsigned X86TargetLowering::getPreferredFDEDataFormat() const { + if (Subtarget->isTargetDarwin()) + return dwarf::DW_EH_PE_pcrel; + + CodeModel::Model M = getTargetMachine().getCodeModel(); + + if (getTargetMachine().getRelocationModel() == Reloc::PIC_) { + if (!Subtarget->is64Bit() || + M == CodeModel::Small || M == CodeModel::Medium) + return dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; + + return dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8; + } + + if (M == CodeModel::Small || M == CodeModel::Medium) + return dwarf::DW_EH_PE_sdata4; + + return dwarf::DW_EH_PE_absptr; +} + //===----------------------------------------------------------------------===// // Return Value Calling Convention Implementation //===----------------------------------------------------------------------===// diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 1c612a13a25..64716e9d2c9 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -560,6 +560,14 @@ namespace llvm { /// getFunctionAlignment - Return the Log2 alignment of this function. virtual unsigned getFunctionAlignment(const Function *F) const; + /// getPreferredLSDADataFormat - Return the preferred exception handling data + /// format for the LSDA. + virtual unsigned getPreferredLSDADataFormat() const; + + /// getPreferredFDEDataFormat - Return the preferred exception handling data + /// format for the FDE. + virtual unsigned getPreferredFDEDataFormat() const; + private: /// Subtarget - Keep a pointer to the X86Subtarget around so that we can /// make the right decision when generating code for different targets.