- Add target lowering methods to get the preferred format for the FDE and LSDA
authorBill Wendling <isanbard@gmail.com>
Sat, 29 Aug 2009 12:20:54 +0000 (12:20 +0000)
committerBill Wendling <isanbard@gmail.com>
Sat, 29 Aug 2009 12:20:54 +0000 (12:20 +0000)
  encodings.
- Make some of the values emitted by the FDEs dependent upon the pointer
  size. This is in line with how GCC does things. And it has the benefit of
  working for Darwin in 64-bit mode now.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80428 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetLowering.h
lib/CodeGen/AsmPrinter/DwarfException.cpp
lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/PowerPC/PPCISelLowering.h
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h

index 00a455c36091270a7f5381e20cacf33c82c1e195..a899651dbdfae2f87d37322044a785bd4085fc2e 100644 (file)
@@ -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 <climits>
 #include <map>
@@ -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
   //
index a8d8bfd7590e42f3355a719fac9832cc02c50e95..e32447392f45a61c3192c7e62c85511613303e11 100644 (file)
@@ -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();
 }
index ad9bbe1d311fbe500f892ace72d27148139e1d35..1f51d0485972aefd88ca94c26df527618dccf137 100644 (file)
@@ -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<PPCSubtarget>().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<PPCSubtarget>().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.
 //===----------------------------------------------------------------------===//
index 19fef4da0b417366ba23d67b9b1cfc6c3ad94246..9e5e36ad14e9bbf8c7a711705955d43cf9528627 100644 (file)
@@ -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;
index 15af42e8c48da43597f8ec0db2b7452870dace19..3600987f26a624ba6d80f3213bd939666f58c2dd 100644 (file)
@@ -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
 //===----------------------------------------------------------------------===//
index 1c612a13a25c847ee1c87a6fb1bc362510773a63..64716e9d2c98740bb16238d28bee3355bfa4cf6a 100644 (file)
@@ -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.