[llvm-commits] [llvm] r103866 - /llvm/trunk/lib/CodeGen/RegAllocFast.cpp

Jakob Stoklund Olesen stoklund at 2pi.dk
Fri May 14 23:09:08 PDT 2010


Author: stoklund
Date: Sat May 15 01:09:08 2010
New Revision: 103866

URL: http://llvm.org/viewvc/llvm-project?rev=103866&view=rev
Log:
Calculate liveness on the fly for local registers.

When working top-down in a basic block, substituting physregs for virtregs, the use-def chains are kept up to date. That means we can recognize a virtreg kill by the use-def chain becoming empty.

This makes the fast allocator independent of incoming kill flags.

Modified:
    llvm/trunk/lib/CodeGen/RegAllocFast.cpp

Modified: llvm/trunk/lib/CodeGen/RegAllocFast.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocFast.cpp?rev=103866&r1=103865&r2=103866&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegAllocFast.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegAllocFast.cpp Sat May 15 01:09:08 2010
@@ -132,6 +132,8 @@
     bool runOnMachineFunction(MachineFunction &Fn);
     void AllocateBasicBlock(MachineBasicBlock &MBB);
     int getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC);
+    bool isLastUseOfLocalReg(MachineOperand&);
+
     void addKillFlag(LiveRegMap::iterator i);
     void killVirtReg(LiveRegMap::iterator i);
     void killVirtReg(unsigned VirtReg);
@@ -174,6 +176,26 @@
   return FrameIdx;
 }
 
+/// isLastUseOfLocalReg - Return true if MO is the only remaining reference to
+/// its virtual register, and it is guaranteed to be a block-local register.
+///
+bool RAFast::isLastUseOfLocalReg(MachineOperand &MO) {
+  // Check for non-debug uses or defs following MO.
+  // This is the most likely way to fail - fast path it.
+  MachineOperand *i = &MO;
+  while ((i = i->getNextOperandForReg()))
+    if (!i->isDebug())
+      return false;
+
+  // If the register has ever been spilled or reloaded, we conservatively assume
+  // it is a global register used in multiple blocks.
+  if (StackSlotForVirtReg[MO.getReg()] != -1)
+    return false;
+
+  // Check that the use/def chain has exactly one operand - MO.
+  return &MRI->reg_nodbg_begin(MO.getReg()).getOperand() == &MO;
+}
+
 /// addKillFlag - Set kill flags on last use of a virtual register.
 void RAFast::addKillFlag(LiveRegMap::iterator lri) {
   assert(lri != LiveVirtRegs.end() && "Killing unmapped virtual register");
@@ -566,6 +588,15 @@
     TII->loadRegFromStackSlot(MBB, MI, lri->second.PhysReg, FrameIndex, RC,
                               TRI);
     ++NumLoads;
+  } else if (lri->second.Dirty) {
+    MachineOperand &MO = MI->getOperand(OpNum);
+    if (isLastUseOfLocalReg(MO)) {
+      DEBUG(dbgs() << "Killing last use: " << MO << "\n");
+      MO.setIsKill();
+    } else if (MO.isKill()) {
+      DEBUG(dbgs() << "Clearing dubious kill: " << MO << "\n");
+      MO.setIsKill(false);
+    }
   }
   LiveReg &LR = lri->second;
   LR.LastUse = MI;





More information about the llvm-commits mailing list