Add TargetInstrInfo::isSafeToMoveRegisterClassDefs. It returns true if it's safe...
[oota-llvm.git] / lib / CodeGen / VirtRegMap.cpp
index 79857d9ff1f3f3a980829ec6f2405204e5cc5d05..9cb580b9f0ab7385edef9c9226305a70f45c8cd5 100644 (file)
@@ -1342,6 +1342,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
     }
 
     // Process all of the spilled uses and all non spilled reg references.
+    SmallVector<int, 2> PotentialDeadStoreSlots;
     for (unsigned j = 0, e = VirtUseOps.size(); j != e; ++j) {
       unsigned i = VirtUseOps[j];
       MachineOperand &MO = MI.getOperand(i);
@@ -1359,7 +1360,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
         unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys;
         MI.getOperand(i).setReg(RReg);
         if (VRM.isImplicitlyDefined(VirtReg))
-          BuildMI(MBB, &MI, TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg);
+          BuildMI(MBB, &MI, MI.getDebugLoc(),
+                  TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg);
         continue;
       }
       
@@ -1446,17 +1448,14 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
 
           if (MI.getOperand(i).isKill() &&
               ReuseSlot <= VirtRegMap::MAX_STACK_SLOT) {
-            // This was the last use and the spilled value is still available
-            // for reuse. That means the spill was unnecessary!
-            MachineInstr* DeadStore = MaybeDeadStores[ReuseSlot];
-            if (DeadStore) {
-              DOUT << "Removed dead store:\t" << *DeadStore;
-              InvalidateKills(*DeadStore, RegKills, KillOps);
-              VRM.RemoveMachineInstrFromMaps(DeadStore);
-              MBB.erase(DeadStore);
-              MaybeDeadStores[ReuseSlot] = NULL;
-              ++NumDSE;
-            }
+
+            // The store of this spilled value is potentially dead, but we
+            // won't know for certain until we've confirmed that the re-use
+            // above is valid, which means waiting until the other operands
+            // are processed. For now we just track the spill slot, we'll
+            // remove it after the other operands are processed if valid.
+
+            PotentialDeadStoreSlots.push_back(ReuseSlot);
           }
           continue;
         }  // CanReuse
@@ -1560,6 +1559,23 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
       DOUT << '\t' << *prior(MII);
     }
 
+    // Ok - now we can remove stores that have been confirmed dead.
+    for (unsigned j = 0, e = PotentialDeadStoreSlots.size(); j != e; ++j) {
+      // This was the last use and the spilled value is still available
+      // for reuse. That means the spill was unnecessary!
+      int PDSSlot = PotentialDeadStoreSlots[j];
+      MachineInstr* DeadStore = MaybeDeadStores[PDSSlot];
+      if (DeadStore) {
+        DOUT << "Removed dead store:\t" << *DeadStore;
+        InvalidateKills(*DeadStore, RegKills, KillOps);
+        VRM.RemoveMachineInstrFromMaps(DeadStore);
+        MBB.erase(DeadStore);
+        MaybeDeadStores[PDSSlot] = NULL;
+        ++NumDSE;
+      }
+    }
+
+
     DOUT << '\t' << MI;
 
 
@@ -1738,15 +1754,17 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
       if (!TargetRegisterInfo::isVirtualRegister(VirtReg)) {
         // Check to see if this is a noop copy.  If so, eliminate the
         // instruction before considering the dest reg to be changed.
-        unsigned Src, Dst;
-        if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
+        unsigned Src, Dst, SrcSR, DstSR;
+        if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst) {
           ++NumDCE;
           DOUT << "Removing now-noop copy: " << MI;
           SmallVector<unsigned, 2> KillRegs;
           InvalidateKills(MI, RegKills, KillOps, &KillRegs);
           if (MO.isDead() && !KillRegs.empty()) {
-            // Source register or an implicit super-register use is killed.
-            assert(KillRegs[0] == Dst || TRI->isSubRegister(KillRegs[0], Dst));
+            // Source register or an implicit super/sub-register use is killed.
+            assert(KillRegs[0] == Dst ||
+                   TRI->isSubRegister(KillRegs[0], Dst) ||
+                   TRI->isSuperRegister(KillRegs[0], Dst));
             // Last def is now dead.
             TransferDeadness(&MBB, Dist, Src, RegKills, KillOps);
           }
@@ -1823,8 +1841,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
         // Check to see if this is a noop copy.  If so, eliminate the
         // instruction before considering the dest reg to be changed.
         {
-          unsigned Src, Dst;
-          if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
+          unsigned Src, Dst, SrcSR, DstSR;
+          if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst) {
             ++NumDCE;
             DOUT << "Removing now-noop copy: " << MI;
             InvalidateKills(MI, RegKills, KillOps);