Mark all PPC CR registers to be spilled as live-in and tag MFCR appropriately
authorHal Finkel <hfinkel@anl.gov>
Sat, 13 Apr 2013 23:06:15 +0000 (23:06 +0000)
committerHal Finkel <hfinkel@anl.gov>
Sat, 13 Apr 2013 23:06:15 +0000 (23:06 +0000)
Leaving MFCR has having unmodeled side effects is not enough to prevent
unwanted instruction reordering post-RA. We could probably apply a stronger
barrier attribute, but there is a better way: Add all (not just the first) CR
to be spilled as live-in to the entry block, and add all CRs to the MFCR
instruction as implicitly killed.

Unfortunately, I don't have a small test case.

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

lib/Target/PowerPC/PPCFrameLowering.cpp
lib/Target/PowerPC/PPCInstr64Bit.td
lib/Target/PowerPC/PPCInstrInfo.td

index 8541e1ba5cd8305cf2cd8eaf1bbd4dc35b730c53..535d31f5c6c31f70943e4214227fbc900d971360 100644 (file)
@@ -1122,18 +1122,21 @@ PPCFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
     *static_cast<const PPCInstrInfo*>(MF->getTarget().getInstrInfo());
   DebugLoc DL;
   bool CRSpilled = false;
+  MachineInstrBuilder CRMIB;
   
   for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
     unsigned Reg = CSI[i].getReg();
     // CR2 through CR4 are the nonvolatile CR fields.
     bool IsCRField = PPC::CR2 <= Reg && Reg <= PPC::CR4;
 
-    if (CRSpilled && IsCRField)
-      continue;
-
     // Add the callee-saved register as live-in; it's killed at the spill.
     MBB.addLiveIn(Reg);
 
+    if (CRSpilled && IsCRField) {
+      CRMIB.addReg(Reg, RegState::ImplicitKill);
+      continue;
+    }
+
     // Insert the spill to the stack frame.
     if (IsCRField) {
       CRSpilled = true;
@@ -1143,7 +1146,10 @@ PPCFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
        // 64-bit:  SP+8
         bool is31 = needsFP(*MF);
         unsigned FP8Reg = is31 ? PPC::X31 : PPC::X1;
-       MBB.insert(MI, BuildMI(*MF, DL, TII.get(PPC::MFCR8), PPC::X12));
+        CRMIB = BuildMI(*MF, DL, TII.get(PPC::MFCR8), PPC::X12)
+                  .addReg(Reg, RegState::ImplicitKill);
+
+       MBB.insert(MI, CRMIB);
        MBB.insert(MI, BuildMI(*MF, DL, TII.get(PPC::STW8))
                               .addReg(PPC::X12,
                                       getKillRegState(true))
@@ -1152,7 +1158,10 @@ PPCFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
       } else {
        // 32-bit:  FP-relative.  Note that we made sure CR2-CR4 all have
        // the same frame index in PPCRegisterInfo::hasReservedSpillSlot.
-       MBB.insert(MI, BuildMI(*MF, DL, TII.get(PPC::MFCR), PPC::R12));
+       CRMIB = BuildMI(*MF, DL, TII.get(PPC::MFCR), PPC::R12)
+                  .addReg(Reg, RegState::ImplicitKill);
+
+       MBB.insert(MI, CRMIB);
        MBB.insert(MI, addFrameReference(BuildMI(*MF, DL, TII.get(PPC::STW))
                                         .addReg(PPC::R12,
                                                 getKillRegState(true)),
index 88da067e2ac6254082119dcf98129ee9cd982f79..9bcd19a937dd5246280327574dd1f6ae8fa14396 100644 (file)
@@ -256,11 +256,7 @@ def MFCR8pseud: XFXForm_3<31, 19, (outs G8RC:$rT), (ins crbitm:$FXM),
             PPC970_MicroCode, PPC970_Unit_CRU;
 } // neverHasSideEffects = 1
 
-// MFCR uses all CR registers, but marking that explicitly causes
-// problems because some of them appear to be undefined. Because
-// this form is used only in prologue code, just mark it as having
-// side effects.
-let /* Uses = [CR0, CR1, CR2, CR3, CR4, CR5, CR6] */ hasSideEffects = 1 in
+let neverHasSideEffects = 1 in
 def MFCR8 : XFXForm_3<31, 19, (outs G8RC:$rT), (ins),
                      "mfcr $rT", SprMFCR>,
                      PPC970_MicroCode, PPC970_Unit_CRU;
index 73e2eed1cc40ec81aa04a6440dbd081770c0b0ec..993738457767b74d47053f9736aa1cd968f190a0 100644 (file)
@@ -1618,11 +1618,7 @@ def MFOCRF: XFXForm_5a<31, 19, (outs GPRC:$rT), (ins crbitm:$FXM),
             PPC970_DGroup_First, PPC970_Unit_CRU;
 } // neverHasSideEffects = 1
 
-// MFCR uses all CR registers, but marking that explicitly causes 
-// problems because some of them appear to be undefined. Because
-// this form is used only in prologue code, just mark it as having
-// side effects.
-let /* Uses = [CR0, CR1, CR2, CR3, CR4, CR5, CR6] */ hasSideEffects = 1 in
+let neverHasSideEffects = 1 in
 def MFCR : XFXForm_3<31, 19, (outs GPRC:$rT), (ins),
                      "mfcr $rT", SprMFCR>,
                      PPC970_MicroCode, PPC970_Unit_CRU;