[llvm-commits] [llvm] r65497 - /llvm/trunk/lib/CodeGen/VirtRegMap.cpp

Evan Cheng evan.cheng at apple.com
Wed Feb 25 18:30:43 PST 2009


Author: evancheng
Date: Wed Feb 25 20:30:42 2009
New Revision: 65497

URL: http://llvm.org/viewvc/llvm-project?rev=65497&view=rev
Log:
If an available register falls through to a succ block, unset the last kill. Sorry, it's impossible to reduce a sensible test case. It basically requires the moon and stars to align in order to cause a failure.

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

Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=65497&r1=65496&r2=65497&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original)
+++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Wed Feb 25 20:30:42 2009
@@ -408,7 +408,12 @@
   /// value for this slot lives in (as the previous value is dead now).
   void ModifyStackSlotOrReMat(int SlotOrReMat);
 
-  void AddAvailableRegsToLiveIn(MachineBasicBlock &MBB);
+  /// AddAvailableRegsToLiveIn - Availability information is being kept coming
+  /// into the specified MBB. Add available physical registers as potential
+  /// live-in's. If they are reused in the MBB, they will be added to the
+  /// live-in set to make register scavenger and post-allocation scheduler.
+  void AddAvailableRegsToLiveIn(MachineBasicBlock &MBB, BitVector &RegKills,
+                                std::vector<MachineOperand*> &KillOps);
 };
 }
 
@@ -488,22 +493,62 @@
   PhysRegsAvailable.erase(I);
 }
 
+/// InvalidateKill - A MI that defines the specified register is being deleted,
+/// invalidate the register kill information.
+static void InvalidateKill(unsigned Reg, BitVector &RegKills,
+                           std::vector<MachineOperand*> &KillOps) {
+  if (RegKills[Reg]) {
+    KillOps[Reg]->setIsKill(false);
+    KillOps[Reg] = NULL;
+    RegKills.reset(Reg);
+  }
+}
+
 /// AddAvailableRegsToLiveIn - Availability information is being kept coming
-/// into the specified MBB. Add available physical registers as live-in's
-/// so register scavenger and post-allocation scheduler are happy.
-void AvailableSpills::AddAvailableRegsToLiveIn(MachineBasicBlock &MBB) {
+/// into the specified MBB. Add available physical registers as potential
+/// live-in's. If they are reused in the MBB, they will be added to the
+/// live-in set to make register scavenger and post-allocation scheduler.
+void AvailableSpills::AddAvailableRegsToLiveIn(MachineBasicBlock &MBB,
+                                        BitVector &RegKills,
+                                        std::vector<MachineOperand*> &KillOps) {
+  std::set<unsigned> NotAvailable;
   for (std::multimap<unsigned, int>::iterator
          I = PhysRegsAvailable.begin(), E = PhysRegsAvailable.end();
        I != E; ++I) {
-    unsigned Reg = (*I).first;
+    unsigned Reg = I->first;
+    bool MakeAvail = true;
     const TargetRegisterClass* RC = TRI->getPhysicalRegisterRegClass(Reg);
     // FIXME: A temporary workaround. We can't reuse available value if it's
     // not safe to move the def of the virtual register's class. e.g.
     // X86::RFP* register classes. Do not add it as a live-in.
     if (!TII->isSafeToMoveRegClassDefs(RC))
-      continue;
-    if (!MBB.isLiveIn(Reg))
+      MakeAvail = false;
+    if (MBB.isLiveIn(Reg))
+      // It's already livein somehow. Be conservative, do not make it available.
+      MakeAvail = false;
+
+    if (!MakeAvail) 
+      // This is no longer available.
+      NotAvailable.insert(Reg);
+    else {
       MBB.addLiveIn(Reg);
+      InvalidateKill(Reg, RegKills, KillOps);
+    }
+
+    // Skip over the same register.
+    std::multimap<unsigned, int>::iterator NI = next(I);
+    while (NI != E && NI->first == Reg) {
+      ++I;
+      ++NI;
+    }
+  }
+
+  for (std::set<unsigned>::iterator I = NotAvailable.begin(),
+         E = NotAvailable.end(); I != E; ++I) {
+    ClobberPhysReg(*I);
+    for (const unsigned *SubRegs = TRI->getSubRegisters(*I);
+       *SubRegs; ++SubRegs)
+      ClobberPhysReg(*SubRegs);
   }
 }
 
@@ -546,6 +591,11 @@
       // reloads. This is usually refreshed per basic block.
       AvailableSpills Spills(TRI, TII);
 
+      // Keep track of kill information.
+      BitVector RegKills(TRI->getNumRegs());
+      std::vector<MachineOperand*> KillOps;
+      KillOps.resize(TRI->getNumRegs(), NULL);
+
       // SingleEntrySuccs - Successor blocks which have a single predecessor.
       SmallVector<MachineBasicBlock*, 4> SinglePredSuccs;
       SmallPtrSet<MachineBasicBlock*,16> EarlyVisited;
@@ -559,7 +609,7 @@
            DFI != E; ++DFI) {
         MachineBasicBlock *MBB = *DFI;
         if (!EarlyVisited.count(MBB))
-          RewriteMBB(*MBB, VRM, Spills);
+          RewriteMBB(*MBB, VRM, Spills, RegKills, KillOps);
 
         // If this MBB is the only predecessor of a successor. Keep the
         // availability information and visit it next.
@@ -574,8 +624,8 @@
             // the only predecessor.
             MBB = SinglePredSuccs[0];
             if (!Visited.count(MBB) && EarlyVisited.insert(MBB)) {
-              Spills.AddAvailableRegsToLiveIn(*MBB);
-              RewriteMBB(*MBB, VRM, Spills);
+              Spills.AddAvailableRegsToLiveIn(*MBB, RegKills, KillOps);
+              RewriteMBB(*MBB, VRM, Spills, RegKills, KillOps);
             }
           }
         } while (MBB);
@@ -612,6 +662,7 @@
     bool CommuteToFoldReload(MachineBasicBlock &MBB,
                              MachineBasicBlock::iterator &MII,
                              unsigned VirtReg, unsigned SrcReg, int SS,
+                             AvailableSpills &Spills,
                              BitVector &RegKills,
                              std::vector<MachineOperand*> &KillOps,
                              const TargetRegisterInfo *TRI,
@@ -627,7 +678,8 @@
                              std::vector<MachineOperand*> &KillOps,
                              VirtRegMap &VRM);
     void RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
-                    AvailableSpills &Spills);
+                    AvailableSpills &Spills,
+                    BitVector &RegKills, std::vector<MachineOperand*> &KillOps);
   };
 }
 
@@ -653,17 +705,6 @@
   }
 }
 
-/// InvalidateKill - A MI that defines the specified register is being deleted,
-/// invalidate the register kill information.
-static void InvalidateKill(unsigned Reg, BitVector &RegKills,
-                           std::vector<MachineOperand*> &KillOps) {
-  if (RegKills[Reg]) {
-    KillOps[Reg]->setIsKill(false);
-    KillOps[Reg] = NULL;
-    RegKills.reset(Reg);
-  }
-}
-
 /// InvalidateRegDef - If the def operand of the specified def MI is now dead
 /// (since it's spill instruction is removed), mark it isDead. Also checks if
 /// the def MI has other definition operands that are not dead. Returns it by
@@ -1086,6 +1127,7 @@
 bool LocalSpiller::CommuteToFoldReload(MachineBasicBlock &MBB,
                                     MachineBasicBlock::iterator &MII,
                                     unsigned VirtReg, unsigned SrcReg, int SS,
+                                    AvailableSpills &Spills,
                                     BitVector &RegKills,
                                     std::vector<MachineOperand*> &KillOps,
                                     const TargetRegisterInfo *TRI,
@@ -1154,6 +1196,11 @@
     VRM.RemoveMachineInstrFromMaps(&MI);
     MBB.erase(&MI);
 
+    // If NewReg was previously holding value of some SS, it's now clobbered.
+    // This has to be done now because it's a physical register. When this
+    // instruction is re-visited, it's ignored.
+    Spills.ClobberPhysReg(NewReg);
+
     ++NumCommutes;
     return true;
   }
@@ -1280,7 +1327,8 @@
 /// rewriteMBB - Keep track of which spills are available even after the
 /// register allocator is done with them.  If possible, avid reloading vregs.
 void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
-                              AvailableSpills &Spills) {
+                              AvailableSpills &Spills, BitVector &RegKills,
+                              std::vector<MachineOperand*> &KillOps) {
   DOUT << "\n**** Local spiller rewriting MBB '"
        << MBB.getBasicBlock()->getName() << ":\n";
 
@@ -1298,9 +1346,9 @@
   // ReMatDefs - These are rematerializable def MIs which are not deleted.
   SmallSet<MachineInstr*, 4> ReMatDefs;
 
-  // Keep track of kill information.
-  BitVector RegKills(TRI->getNumRegs());
-  std::vector<MachineOperand*>  KillOps;
+  // Clear kill info.
+  RegKills.reset();
+  KillOps.clear();
   KillOps.resize(TRI->getNumRegs(), NULL);
 
   unsigned Dist = 0;
@@ -1368,11 +1416,7 @@
         int SSorRMId = DoReMat
           ? VRM.getReMatId(VirtReg) : VRM.getStackSlot(VirtReg);
         const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
-        // FIXME: A temporary workaround. Don't reuse available value if it's
-        // not safe to move the def of the virtual register's class. e.g.
-        // X86::RFP* register classes.
-        unsigned InReg = TII->isSafeToMoveRegClassDefs(RC) ?
-          Spills.getSpillSlotOrReMatPhysReg(SSorRMId) : 0;
+        unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SSorRMId);
         if (InReg == Phys) {
           // If the value is already available in the expected register, save
           // a reload / remat.
@@ -1600,11 +1644,6 @@
             PotentialDeadStoreSlots.push_back(ReuseSlot);
           }
 
-          // Assumes this is the last use. IsKill will be unset if reg is reused
-          // unless it's a two-address operand.
-          if (ti == -1)
-            MI.getOperand(i).setIsKill();
-
           continue;
         }  // CanReuse
         
@@ -1877,7 +1916,7 @@
                    "Src hasn't been allocated yet?");
 
             if (CommuteToFoldReload(MBB, MII, VirtReg, SrcReg, StackSlot,
-                                    RegKills, KillOps, TRI, VRM)) {
+                                    Spills, RegKills, KillOps, TRI, VRM)) {
               NextMII = next(MII);
               BackTracked = true;
               goto ProcessNextInst;





More information about the llvm-commits mailing list