[llvm-commits] [llvm] r76029 - in /llvm/trunk/lib/Target/SystemZ: SystemZInstrInfo.cpp SystemZInstrInfo.td SystemZRegisterInfo.cpp

Anton Korobeynikov asl at math.spbu.ru
Thu Jul 16 07:23:02 PDT 2009


Author: asl
Date: Thu Jul 16 09:23:01 2009
New Revision: 76029

URL: http://llvm.org/viewvc/llvm-project?rev=76029&view=rev
Log:
Handle FP callee-saved regs

Modified:
    llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.cpp
    llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td
    llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.cpp

Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.cpp?rev=76029&r1=76028&r2=76029&view=diff

==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.cpp Thu Jul 16 09:23:01 2009
@@ -186,50 +186,71 @@
 SystemZInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
                                            MachineBasicBlock::iterator MI,
                                 const std::vector<CalleeSavedInfo> &CSI) const {
+  if (CSI.empty())
+    return false;
+
   DebugLoc DL = DebugLoc::getUnknownLoc();
   if (MI != MBB.end()) DL = MI->getDebugLoc();
 
   MachineFunction &MF = *MBB.getParent();
   SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();
-  MFI->setCalleeSavedFrameSize(CSI.size() * 8);
+  unsigned CalleeFrameSize = 0;
 
   // Scan the callee-saved and find the bounds of register spill area.
   unsigned LowReg = 0, HighReg = 0, StartOffset = -1U, EndOffset = 0;
   for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
     unsigned Reg = CSI[i].getReg();
-    unsigned Offset = RegSpillOffsets[Reg];
-    if (StartOffset > Offset) {
-      LowReg = Reg; StartOffset = Offset;
-    }
-    if (EndOffset < Offset) {
-      HighReg = Reg; EndOffset = RegSpillOffsets[Reg];
+    const TargetRegisterClass *RegClass = CSI[i].getRegClass();
+    if (RegClass != &SystemZ::FP64RegClass) {
+      unsigned Offset = RegSpillOffsets[Reg];
+      CalleeFrameSize += 8;
+      if (StartOffset > Offset) {
+        LowReg = Reg; StartOffset = Offset;
+      }
+      if (EndOffset < Offset) {
+        HighReg = Reg; EndOffset = RegSpillOffsets[Reg];
+      }
     }
   }
 
   // Save information for epilogue inserter.
+  MFI->setCalleeSavedFrameSize(CalleeFrameSize);
   MFI->setLowReg(LowReg); MFI->setHighReg(HighReg);
 
-  // Build a store instruction. Use STORE MULTIPLE instruction if there are many
-  // registers to store, otherwise - just STORE.
-  MachineInstrBuilder MIB =
-    BuildMI(MBB, MI, DL, get((LowReg == HighReg ?
-                              SystemZ::MOV64mr : SystemZ::MOV64mrm)));
-
-  // Add store operands.
-  MIB.addReg(SystemZ::R15D).addImm(StartOffset);
-  if (LowReg == HighReg)
-    MIB.addReg(0);
-  MIB.addReg(LowReg, RegState::Kill);
-  if (LowReg != HighReg)
-    MIB.addReg(HighReg, RegState::Kill);
+  // Save GPRs
+  if (StartOffset) {
+    // Build a store instruction. Use STORE MULTIPLE instruction if there are many
+    // registers to store, otherwise - just STORE.
+    MachineInstrBuilder MIB =
+      BuildMI(MBB, MI, DL, get((LowReg == HighReg ?
+                                SystemZ::MOV64mr : SystemZ::MOV64mrm)));
+
+    // Add store operands.
+    MIB.addReg(SystemZ::R15D).addImm(StartOffset);
+    if (LowReg == HighReg)
+      MIB.addReg(0);
+    MIB.addReg(LowReg, RegState::Kill);
+    if (LowReg != HighReg)
+      MIB.addReg(HighReg, RegState::Kill);
+
+    // Do a second scan adding regs as being killed by instruction
+    for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+      unsigned Reg = CSI[i].getReg();
+      // Add the callee-saved register as live-in. It's killed at the spill.
+      MBB.addLiveIn(Reg);
+      if (Reg != LowReg && Reg != HighReg)
+        MIB.addReg(Reg, RegState::ImplicitKill);
+    }
+  }
 
-  // Do a second scan adding regs as being killed by instruction
+  // Save FPRs
   for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
     unsigned Reg = CSI[i].getReg();
-    // Add the callee-saved register as live-in. It's killed at the spill.
-    MBB.addLiveIn(Reg);
-    if (Reg != LowReg && Reg != HighReg)
-      MIB.addReg(Reg, RegState::ImplicitKill);
+    const TargetRegisterClass *RegClass = CSI[i].getRegClass();
+    if (RegClass == &SystemZ::FP64RegClass) {
+      MBB.addLiveIn(Reg);
+      storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(), RegClass);
+    }
   }
 
   return true;
@@ -249,29 +270,40 @@
   const TargetRegisterInfo *RegInfo= MF.getTarget().getRegisterInfo();
   SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();
 
+  // Restore FP registers
+  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+    unsigned Reg = CSI[i].getReg();
+    const TargetRegisterClass *RegClass = CSI[i].getRegClass();
+    if (RegClass == &SystemZ::FP64RegClass)
+      loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), RegClass);
+  }
+
+  // Restore GP registers
   unsigned LowReg = MFI->getLowReg(), HighReg = MFI->getHighReg();
   unsigned StartOffset = RegSpillOffsets[LowReg];
 
-  // Build a load instruction. Use LOAD MULTIPLE instruction if there are many
-  // registers to load, otherwise - just LOAD.
-  MachineInstrBuilder MIB =
-    BuildMI(MBB, MI, DL, get((LowReg == HighReg ?
-                              SystemZ::MOV64rm : SystemZ::MOV64rmm)));
-  // Add store operands.
-  MIB.addReg(LowReg, RegState::Define);
-  if (LowReg != HighReg)
-    MIB.addReg(HighReg, RegState::Define);
-
-  MIB.addReg((RegInfo->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D));
-  MIB.addImm(StartOffset);
-  if (LowReg == HighReg)
-    MIB.addReg(0);
-
-  // Do a second scan adding regs as being defined by instruction
-  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
-    unsigned Reg = CSI[i].getReg();
-    if (Reg != LowReg && Reg != HighReg)
-      MIB.addReg(Reg, RegState::ImplicitDefine);
+  if (StartOffset) {
+    // Build a load instruction. Use LOAD MULTIPLE instruction if there are many
+    // registers to load, otherwise - just LOAD.
+    MachineInstrBuilder MIB =
+      BuildMI(MBB, MI, DL, get((LowReg == HighReg ?
+                                SystemZ::MOV64rm : SystemZ::MOV64rmm)));
+    // Add store operands.
+    MIB.addReg(LowReg, RegState::Define);
+    if (LowReg != HighReg)
+      MIB.addReg(HighReg, RegState::Define);
+
+    MIB.addReg((RegInfo->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D));
+    MIB.addImm(StartOffset);
+    if (LowReg == HighReg)
+      MIB.addReg(0);
+
+    // Do a second scan adding regs as being defined by instruction
+    for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+      unsigned Reg = CSI[i].getReg();
+      if (Reg != LowReg && Reg != HighReg)
+        MIB.addReg(Reg, RegState::ImplicitDefine);
+    }
   }
 
   return true;

Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td?rev=76029&r1=76028&r2=76029&view=diff

==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td Thu Jul 16 09:23:01 2009
@@ -156,7 +156,8 @@
 let isCall = 1 in
   // All calls clobber the non-callee saved registers. Uses for argument
   // registers are added manually.
-  let Defs = [R0D, R1D, R2D, R3D, R4D, R5D, R14D] in {
+  let Defs = [R0D, R1D, R2D, R3D, R4D, R5D, R14D,
+              F0L, F1L, F2L, F3L, F4L, F5L, F6L, F7L] in {
     def CALLi     : Pseudo<(outs), (ins imm_pcrel:$dst, variable_ops),
                            "brasl\t%r14, $dst", [(SystemZcall imm:$dst)]>;
     def CALLr     : Pseudo<(outs), (ins ADDR64:$dst, variable_ops),

Modified: llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.cpp?rev=76029&r1=76028&r2=76029&view=diff

==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.cpp Thu Jul 16 09:23:01 2009
@@ -39,7 +39,8 @@
     SystemZ::R6D,  SystemZ::R7D,  SystemZ::R8D,  SystemZ::R9D,
     SystemZ::R10D, SystemZ::R11D, SystemZ::R12D, SystemZ::R13D,
     SystemZ::R14D, SystemZ::R15D,
-    SystemZ::F1L,  SystemZ::F3L,  SystemZ::F5L,  SystemZ::F7L,
+    SystemZ::F8L,  SystemZ::F9L,  SystemZ::F10L, SystemZ::F11L,
+    SystemZ::F12L, SystemZ::F13L, SystemZ::F14L, SystemZ::F15L,
     0
   };
 
@@ -55,6 +56,8 @@
     &SystemZ::GR64RegClass, &SystemZ::GR64RegClass,
     &SystemZ::GR64RegClass, &SystemZ::GR64RegClass,
     &SystemZ::FP64RegClass, &SystemZ::FP64RegClass,
+    &SystemZ::FP64RegClass, &SystemZ::FP64RegClass,
+    &SystemZ::FP64RegClass, &SystemZ::FP64RegClass,
     &SystemZ::FP64RegClass, &SystemZ::FP64RegClass, 0
   };
   return CalleeSavedRegClasses;
@@ -142,18 +145,33 @@
   // Determine whether R15/R14 will ever be clobbered inside the function. And
   // if yes - mark it as 'callee' saved.
   MachineFrameInfo *FFI = MF.getFrameInfo();
+  MachineRegisterInfo &MRI = MF.getRegInfo();
+
+  // Check whether high FPRs are ever used, if yes - we need to save R15 as
+  // well.
+  static const unsigned HighFPRs[] = {
+    SystemZ::F8L,  SystemZ::F9L,  SystemZ::F10L, SystemZ::F11L,
+    SystemZ::F12L, SystemZ::F13L, SystemZ::F14L, SystemZ::F15L,
+    SystemZ::F8S,  SystemZ::F9S,  SystemZ::F10S, SystemZ::F11S,
+    SystemZ::F12S, SystemZ::F13S, SystemZ::F14S, SystemZ::F15S,
+  };
+
+  bool HighFPRsUsed = false;
+  for (unsigned i = 0, e = array_lengthof(HighFPRs); i != e; ++i)
+    HighFPRsUsed |= MRI.isPhysRegUsed(HighFPRs[i]);
 
   if (FFI->hasCalls())
     /* FIXME: function is varargs */
     /* FIXME: function grabs RA */
     /* FIXME: function calls eh_return */
-    MF.getRegInfo().setPhysRegUsed(SystemZ::R14D);
+    MRI.setPhysRegUsed(SystemZ::R14D);
 
-  if (FFI->hasCalls() ||
+  if (HighFPRsUsed ||
+      FFI->hasCalls() ||
       FFI->getObjectIndexEnd() != 0 || // Contains automatic variables
       FFI->hasVarSizedObjects() // Function calls dynamic alloca's
       /* FIXME: function is varargs */)
-    MF.getRegInfo().setPhysRegUsed(SystemZ::R15D);
+    MRI.setPhysRegUsed(SystemZ::R15D);
 }
 
 /// emitSPUpdate - Emit a series of instructions to increment / decrement the





More information about the llvm-commits mailing list