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

Chris Lattner lattner at cs.uiuc.edu
Tue Feb 17 02:10:27 PST 2004


Changes in directory llvm/lib/CodeGen:

RegAllocLocal.cpp updated: 1.49 -> 1.50

---
Log message:

Add support to the local allocator for fusing spill code into the instructions
that need them.  This is very useful on CISCy targets like the X86 because it
reduces the total spill pressure, and makes better use of it's (large) 
instruction set.  Though the X86 backend doesn't know how to rewrite many 
instructions yet, this already makes a substantial difference on 176.gcc for 
example:

Before:
Time:
   8.0099 ( 31.2%)   0.0100 ( 12.5%)   8.0199 ( 31.2%)   7.7186 ( 30.0%)  Local Register Allocator

Code quality:
734559 asm-printer           - Number of machine instrs printed
111395 ra-local              - Number of registers reloaded
 79902 ra-local              - Number of registers spilled
231554 x86-peephole          - Number of peephole optimization performed

After:
Time:
   7.8700 ( 30.6%)   0.0099 ( 19.9%)   7.8800 ( 30.6%)   7.7892 ( 30.2%)  Local Register Allocator
Code quality:
733083 asm-printer           - Number of machine instrs printed
  2379 ra-local              - Number of reloads fused into instructions
109046 ra-local              - Number of registers reloaded
 79881 ra-local              - Number of registers spilled
230658 x86-peephole          - Number of peephole optimization performed

So by fusing 2300 instructions, we reduced the  static number of instructions 
by 1500, and reduces the number of peepholes (and thus the work) by about 900.
This also clearly reduces the number of reload/spill instructions that are 
emitted.




---
Diffs of the changes:  (+13 -11)

Index: llvm/lib/CodeGen/RegAllocLocal.cpp
diff -u llvm/lib/CodeGen/RegAllocLocal.cpp:1.49 llvm/lib/CodeGen/RegAllocLocal.cpp:1.50
--- llvm/lib/CodeGen/RegAllocLocal.cpp:1.49	Tue Feb 17 01:02:17 2004
+++ llvm/lib/CodeGen/RegAllocLocal.cpp	Tue Feb 17 02:09:40 2004
@@ -30,6 +30,7 @@
 namespace {
   Statistic<> NumSpilled ("ra-local", "Number of registers spilled");
   Statistic<> NumReloaded("ra-local", "Number of registers reloaded");
+  Statistic<> NumFused   ("ra-local", "Number of reloads fused into instructions");
   cl::opt<bool> DisableKill("disable-kill", cl::Hidden,
                             cl::desc("Disable register kill in local-ra"));
 
@@ -491,14 +492,16 @@
   // If we have registers available to hold the value, use them.
   const TargetRegisterClass *RC = MF->getSSARegMap()->getRegClass(VirtReg);
   unsigned PhysReg = getFreeReg(RC);
+  int FrameIndex = getStackSpaceFor(VirtReg, RC);
 
-  if (PhysReg) {  // PhysReg available!
-    PhysReg = getReg(MBB, MI, VirtReg);
-  } else {  // No registers available...
-    /// If we can fold this spill into this instruction, do so now.
-    if (0) {
-      // TODO
-      return MI;
+  if (PhysReg) {   // Register is available, allocate it!
+    assignVirtToPhysReg(VirtReg, PhysReg);
+  } else {         // No registers available.
+    // If we can fold this spill into this instruction, do so now.
+    MachineBasicBlock::iterator MII = MI;
+    if (RegInfo->foldMemoryOperand(MII, OpNum, FrameIndex)) {
+      ++NumFused;
+      return MII;
     }
 
     // It looks like we can't fold this virtual register load into this
@@ -507,8 +510,6 @@
     PhysReg = getReg(MBB, MI, VirtReg);
   }
 
-  int FrameIndex = getStackSpaceFor(VirtReg, RC);
-
   markVirtRegModified(VirtReg, false);   // Note that this reg was just reloaded
 
   DEBUG(std::cerr << "  Reloading %reg" << VirtReg << " into "
@@ -565,9 +566,10 @@
         unsigned VirtReg = KI->second;
         unsigned PhysReg = VirtReg;
         if (MRegisterInfo::isVirtualRegister(VirtReg)) {
+          // If the virtual register was never materialized into a register, it
+          // might not be in the map, but it won't hurt to zero it out anyway.
           unsigned &PhysRegSlot = getVirt2PhysRegMapSlot(VirtReg);
           PhysReg = PhysRegSlot;
-          assert(PhysReg != 0);
           PhysRegSlot = 0;
         }
 
@@ -599,7 +601,7 @@
     for (const unsigned *ImplicitDefs = TID.ImplicitDefs;
          *ImplicitDefs; ++ImplicitDefs) {
       unsigned Reg = *ImplicitDefs;
-      spillPhysReg(MBB, MI, Reg);
+      spillPhysReg(MBB, MI, Reg, true);
       PhysRegsUseOrder.push_back(Reg);
       PhysRegsUsed[Reg] = 0;            // It is free and reserved now
       for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);





More information about the llvm-commits mailing list