[llvm-commits] [llvm] r39855 - in /llvm/trunk: include/llvm/ include/llvm/CodeGen/ include/llvm/Target/ lib/CodeGen/ lib/CodeGen/SelectionDAG/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/IA64/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/Target/X86/

Anton Korobeynikov asl at math.spbu.ru
Sat Jul 14 07:06:15 PDT 2007


Author: asl
Date: Sat Jul 14 09:06:15 2007
New Revision: 39855

URL: http://llvm.org/viewvc/llvm-project?rev=39855&view=rev
Log:
Long live the exception handling!

This patch fills the last necessary bits to enable exceptions
handling in LLVM. Currently only on x86-32/linux.

In fact, this patch adds necessary intrinsics (and their lowering) which
represent really weird target-specific gcc builtins used inside unwinder.

After corresponding llvm-gcc patch will land (easy) exceptions should be
more or less workable. However, exceptions handling support should not be 
thought as 'finished': I expect many small and not so small glitches
everywhere.

Modified:
    llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h
    llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
    llvm/trunk/include/llvm/Intrinsics.td
    llvm/trunk/include/llvm/Target/MRegisterInfo.h
    llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
    llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
    llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp
    llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h
    llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.cpp
    llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.h
    llvm/trunk/lib/Target/IA64/IA64RegisterInfo.cpp
    llvm/trunk/lib/Target/IA64/IA64RegisterInfo.h
    llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp
    llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h
    llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.cpp
    llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.h
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
    llvm/trunk/lib/Target/X86/X86ISelLowering.h
    llvm/trunk/lib/Target/X86/X86InstrInfo.td
    llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp
    llvm/trunk/lib/Target/X86/X86RegisterInfo.h
    llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp

Modified: llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h Sat Jul 14 09:06:15 2007
@@ -1030,6 +1030,9 @@
   // Personalities - Vector of all personality functions ever seen. Used to emit
   // common EH frames.
   std::vector<Function *> Personalities;
+
+  bool CallsEHReturn;
+  bool CallsUnwindInit;
 public:
   static char ID; // Pass identification, replacement for typeid
 
@@ -1072,6 +1075,12 @@
   /// needsFrameInfo - Returns true if we need to gather callee-saved register
   /// move info for the frame.
   bool needsFrameInfo() const;
+
+  bool callsEHReturn() const { return CallsEHReturn; }
+  void setCallsEHReturn(bool b) { CallsEHReturn = b; }
+
+  bool callsUnwindInit() const { return CallsUnwindInit; }
+  void setCallsUnwindInit(bool b) { CallsUnwindInit = b; }
   
   /// NextLabelID - Return the next unique label id.
   ///

Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Sat Jul 14 09:06:15 2007
@@ -110,6 +110,11 @@
     // to the current function's frame or return address, an index of one to the
     // parent's frame or return address, and so on.
     FRAMEADDR, RETURNADDR,
+
+    // FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to
+    // first (possible) on-stack argument. This is needed for correct stack
+    // adjustment during unwind.
+    FRAME_TO_ARGS_OFFSET,
     
     // RESULT, OUTCHAIN = EXCEPTIONADDR(INCHAIN) - This node represents the
     // address of the exception block on entry to an landing pad block.
@@ -119,6 +124,12 @@
     // the selection index of the exception thrown.
     EHSELECTION,
 
+    // OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents
+    // 'eh_return' gcc dwarf builtin, which is used to return from
+    // exception. The general meaning is: adjust stack by OFFSET and pass
+    // execution to HANDLER. Many platform-related details also :)
+    EH_RETURN,
+
     // TargetConstant* - Like Constant*, but the DAG does not do any folding or
     // simplification of the constant.
     TargetConstant,

Modified: llvm/trunk/include/llvm/Intrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Intrinsics.td (original)
+++ llvm/trunk/include/llvm/Intrinsics.td Sat Jul 14 09:06:15 2007
@@ -233,6 +233,14 @@
                                                 llvm_vararg_ty]>;
 def int_eh_typeid_for : Intrinsic<[llvm_i32_ty, llvm_ptr_ty]>;
 
+def int_eh_return     : Intrinsic<[llvm_void_ty, llvm_i32_ty, llvm_ptr_ty]>,
+                        GCCBuiltin<"__builtin_eh_return">;
+
+def int_eh_unwind_init: Intrinsic<[llvm_void_ty]>,
+                        GCCBuiltin<"__builtin_unwind_init">;
+
+def int_eh_dwarf_cfa  : Intrinsic<[llvm_ptr_ty, llvm_i32_ty]>;
+
 //===---------------- Generic Variable Attribute Intrinsics----------------===//
 //
 def int_var_annotation : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,

Modified: llvm/trunk/include/llvm/Target/MRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/MRegisterInfo.h?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/MRegisterInfo.h (original)
+++ llvm/trunk/include/llvm/Target/MRegisterInfo.h Sat Jul 14 09:06:15 2007
@@ -396,12 +396,14 @@
   /// callee saved registers on this target. The register should be in the
   /// order of desired callee-save stack frame offset. The first register is
   /// closed to the incoming stack pointer if stack grows down, and vice versa.
-  virtual const unsigned* getCalleeSavedRegs() const = 0;
+  virtual const unsigned* getCalleeSavedRegs(const MachineFunction *MF = 0)
+                                                                      const = 0;
 
   /// getCalleeSavedRegClasses - Return a null-terminated list of the preferred
   /// register classes to spill each callee saved register with.  The order and
   /// length of this list match the getCalleeSaveRegs() list.
-  virtual const TargetRegisterClass* const *getCalleeSavedRegClasses() const =0;
+  virtual const TargetRegisterClass* const *getCalleeSavedRegClasses(
+                                            const MachineFunction *MF) const =0;
 
   /// getReservedRegs - Returns a bitset indexed by physical register number
   /// indicating if a register is a special register that has particular uses and

Modified: llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp Sat Jul 14 09:06:15 2007
@@ -1476,6 +1476,8 @@
 , FrameMoves()
 , LandingPads()
 , Personalities()
+, CallsEHReturn(0)
+, CallsUnwindInit(0)
 {
   // Always emit "no personality" info
   Personalities.push_back(NULL);
@@ -1523,6 +1525,8 @@
   TypeInfos.clear();
   FilterIds.clear();
   FilterEnds.clear();
+  CallsEHReturn = 0;
+  CallsUnwindInit = 0;
 }
 
 /// getDescFor - Convert a Value to a debug information descriptor.

Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp (original)
+++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp Sat Jul 14 09:06:15 2007
@@ -121,7 +121,7 @@
   const TargetFrameInfo *TFI = Fn.getTarget().getFrameInfo();
 
   // Get the callee saved register list...
-  const unsigned *CSRegs = RegInfo->getCalleeSavedRegs();
+  const unsigned *CSRegs = RegInfo->getCalleeSavedRegs(&Fn);
 
   // Get the function call frame set-up and tear-down instruction opcode
   int FrameSetupOpcode   = RegInfo->getCallFrameSetupOpcode();
@@ -170,7 +170,7 @@
   // function, thus needing to be saved and restored in the prolog/epilog.
   //
   const TargetRegisterClass* const *CSRegClasses =
-    RegInfo->getCalleeSavedRegClasses();
+    RegInfo->getCalleeSavedRegClasses(&Fn);
   std::vector<CalleeSavedInfo> CSI;
   for (unsigned i = 0; CSRegs[i]; ++i) {
     unsigned Reg = CSRegs[i];

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sat Jul 14 09:06:15 2007
@@ -640,6 +640,7 @@
     break;
   case ISD::FRAMEADDR:
   case ISD::RETURNADDR:
+  case ISD::FRAME_TO_ARGS_OFFSET:
     // The only option for these nodes is to custom lower them.  If the target
     // does not custom lower them, then return zero.
     Tmp1 = TLI.LowerOperation(Op, DAG);
@@ -695,6 +696,21 @@
     }
     }
     break;
+  case ISD::EH_RETURN:
+    MVT::ValueType VT = Node->getValueType(0);
+    // The only "good" option for this node is to custom lower it.
+    switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
+    default: assert(0 && "This action is not supported at all!");
+    case TargetLowering::Custom:
+      Result = TLI.LowerOperation(Op, DAG);
+      if (Result.Val) break;
+      // Fall Thru
+    case TargetLowering::Legal:
+      // Target does not know, how to lower this, lower to noop
+      Result = LegalizeOp(Node->getOperand(0));
+      break;
+    }
+    break;
   case ISD::AssertSext:
   case ISD::AssertZext:
     Tmp1 = LegalizeOp(Node->getOperand(0));

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Jul 14 09:06:15 2007
@@ -3369,8 +3369,10 @@
   case ISD::GLOBAL_OFFSET_TABLE: return "GLOBAL_OFFSET_TABLE";
   case ISD::RETURNADDR: return "RETURNADDR";
   case ISD::FRAMEADDR: return "FRAMEADDR";
+  case ISD::FRAME_TO_ARGS_OFFSET: return "FRAME_TO_ARGS_OFFSET";
   case ISD::EXCEPTIONADDR: return "EXCEPTIONADDR";
   case ISD::EHSELECTION: return "EHSELECTION";
+  case ISD::EH_RETURN: return "EH_RETURN";
   case ISD::ConstantPool:  return "ConstantPool";
   case ISD::ExternalSymbol: return "ExternalSymbol";
   case ISD::INTRINSIC_WO_CHAIN: {

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Sat Jul 14 09:06:15 2007
@@ -2721,6 +2721,53 @@
     return 0;
   }
 
+  case Intrinsic::eh_return: {
+    MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+
+    if (MMI && ExceptionHandling) {
+      MMI->setCallsEHReturn(true);
+      DAG.setRoot(DAG.getNode(ISD::EH_RETURN,
+                              MVT::Other,
+                              getRoot(),
+                              getValue(I.getOperand(1)),
+                              getValue(I.getOperand(2))));
+    } else {
+      setValue(&I, DAG.getConstant(0, TLI.getPointerTy()));
+    }
+
+    return 0;
+  }
+
+   case Intrinsic::eh_unwind_init: {    
+     if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo()) {
+       MMI->setCallsUnwindInit(true);
+     }
+
+     return 0;
+   }
+
+   case Intrinsic::eh_dwarf_cfa: {
+     if (ExceptionHandling) {
+       MVT::ValueType VT = getValue(I.getOperand(1)).getValueType();
+       SDOperand Offset = DAG.getNode(ISD::ADD,
+                                      TLI.getPointerTy(),
+                                      DAG.getNode(ISD::FRAME_TO_ARGS_OFFSET,
+                                                  VT),
+                                      getValue(I.getOperand(1)));
+       setValue(&I, DAG.getNode(ISD::ADD,
+                                TLI.getPointerTy(),
+                                DAG.getNode(ISD::FRAMEADDR,
+                                            TLI.getPointerTy(),
+                                            DAG.getConstant(0,
+                                                            TLI.getPointerTy())),
+                                Offset));
+     } else {
+       setValue(&I, DAG.getConstant(0, TLI.getPointerTy()));
+     }
+
+     return 0;
+  }
+
   case Intrinsic::sqrt_f32:
   case Intrinsic::sqrt_f64:
     setValue(&I, DAG.getNode(ISD::FSQRT,

Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Sat Jul 14 09:06:15 2007
@@ -327,7 +327,8 @@
   return NewMI;
 }
 
-const unsigned* ARMRegisterInfo::getCalleeSavedRegs() const {
+const unsigned* ARMRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
+                                                                         const {
   static const unsigned CalleeSavedRegs[] = {
     ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8,
     ARM::R7, ARM::R6,  ARM::R5,  ARM::R4,
@@ -349,7 +350,7 @@
 }
 
 const TargetRegisterClass* const *
-ARMRegisterInfo::getCalleeSavedRegClasses() const {
+ARMRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
   static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
     &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
     &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,

Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h Sat Jul 14 09:06:15 2007
@@ -66,9 +66,10 @@
   MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum,
                                   int FrameIndex) const;
 
-  const unsigned *getCalleeSavedRegs() const;
+  const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) const;
 
-  const TargetRegisterClass* const* getCalleeSavedRegClasses() const;
+  const TargetRegisterClass* const* getCalleeSavedRegClasses(
+                                     const MachineFunction *MF = 0) const;
 
   BitVector getReservedRegs(const MachineFunction &MF) const;
 

Modified: llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.cpp?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.cpp Sat Jul 14 09:06:15 2007
@@ -164,7 +164,8 @@
   MBB.insert(I, MI);
 }
 
-const unsigned* AlphaRegisterInfo::getCalleeSavedRegs() const {
+const unsigned* AlphaRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
+                                                                         const {
   static const unsigned CalleeSavedRegs[] = {
     Alpha::R9, Alpha::R10,
     Alpha::R11, Alpha::R12,
@@ -178,7 +179,7 @@
 }
 
 const TargetRegisterClass* const*
-AlphaRegisterInfo::getCalleeSavedRegClasses() const {
+AlphaRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
   static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
     &Alpha::GPRCRegClass, &Alpha::GPRCRegClass,
     &Alpha::GPRCRegClass, &Alpha::GPRCRegClass,

Modified: llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.h?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.h (original)
+++ llvm/trunk/lib/Target/Alpha/AlphaRegisterInfo.h Sat Jul 14 09:06:15 2007
@@ -48,9 +48,10 @@
   void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
                      unsigned DestReg, const MachineInstr *Orig) const;
 
-  const unsigned *getCalleeSavedRegs() const;
+  const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) const;
 
-  const TargetRegisterClass* const* getCalleeSavedRegClasses() const;
+  const TargetRegisterClass* const* getCalleeSavedRegClasses(
+                                     const MachineFunction *MF = 0) const;
 
   BitVector getReservedRegs(const MachineFunction &MF) const;
 

Modified: llvm/trunk/lib/Target/IA64/IA64RegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/IA64RegisterInfo.cpp?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/IA64/IA64RegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/IA64/IA64RegisterInfo.cpp Sat Jul 14 09:06:15 2007
@@ -102,7 +102,8 @@
   MBB.insert(I, MI);
 }
 
-const unsigned* IA64RegisterInfo::getCalleeSavedRegs() const {
+const unsigned* IA64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
+                                                                         const {
   static const unsigned CalleeSavedRegs[] = {
     IA64::r5,  0
   };
@@ -110,7 +111,7 @@
 }
 
 const TargetRegisterClass* const*
-IA64RegisterInfo::getCalleeSavedRegClasses() const {
+IA64RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
   static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
     &IA64::GRRegClass,  0
   };

Modified: llvm/trunk/lib/Target/IA64/IA64RegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/IA64RegisterInfo.h?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/IA64/IA64RegisterInfo.h (original)
+++ llvm/trunk/lib/Target/IA64/IA64RegisterInfo.h Sat Jul 14 09:06:15 2007
@@ -47,9 +47,10 @@
   void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
                      unsigned DestReg, const MachineInstr *Orig) const;
 
-  const unsigned *getCalleeSavedRegs() const;
+  const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) const;
 
-  const TargetRegisterClass* const* getCalleeSavedRegClasses() const;
+  const TargetRegisterClass* const* getCalleeSavedRegClasses(
+                                     const MachineFunction *MF = 0) const;
 
   BitVector getReservedRegs(const MachineFunction &MF) const;
 

Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp Sat Jul 14 09:06:15 2007
@@ -248,7 +248,8 @@
   MBB.insert(I, MI);
 }
 
-const unsigned* PPCRegisterInfo::getCalleeSavedRegs() const {
+const unsigned* PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
+                                                                         const {
   // 32-bit Darwin calling convention. 
   static const unsigned Macho32_CalleeSavedRegs[] = {
               PPC::R13, PPC::R14, PPC::R15,
@@ -324,7 +325,7 @@
 }
 
 const TargetRegisterClass* const*
-PPCRegisterInfo::getCalleeSavedRegClasses() const {
+PPCRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
   // 32-bit Macho calling convention. 
   static const TargetRegisterClass * const Macho32_CalleeSavedRegClasses[] = {
                        &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,

Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.h Sat Jul 14 09:06:15 2007
@@ -57,9 +57,10 @@
   virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum,
                                           int FrameIndex) const;
   
-  const unsigned *getCalleeSavedRegs() const;
+  const unsigned *getCalleeSavedRegs(const MachineFunction* MF = 0) const;
 
-  const TargetRegisterClass* const* getCalleeSavedRegClasses() const;
+  const TargetRegisterClass* const* getCalleeSavedRegClasses(
+                                     const MachineFunction *MF = 0) const;
 
   BitVector getReservedRegs(const MachineFunction &MF) const;
 

Modified: llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.cpp?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.cpp Sat Jul 14 09:06:15 2007
@@ -121,7 +121,8 @@
   return NewMI;
 }
 
-const unsigned* SparcRegisterInfo::getCalleeSavedRegs() const {
+const unsigned* SparcRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
+                                                                         const {
   static const unsigned CalleeSavedRegs[] = { 0 };
   return CalleeSavedRegs;
 }
@@ -143,7 +144,7 @@
 
 
 const TargetRegisterClass* const*
-SparcRegisterInfo::getCalleeSavedRegClasses() const {
+SparcRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
   static const TargetRegisterClass * const CalleeSavedRegClasses[] = { 0 };
   return CalleeSavedRegClasses;
 }

Modified: llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.h?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.h (original)
+++ llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.h Sat Jul 14 09:06:15 2007
@@ -51,9 +51,10 @@
                                           unsigned OpNum,
                                           int FrameIndex) const;
 
-  const unsigned *getCalleeSavedRegs() const;
+  const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) const;
 
-  const TargetRegisterClass* const* getCalleeSavedRegClasses() const;
+  const TargetRegisterClass* const* getCalleeSavedRegClasses(
+                                     const MachineFunction *MF = 0) const;
 
   BitVector getReservedRegs(const MachineFunction &MF) const;
 

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sat Jul 14 09:06:15 2007
@@ -42,6 +42,8 @@
   X86ScalarSSE = Subtarget->hasSSE2();
   X86StackPtr = Subtarget->is64Bit() ? X86::RSP : X86::ESP;
 
+  RegInfo = TM.getRegisterInfo();
+
   // Set up the TargetLowering object.
 
   // X86 is weird, it always uses i8 for shift amounts and setcc results.
@@ -197,6 +199,9 @@
   }
   // X86 ret instruction may pop stack.
   setOperationAction(ISD::RET             , MVT::Other, Custom);
+  if (!Subtarget->is64Bit())
+    setOperationAction(ISD::EH_RETURN       , MVT::Other, Custom);
+
   // Darwin ABI issue.
   setOperationAction(ISD::ConstantPool    , MVT::i32  , Custom);
   setOperationAction(ISD::JumpTable       , MVT::i32  , Custom);
@@ -4226,6 +4231,39 @@
                      DAG.getConstant(4, getPointerTy()));
 }
 
+SDOperand X86TargetLowering::LowerFRAME_TO_ARGS_OFFSET(SDOperand Op,
+                                                       SelectionDAG &DAG) {
+  // Is not yet supported on x86-64
+  if (Subtarget->is64Bit())
+    return SDOperand();
+  
+  return DAG.getConstant(8, getPointerTy());
+}
+
+SDOperand X86TargetLowering::LowerEH_RETURN(SDOperand Op, SelectionDAG &DAG)
+{
+  assert(!Subtarget->is64Bit() &&
+         "Lowering of eh_return builtin is not supported yet on x86-64");
+    
+  MachineFunction &MF = DAG.getMachineFunction();
+  SDOperand Chain     = Op.getOperand(0);
+  SDOperand Offset    = Op.getOperand(1);
+  SDOperand Handler   = Op.getOperand(2);
+
+  SDOperand Frame = DAG.getRegister(RegInfo->getFrameRegister(MF),
+                                    getPointerTy());
+
+  SDOperand StoreAddr = DAG.getNode(ISD::SUB, getPointerTy(), Frame,
+                                    DAG.getConstant(-4UL, getPointerTy()));
+  StoreAddr = DAG.getNode(ISD::ADD, getPointerTy(), StoreAddr, Offset);
+  Chain = DAG.getStore(Chain, Handler, StoreAddr, NULL, 0);
+  Chain = DAG.getCopyToReg(Chain, X86::ECX, StoreAddr);
+  MF.addLiveOut(X86::ECX);
+
+  return DAG.getNode(X86ISD::EH_RETURN, MVT::Other,
+                     Chain, DAG.getRegister(X86::ECX, getPointerTy()));
+}
+
 /// LowerOperation - Provide custom lowering hooks for some operations.
 ///
 SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
@@ -4263,7 +4301,10 @@
   case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
   case ISD::RETURNADDR:         return LowerRETURNADDR(Op, DAG);
   case ISD::FRAMEADDR:          return LowerFRAMEADDR(Op, DAG);
+  case ISD::FRAME_TO_ARGS_OFFSET:
+                                return LowerFRAME_TO_ARGS_OFFSET(Op, DAG);
   case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
+  case ISD::EH_RETURN:          return LowerEH_RETURN(Op, DAG);
   }
   return SDOperand();
 }
@@ -4311,6 +4352,7 @@
   case X86ISD::FRCP:               return "X86ISD::FRCP";
   case X86ISD::TLSADDR:            return "X86ISD::TLSADDR";
   case X86ISD::THREAD_POINTER:     return "X86ISD::THREAD_POINTER";
+  case X86ISD::EH_RETURN:          return "X86ISD::EH_RETURN";
   }
 }
 

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Sat Jul 14 09:06:15 2007
@@ -16,6 +16,7 @@
 #define X86ISELLOWERING_H
 
 #include "X86Subtarget.h"
+#include "X86RegisterInfo.h"
 #include "llvm/Target/TargetLowering.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 
@@ -184,7 +185,10 @@
       FRSQRT, FRCP,
 
       // Thread Local Storage
-      TLSADDR, THREAD_POINTER
+      TLSADDR, THREAD_POINTER,
+
+      // Exception Handling helpers
+      EH_RETURN
     };
   }
 
@@ -370,6 +374,7 @@
     /// Subtarget - Keep a pointer to the X86Subtarget around so that we can
     /// make the right decision when generating code for different targets.
     const X86Subtarget *Subtarget;
+    const MRegisterInfo *RegInfo;
 
     /// X86StackPtr - X86 physical register used as stack ptr.
     unsigned X86StackPtr;
@@ -424,6 +429,8 @@
     SDOperand LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerRETURNADDR(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG);
+    SDOperand LowerFRAME_TO_ARGS_OFFSET(SDOperand Op, SelectionDAG &DAG);
+    SDOperand LowerEH_RETURN(SDOperand Op, SelectionDAG &DAG);
   };
 }
 

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Sat Jul 14 09:06:15 2007
@@ -51,6 +51,8 @@
 
 def SDT_X86TLSTP : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
 
+def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
+
 def X86shld    : SDNode<"X86ISD::SHLD",     SDTIntShiftDOp>;
 def X86shrd    : SDNode<"X86ISD::SHRD",     SDTIntShiftDOp>;
 
@@ -95,6 +97,9 @@
                         [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
 def X86TLStp : SDNode<"X86ISD::THREAD_POINTER", SDT_X86TLSTP, []>;
 
+def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
+                        [SDNPHasChain]>;
+
 
 //===----------------------------------------------------------------------===//
 // X86 Operand Definitions.
@@ -2492,6 +2497,17 @@
                       (i32 imm:$file))]>;
 
 //===----------------------------------------------------------------------===//
+// EH Pseudo Instructions
+//
+let isTerminator = 1, isReturn = 1, isBarrier = 1,
+    hasCtrlDep = 1, noResults = 1 in {
+def EH_RETURN   : I<0xC3, RawFrm, (ops GR32:$addr),
+                    "ret #eh_return, addr: $addr",
+                    [(X86ehret GR32:$addr)]>;
+
+}
+
+//===----------------------------------------------------------------------===//
 // Non-Instruction Patterns
 //===----------------------------------------------------------------------===//
 

Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Sat Jul 14 09:06:15 2007
@@ -903,30 +903,62 @@
 }
 
 
-const unsigned *X86RegisterInfo::getCalleeSavedRegs() const {
+const unsigned *X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
+                                                                         const {
   static const unsigned CalleeSavedRegs32Bit[] = {
     X86::ESI, X86::EDI, X86::EBX, X86::EBP,  0
   };
+
+  static const unsigned CalleeSavedRegs32EHRet[] = {
+    X86::EAX, X86::EDX, X86::ESI, X86::EDI, X86::EBX, X86::EBP,  0
+  };
+
   static const unsigned CalleeSavedRegs64Bit[] = {
     X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
   };
 
-  return Is64Bit ? CalleeSavedRegs64Bit : CalleeSavedRegs32Bit;
+  if (Is64Bit)
+    return CalleeSavedRegs64Bit;
+  else {
+    if (MF) {
+        MachineFrameInfo *MFI = MF->getFrameInfo();
+        MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
+        if (MMI && MMI->callsEHReturn())
+          return CalleeSavedRegs32EHRet;
+    }
+    return CalleeSavedRegs32Bit;
+  }
 }
 
 const TargetRegisterClass* const*
-X86RegisterInfo::getCalleeSavedRegClasses() const {
+X86RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
   static const TargetRegisterClass * const CalleeSavedRegClasses32Bit[] = {
     &X86::GR32RegClass, &X86::GR32RegClass,
     &X86::GR32RegClass, &X86::GR32RegClass,  0
   };
+  static const TargetRegisterClass * const CalleeSavedRegClasses32EHRet[] = {
+    &X86::GR32RegClass, &X86::GR32RegClass,
+    &X86::GR32RegClass, &X86::GR32RegClass,
+    &X86::GR32RegClass, &X86::GR32RegClass,  0
+  };
   static const TargetRegisterClass * const CalleeSavedRegClasses64Bit[] = {
     &X86::GR64RegClass, &X86::GR64RegClass,
     &X86::GR64RegClass, &X86::GR64RegClass,
     &X86::GR64RegClass, &X86::GR64RegClass, 0
   };
 
-  return Is64Bit ? CalleeSavedRegClasses64Bit : CalleeSavedRegClasses32Bit;
+  if (Is64Bit)
+    return CalleeSavedRegClasses64Bit;
+  else {
+    if (MF) {
+        MachineFrameInfo *MFI = MF->getFrameInfo();
+        MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
+        if (MMI && MMI->callsEHReturn())
+          return CalleeSavedRegClasses32EHRet;
+    }
+    return CalleeSavedRegClasses32Bit;
+  }
+
 }
 
 BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
@@ -953,9 +985,13 @@
 // if frame pointer elimination is disabled.
 //
 bool X86RegisterInfo::hasFP(const MachineFunction &MF) const {
+  MachineFrameInfo *MFI = MF.getFrameInfo();
+  MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
+
   return (NoFramePointerElim || 
           MF.getFrameInfo()->hasVarSizedObjects() ||
-          MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer());
+          MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() ||
+          (MMI && MMI->callsUnwindInit()));
 }
 
 void X86RegisterInfo::
@@ -1243,10 +1279,12 @@
                                    MachineBasicBlock &MBB) const {
   const MachineFrameInfo *MFI = MF.getFrameInfo();
   MachineBasicBlock::iterator MBBI = prior(MBB.end());
+  unsigned RetOpcode = MBBI->getOpcode();
 
-  switch (MBBI->getOpcode()) {
+  switch (RetOpcode) {
   case X86::RET:
   case X86::RETI:
+  case X86::EH_RETURN:
   case X86::TAILJMPd:
   case X86::TAILJMPr:
   case X86::TAILJMPm: break;  // These are ok
@@ -1288,6 +1326,14 @@
         emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII);
     }
   }
+
+  // We're returning from function via eh_return.
+  if (RetOpcode == X86::EH_RETURN) {
+    MachineOperand &DestAddr  = MBBI->getOperand(0);
+    assert(DestAddr.isReg() && "Offset should be in register!");
+    BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),StackPtr).
+      addReg(DestAddr.getReg());
+  }
 }
 
 unsigned X86RegisterInfo::getRARegister() const {

Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.h?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86RegisterInfo.h (original)
+++ llvm/trunk/lib/Target/X86/X86RegisterInfo.h Sat Jul 14 09:06:15 2007
@@ -74,12 +74,13 @@
 
   /// getCalleeSavedRegs - Return a null-terminated list of all of the
   /// callee-save registers on this target.
-  const unsigned *getCalleeSavedRegs() const;
+  const unsigned *getCalleeSavedRegs(const MachineFunction* MF = 0) const;
 
   /// getCalleeSavedRegClasses - Return a null-terminated list of the preferred
   /// register classes to spill each callee-saved register with.  The order and
   /// length of this list match the getCalleeSavedRegs() list.
-  const TargetRegisterClass* const* getCalleeSavedRegClasses() const;
+  const TargetRegisterClass* const* getCalleeSavedRegClasses(
+                                     const MachineFunction *MF = 0) const;
 
   /// getReservedRegs - Returns a bitset indexed by physical register number
   /// indicating if a register is a special register that has particular uses and

Modified: llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp?rev=39855&r1=39854&r2=39855&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Sat Jul 14 09:06:15 2007
@@ -124,8 +124,9 @@
     DwarfARangesSection = "\t.section\t.debug_aranges,\"\", at progbits";
     DwarfRangesSection =  "\t.section\t.debug_ranges,\"\", at progbits";
     DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"\", at progbits";
-    
-    SupportsExceptionHandling = true;
+
+    if (!Subtarget->is64Bit())
+      SupportsExceptionHandling = true;
     DwarfEHFrameSection = "\t.section\t.eh_frame,\"aw\", at progbits";
     DwarfExceptionSection = "\t.section\t.gcc_except_table,\"a\", at progbits";
     break;





More information about the llvm-commits mailing list