[llvm-commits] [llvm] r48348 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp

Evan Cheng evan.cheng at apple.com
Thu Mar 13 17:14:56 PDT 2008


Author: evancheng
Date: Thu Mar 13 19:14:55 2008
New Revision: 48348

URL: http://llvm.org/viewvc/llvm-project?rev=48348&view=rev
Log:
Livein copy scheduling fixes: do not coalesce physical register copies, correctly determine the safe location to insert the copies.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=48348&r1=48347&r2=48348&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Thu Mar 13 19:14:55 2008
@@ -987,50 +987,14 @@
   }
 }
 
-/// regIsLive - Return true if the specified register is live due to a
-/// live in copy.
-static bool regIsLive(unsigned Reg, BitVector &LiveRegs,
-                      const TargetRegisterInfo *TRI) {
-  if (LiveRegs[Reg])
-    return true;
-  for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS)
-    if (LiveRegs[*AS])
-      return true;
-  return false;
-}
-
-/// regIsClobbered - Return true if the specified register is defined in
-/// between the two specific instructions.
-static bool regIsClobbered(unsigned Reg, MachineBasicBlock *MBB,
-                           MachineBasicBlock::iterator InsertPos,
-                           MachineBasicBlock::iterator UsePos,
-                           const TargetRegisterInfo *TRI) {
-  for (MachineBasicBlock::iterator I = InsertPos; I != UsePos; ++I) {
-    MachineInstr *MI = I;
-    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
-      const MachineOperand &MO = MI->getOperand(i);
-      if (!MO.isRegister() || !MO.isDef())
-        continue;
-      unsigned DefReg = MO.getReg();
-      if (TargetRegisterInfo::isVirtualRegister(DefReg))
-        continue;
-      if (TRI->regsOverlap(DefReg, Reg))
-        return true;
-    }
-  }
-  return false;
-}
-
 /// EmitLiveInCopy - Emit a copy for a live in physical register. If the
 /// physical register has only a single copy use, then coalesced the copy
-/// if possible. It returns the destination register of the emitted copy
-/// if it is a physical register; otherwise it returns zero.
-unsigned ScheduleDAG::EmitLiveInCopy(MachineBasicBlock *MBB,
-                                     MachineBasicBlock::iterator &InsertPos,
-                                     unsigned VirtReg, unsigned PhysReg,
-                                     const TargetRegisterClass *RC,
-                                     BitVector &LiveRegsBefore,
-                                     BitVector &LiveRegsAfter) {
+/// if possible.
+void ScheduleDAG::EmitLiveInCopy(MachineBasicBlock *MBB,
+                                 MachineBasicBlock::iterator &InsertPos,
+                                 unsigned VirtReg, unsigned PhysReg,
+                                 const TargetRegisterClass *RC,
+                                 DenseMap<MachineInstr*, unsigned> &CopyRegMap){
   unsigned NumUses = 0;
   MachineInstr *UseMI = NULL;
   for (MachineRegisterInfo::use_iterator UI = MRI.use_begin(VirtReg),
@@ -1041,95 +1005,61 @@
   }
 
   // If the number of uses is not one, or the use is not a move instruction,
-  // don't coalesce.
+  // don't coalesce. Also, only coalesce away a virtual register to virtual
+  // register copy.
+  bool Coalesced = false;
   unsigned SrcReg, DstReg;
-  if (NumUses != 1 ||
-      !TII->isMoveInstr(*UseMI, SrcReg, DstReg)) {
-    TII->copyRegToReg(*MBB, InsertPos, VirtReg, PhysReg, RC, RC);
-    return 0;
-  }
-
-  // Coalesce away a virtual register to virtual register copy.
-  if (TargetRegisterInfo::isVirtualRegister(DstReg)) {
-    TII->copyRegToReg(*MBB, InsertPos, DstReg, PhysReg, RC, RC);
+  if (NumUses == 1 &&
+      TII->isMoveInstr(*UseMI, SrcReg, DstReg) &&
+      TargetRegisterInfo::isVirtualRegister(DstReg)) {
+    VirtReg = DstReg;
+    Coalesced = true;
+  }
+
+  // Now find an ideal location to insert the copy.
+  MachineBasicBlock::iterator Pos = InsertPos;
+  while (Pos != MBB->begin()) {
+    MachineInstr *PrevMI = prior(Pos);
+    DenseMap<MachineInstr*, unsigned>::iterator RI = CopyRegMap.find(PrevMI);
+    // copyRegToReg might emit multiple instructions to do a copy.
+    unsigned CopyDstReg = (RI == CopyRegMap.end()) ? 0 : RI->second;
+    if (CopyDstReg && !TRI->regsOverlap(CopyDstReg, PhysReg))
+      // This is what the BB looks like right now:
+      // r1024 = mov r0
+      // ...
+      // r1    = mov r1024
+      //
+      // We want to insert "r1025 = mov r1". Inserting this copy below the
+      // move to r1024 makes it impossible for that move to be coalesced.
+      //
+      // r1025 = mov r1
+      // r1024 = mov r0
+      // ...
+      // r1    = mov 1024
+      // r2    = mov 1025
+      break; // Woot! Found a good location.
+    --Pos;
+  }
+
+  TII->copyRegToReg(*MBB, Pos, VirtReg, PhysReg, RC, RC);
+  CopyRegMap.insert(std::make_pair(prior(Pos), VirtReg));
+  if (Coalesced) {
     if (&*InsertPos == UseMI) ++InsertPos;
     MBB->erase(UseMI);
-    return 0;
   }
-
-  // If the destination is a physical register, check if it's safe to
-  // coalesce. If there is a def of the register between the insertion point and
-  // the use, then it's not safe.
-  if (regIsClobbered(DstReg, MBB, InsertPos, UseMI, TRI)) {
-    TII->copyRegToReg(*MBB, InsertPos, VirtReg, PhysReg, RC, RC);
-    return 0;
-  }
-
-  // Also check already processed livein copies and determine the safe location
-  // to insert the copy.  e.g. Suppose livein r0 is already processed and now
-  // we are inserting r1 copy to vr1025 which will be coalesced to r0.
-  // vr1024 = r0
-  // <this is the insertion pt>
-  // ...
-  // It's safe to insert the copy from r1 to r0.
-  // vr1024 = r0
-  // r0     = r1
-  //
-  // However, if livein r0 copy is coalesced to r1:
-  // r1 = r0
-  // <insertion pt>
-  // ...
-  // Then it's not safe to insert the copy from r1 to r0 at the insertion pt.
-  // Nor is it safe to insert it at the start of the MBB.
-  //
-  // If livein r3 is already processed and it's coalesced to r1.
-  // <begin of MBB>   -- safe to insert here
-  // r1    = r3
-  // <insertion pt>  -- not safe
-  // Then it's safe to insert at the start of the MBB.
-  if (regIsLive(DstReg, LiveRegsAfter, TRI)) {
-    if (regIsLive(PhysReg, LiveRegsBefore, TRI)) {
-      // FIXME: Still possible to find a safe place to insert the copy.
-      TII->copyRegToReg(*MBB, InsertPos, VirtReg, PhysReg, RC, RC);
-      return 0;
-    }
-    TII->copyRegToReg(*MBB, MBB->begin(), DstReg, PhysReg, RC, RC);
-    if (&*InsertPos == UseMI) ++InsertPos;
-    MBB->erase(UseMI);
-    return DstReg;
-  }
-  TII->copyRegToReg(*MBB, InsertPos, DstReg, PhysReg, RC, RC);
-  if (&*InsertPos == UseMI) ++InsertPos;
-  MBB->erase(UseMI);
-  return DstReg;
 }
 
 /// EmitLiveInCopies - If this is the first basic block in the function,
 /// and if it has live ins that need to be copied into vregs, emit the
 /// copies into the top of the block.
 void ScheduleDAG::EmitLiveInCopies(MachineBasicBlock *MBB) {
-  BitVector LiveRegsBefore; // Live registers before insertion pt.
-  BitVector LiveRegsAfter;  // Live registers after insertion pt.
-  LiveRegsBefore.resize(TRI->getNumRegs());
-  LiveRegsAfter.resize(TRI->getNumRegs());
-
+  DenseMap<MachineInstr*, unsigned> CopyRegMap;
   MachineBasicBlock::iterator InsertPos = MBB->begin();
   for (MachineRegisterInfo::livein_iterator LI = MRI.livein_begin(),
          E = MRI.livein_end(); LI != E; ++LI)
     if (LI->second) {
       const TargetRegisterClass *RC = MRI.getRegClass(LI->second);
-      unsigned Reg = EmitLiveInCopy(MBB, InsertPos, LI->second, LI->first, RC,
-                                    LiveRegsBefore, LiveRegsAfter);
-      if (Reg) {
-        LiveRegsAfter.set(Reg);
-        for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
-             unsigned SubReg = *SubRegs; ++SubRegs)
-          LiveRegsAfter.set(SubReg);
-      }
-      LiveRegsBefore.set(LI->first);
-      for (const unsigned *SubRegs = TRI->getSubRegisters(LI->first);
-           unsigned SubReg = *SubRegs; ++SubRegs)
-        LiveRegsBefore.set(SubReg);
+      EmitLiveInCopy(MBB, InsertPos, LI->second, LI->first, RC, CopyRegMap);
     }
 }
 





More information about the llvm-commits mailing list