[llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp

Chris Lattner lattner at cs.uiuc.edu
Thu Feb 2 15:29:48 PST 2006



Changes in directory llvm/lib/CodeGen:

VirtRegMap.cpp updated: 1.45 -> 1.46
---
Log message:

Fix a deficiency in the spiller that Evan noticed.  In particular, consider
this code:

  store [stack slot #0],  R10
    = add R14, [stack slot #0]

The spiller didn't know that the store made the value of [stackslot#0] available
in R10 *IF* the store came from a copy instruction with the store folded into it.

This patch teaches VirtRegMap to look at these stores and recognize the values
they make available.  In one case Evan provided, this code:

        divsd %XMM0, %XMM1
        movsd %XMM1, QWORD PTR [%ESP + 40]
1)      movsd QWORD PTR [%ESP + 48], %XMM1
2)      movsd %XMM1, QWORD PTR [%ESP + 48]
        addsd %XMM1, %XMM0
3)      movsd QWORD PTR [%ESP + 48], %XMM1
        movsd QWORD PTR [%ESP + 4], %XMM0

turns into:

        divsd %XMM0, %XMM1
        movsd %XMM1, QWORD PTR [%ESP + 40]
        addsd %XMM1, %XMM0
3)      movsd QWORD PTR [%ESP + 48], %XMM1
        movsd QWORD PTR [%ESP + 4], %XMM0

In this case, instruction #2 was removed because of the value made 
available by #1, and inst #1 was later deleted because it is now 
never used before the stack slot is redefined by #3.

This occurs here and there in a lot of code with high spilling, on PPC
most of the removed loads/stores are LSU-reject-causing loads, which is
nice.

On X86, things are much better (because it spills more), where we nuke
about 1% of the instructions from SMG2000 and several hundred from eon.

More improvements to come...





---
Diffs of the changes:  (+31 -1)

 VirtRegMap.cpp |   32 +++++++++++++++++++++++++++++++-
 1 files changed, 31 insertions(+), 1 deletion(-)


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.45 llvm/lib/CodeGen/VirtRegMap.cpp:1.46
--- llvm/lib/CodeGen/VirtRegMap.cpp:1.45	Thu Feb  2 14:12:13 2006
+++ llvm/lib/CodeGen/VirtRegMap.cpp	Thu Feb  2 17:29:36 2006
@@ -284,7 +284,7 @@
 void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
 
   // SpillSlotsAvailable - This map keeps track of all of the spilled virtual
-  // register values that are still available, due to being loaded to stored to,
+  // register values that are still available, due to being loaded or stored to,
   // but not invalidated yet.
   std::map<int, unsigned> SpillSlotsAvailable;
 
@@ -535,6 +535,36 @@
           PhysRegsAvailable.erase(It->second);
           SpillSlotsAvailable.erase(It);
         }
+        
+        // If this is *just* a mod of the value, check to see if this is just a
+        // store to the spill slot (i.e. the spill got merged into the copy). If
+        // so, realize that the vreg is available now, and add the store to the
+        // MaybeDeadStore info.
+        int StackSlot;
+        if (!(MR & VirtRegMap::isRef)) {
+          if (unsigned SrcReg = TII->isStoreToStackSlot(&MI, StackSlot)) {
+            assert(MRegisterInfo::isPhysicalRegister(SrcReg) &&
+                   "Src hasn't been allocated yet?");
+            // Okay, this is certainly a store of SrcReg to [FrameIdx].  Mark
+            // this as a potentially dead store in case there is a subsequent
+            // store into the stack slot without a read from it.
+            MaybeDeadStores[StackSlot] = &MI;
+
+            // FIXME: PhysRegsAvailable is a 1-1 map, not a N-1 map, which means
+            // that we have to *forget* that SrcReg contains the old value it
+            // does.
+            ClobberPhysRegOnly(SrcReg, SpillSlotsAvailable, PhysRegsAvailable);
+            
+            // If the stack slot value was previously available in some other
+            // register, change it now.  Otherwise, make the register available,
+            // in PhysReg.
+            SpillSlotsAvailable[StackSlot] = SrcReg;
+            PhysRegsAvailable[SrcReg] = StackSlot;
+            DEBUG(std::cerr << "Updating SS#" << StackSlot << " in physreg "
+                            << MRI->getName(SrcReg) << " for virtreg #"
+                            << VirtReg << "\n" << MI);
+          }
+        }
       }
     }
 






More information about the llvm-commits mailing list