[llvm-commits] [llvm] r103686 - in /llvm/trunk: lib/CodeGen/RegAllocFast.cpp test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll test/CodeGen/X86/2008-09-18-inline-asm-2.ll

Jakob Stoklund Olesen stoklund at 2pi.dk
Wed May 12 17:19:43 PDT 2010


Author: stoklund
Date: Wed May 12 19:19:43 2010
New Revision: 103686

URL: http://llvm.org/viewvc/llvm-project?rev=103686&view=rev
Log:
Take allocation hints from copy instructions to/from physregs.
This causes way more identity copies to be generated, ripe for coalescing.

Modified:
    llvm/trunk/lib/CodeGen/RegAllocFast.cpp
    llvm/trunk/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll
    llvm/trunk/test/CodeGen/X86/2008-09-18-inline-asm-2.ll

Modified: llvm/trunk/lib/CodeGen/RegAllocFast.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocFast.cpp?rev=103686&r1=103685&r2=103686&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegAllocFast.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegAllocFast.cpp Wed May 12 19:19:43 2010
@@ -49,6 +49,7 @@
   private:
     const TargetMachine *TM;
     MachineFunction *MF;
+    MachineRegisterInfo *MRI;
     const TargetRegisterInfo *TRI;
     const TargetInstrInfo *TII;
 
@@ -132,11 +133,11 @@
     LiveRegMap::iterator assignVirtToPhysReg(unsigned VirtReg,
                                              unsigned PhysReg);
     LiveRegMap::iterator allocVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
-                                      unsigned VirtReg);
+                                      unsigned VirtReg, unsigned Hint);
     unsigned defineVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
-                           unsigned OpNum, unsigned VirtReg);
+                           unsigned OpNum, unsigned VirtReg, unsigned Hint);
     unsigned reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
-                           unsigned OpNum, unsigned VirtReg);
+                           unsigned OpNum, unsigned VirtReg, unsigned Hint);
     void reservePhysReg(MachineBasicBlock &MBB, MachineInstr *MI,
                         unsigned PhysReg);
     void spillAll(MachineBasicBlock &MBB, MachineInstr *MI);
@@ -216,7 +217,7 @@
     LR.Dirty = false;
     DEBUG(dbgs() << "  Spilling register " << TRI->getName(LR.PhysReg)
       << " containing %reg" << VirtReg);
-    const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
+    const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
     int FrameIndex = getStackSpaceFor(VirtReg, RC);
     DEBUG(dbgs() << " to stack slot #" << FrameIndex << "\n");
     TII->storeRegToStackSlot(MBB, MI, LR.PhysReg, spillKill,
@@ -331,15 +332,52 @@
 /// allocVirtReg - Allocate a physical register for VirtReg.
 RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineBasicBlock &MBB,
                                                   MachineInstr *MI,
-                                                  unsigned VirtReg) {
+                                                  unsigned VirtReg,
+                                                  unsigned Hint) {
   const unsigned spillCost = 100;
   assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
          "Can only allocate virtual registers");
 
-  const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
+  const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
   TargetRegisterClass::iterator AOB = RC->allocation_order_begin(*MF);
   TargetRegisterClass::iterator AOE = RC->allocation_order_end(*MF);
 
+  // Ignore invalid hints.
+  if (Hint && (!TargetRegisterInfo::isPhysicalRegister(Hint) ||
+               !RC->contains(Hint) || UsedInInstr.test(Hint)))
+    Hint = 0;
+
+  // If there is no hint, peek at the first use of this register.
+  if (!Hint && !MRI->use_nodbg_empty(VirtReg)) {
+    MachineInstr &MI = *MRI->use_nodbg_begin(VirtReg);
+    unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+    // Copy to physreg -> use physreg as hint.
+    if (TII->isMoveInstr(MI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
+        SrcReg == VirtReg && TargetRegisterInfo::isPhysicalRegister(DstReg) &&
+        RC->contains(DstReg) && !UsedInInstr.test(DstReg)) {
+      Hint = DstReg;
+      DEBUG(dbgs() << "  %reg" << VirtReg << " gets hint from " << MI);
+    }
+  }
+
+  // Take hint when possible.
+  if (Hint) {
+    assert(RC->contains(Hint) && !UsedInInstr.test(Hint) &&
+           "Invalid hint should have been cleared");
+    switch(PhysRegState[Hint]) {
+    case regDisabled:
+    case regReserved:
+      break;
+    default:
+      DEBUG(dbgs() << "  %reg" << VirtReg << " really wants "
+                   << TRI->getName(Hint) << "\n");
+      spillVirtReg(MBB, MI, PhysRegState[Hint], true);
+      // Fall through.
+    case regFree:
+      return assignVirtToPhysReg(VirtReg, Hint);
+    }
+  }
+
   // First try to find a completely free register.
   unsigned BestCost = 0, BestReg = 0;
   bool hasDisabled = false;
@@ -447,12 +485,12 @@
 
 /// defineVirtReg - Allocate a register for VirtReg and mark it as dirty.
 unsigned RAFast::defineVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
-                               unsigned OpNum, unsigned VirtReg) {
+                              unsigned OpNum, unsigned VirtReg, unsigned Hint) {
   assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
          "Not a virtual register");
   LiveRegMap::iterator lri = LiveVirtRegs.find(VirtReg);
   if (lri == LiveVirtRegs.end())
-    lri = allocVirtReg(MBB, MI, VirtReg);
+    lri = allocVirtReg(MBB, MI, VirtReg, Hint);
   else
     addKillFlag(lri); // Kill before redefine.
   LiveReg &LR = lri->second;
@@ -465,13 +503,13 @@
 
 /// reloadVirtReg - Make sure VirtReg is available in a physreg and return it.
 unsigned RAFast::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
-                               unsigned OpNum, unsigned VirtReg) {
+                              unsigned OpNum, unsigned VirtReg, unsigned Hint) {
   assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
          "Not a virtual register");
   LiveRegMap::iterator lri = LiveVirtRegs.find(VirtReg);
   if (lri == LiveVirtRegs.end()) {
-    lri = allocVirtReg(MBB, MI, VirtReg);
-    const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
+    lri = allocVirtReg(MBB, MI, VirtReg, Hint);
+    const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
     int FrameIndex = getStackSpaceFor(VirtReg, RC);
     DEBUG(dbgs() << "  Reloading %reg" << VirtReg << " into "
                  << TRI->getName(lri->second.PhysReg) << "\n");
@@ -605,6 +643,11 @@
       continue;
     }
 
+    // If this is a copy, we may be able to coalesce.
+    unsigned CopySrc, CopyDst, CopySrcSub, CopyDstSub;
+    if (!TII->isMoveInstr(*MI, CopySrc, CopyDst, CopySrcSub, CopyDstSub))
+      CopySrc = CopyDst = 0;
+
     // Track registers used by instruction.
     UsedInInstr.reset();
     PhysDefs.clear();
@@ -651,11 +694,14 @@
       unsigned Reg = MO.getReg();
       if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
       if (MO.isUse()) {
-        setPhysReg(MO, reloadVirtReg(MBB, MI, i, Reg));
+        unsigned PhysReg = reloadVirtReg(MBB, MI, i, Reg, CopyDst);
+        if (CopySrc == Reg)
+          CopySrc = PhysReg;
+        setPhysReg(MO, PhysReg);
         if (MO.isKill())
           VirtKills.push_back(Reg);
       } else if (MO.isEarlyClobber()) {
-        unsigned PhysReg = defineVirtReg(MBB, MI, i, Reg);
+        unsigned PhysReg = defineVirtReg(MBB, MI, i, Reg, 0);
         setPhysReg(MO, PhysReg);
         PhysDefs.push_back(PhysReg);
       }
@@ -671,7 +717,7 @@
       killPhysReg(PhysKills[i]);
     PhysKills.clear();
 
-    MF->getRegInfo().addPhysRegsUsed(UsedInInstr);
+    MRI->addPhysRegsUsed(UsedInInstr);
 
     // Track registers defined by instruction - early clobbers at this point.
     UsedInInstr.reset();
@@ -702,7 +748,10 @@
       }
       if (MO.isDead())
         VirtKills.push_back(Reg);
-      setPhysReg(MO, defineVirtReg(MBB, MI, i, Reg));
+      unsigned PhysReg = defineVirtReg(MBB, MI, i, Reg, CopySrc);
+      if (CopyDst == Reg)
+        CopyDst = PhysReg;
+      setPhysReg(MO, PhysReg);
     }
 
     // Spill all dirty virtregs before a call, in case of an exception.
@@ -721,7 +770,7 @@
       killPhysReg(PhysKills[i]);
     PhysKills.clear();
 
-    MF->getRegInfo().addPhysRegsUsed(UsedInInstr);
+    MRI->addPhysRegsUsed(UsedInInstr);
   }
 
   // Spill all physical registers holding virtual registers now.
@@ -739,6 +788,7 @@
   DEBUG(dbgs() << "Machine Function\n");
   DEBUG(Fn.dump());
   MF = &Fn;
+  MRI = &MF->getRegInfo();
   TM = &Fn.getTarget();
   TRI = TM->getRegisterInfo();
   TII = TM->getInstrInfo();
@@ -748,7 +798,7 @@
 
   // initialize the virtual->physical register map to have a 'null'
   // mapping for all virtual registers
-  unsigned LastVirtReg = MF->getRegInfo().getLastVirtReg();
+  unsigned LastVirtReg = MRI->getLastVirtReg();
   StackSlotForVirtReg.grow(LastVirtReg);
 
   // Loop over all of the basic blocks, eliminating virtual register references
@@ -757,7 +807,7 @@
     AllocateBasicBlock(*MBB);
 
   // Make sure the set of used physregs is closed under subreg operations.
-  MF->getRegInfo().closePhysRegsUsed(*TRI);
+  MRI->closePhysRegsUsed(*TRI);
 
   StackSlotForVirtReg.clear();
   return true;

Modified: llvm/trunk/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll?rev=103686&r1=103685&r2=103686&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll Wed May 12 19:19:43 2010
@@ -7,8 +7,8 @@
 ; CHECK: subfze r4,r6
 ; LOCAL: subfc r6,r5,r4
 ; LOCAL: subfze r3,r3
-; FAST: subfc r9,r8,r7
-; FAST: subfze r10,r6
+; FAST: subfc r3,r5,r4
+; FAST: subfze r4,r6
 
 ; PR1357
 

Modified: llvm/trunk/test/CodeGen/X86/2008-09-18-inline-asm-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-09-18-inline-asm-2.ll?rev=103686&r1=103685&r2=103686&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/2008-09-18-inline-asm-2.ll (original)
+++ llvm/trunk/test/CodeGen/X86/2008-09-18-inline-asm-2.ll Wed May 12 19:19:43 2010
@@ -1,6 +1,6 @@
 ; RUN: llc < %s -march=x86 | grep "#%ebp %esi %edi 8(%edx) %eax (%ebx)"
 ; RUN: llc < %s -march=x86 -regalloc=local | grep "#%edi %ebp %edx 8(%ebx) %eax (%esi)"
-; RUN: llc < %s -march=x86 -regalloc=fast  | grep "#%ecx %ebx %edi 8(%ebp) %eax (%esi)"
+; RUN: llc < %s -march=x86 -regalloc=fast  | grep "#%ecx %ebx %edx 8(%edi) %eax (%esi)"
 
 ; The 1st, 2nd, 3rd and 5th registers above must all be different.  The registers
 ; referenced in the 4th and 6th operands must not be the same as the 1st or 5th





More information about the llvm-commits mailing list