[llvm] r260586 - Revert "LiveIntervalAnalysis: Support moving of subregister defs in handleMove"

Matthias Braun via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 11 13:07:45 PST 2016


Author: matze
Date: Thu Feb 11 15:07:44 2016
New Revision: 260586

URL: http://llvm.org/viewvc/llvm-project?rev=260586&view=rev
Log:
Revert "LiveIntervalAnalysis: Support moving of subregister defs in handleMove"

This is broke a bot:

http://lab.llvm.org:8011/builders/clang-cmake-aarch64-quick/builds/4703/steps/test-suite/logs/test.log

Reverting while I investigate.

This reverts commit r260565.

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

Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=260586&r1=260585&r2=260586&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Feb 11 15:07:44 2016
@@ -1044,24 +1044,6 @@ private:
         for (MIBundleOperands MO(KillMI); MO.isValid(); ++MO)
           if (MO->isReg() && MO->isUse())
             MO->setIsKill(false);
-
-      // Is there a def before NewIdx which is not OldIdx?
-      LiveRange::iterator Next = std::next(OldIdxIn);
-      if (Next != E && !SlotIndex::isSameInstr(OldIdx, Next->start) &&
-          SlotIndex::isEarlierInstr(Next->start, NewIdx)) {
-        // If we are here then OldIdx was just a use but not a def. We only have
-        // to ensure liveness extends to NewIdx.
-        LiveRange::iterator NewIdxIn =
-          LR.advanceTo(Next, NewIdx.getBaseIndex());
-        // Extend the segment before NewIdx if necessary.
-        if (NewIdxIn == E ||
-            !SlotIndex::isEarlierInstr(NewIdxIn->start, NewIdx)) {
-          LiveRange::iterator Prev = std::prev(NewIdxIn);
-          Prev->end = NewIdx.getRegSlot();
-        }
-        return;
-      }
-
       // Adjust OldIdxIn->end to reach NewIdx. This may temporarily make LR
       // invalid by overlapping ranges.
       bool isKill = SlotIndex::isSameInstr(OldIdx, OldIdxIn->end);
@@ -1071,7 +1053,7 @@ private:
         return;
 
       // Did we have a Def at OldIdx?
-      OldIdxOut = Next;
+      OldIdxOut = std::next(OldIdxIn);
       if (OldIdxOut == E || !SlotIndex::isSameInstr(OldIdx, OldIdxOut->start))
         return;
     } else {
@@ -1095,80 +1077,14 @@ private:
     }
 
     // If we are here then we have a Definition at OldIdx which ends before
-    // NewIdx.
-
+    // NewIdx. Moving across unrelated defs is not allowed; That means we either
+    // had a dead-def at OldIdx or the OldIdxOut segment ends at NewIdx.
+    assert((OldIdxOut->end == OldIdx.getDeadSlot() ||
+            SlotIndex::isSameInstr(OldIdxOut->end, NewIdxDef)) &&
+            "Cannot move def below kill");
     // Is there an existing Def at NewIdx?
     LiveRange::iterator AfterNewIdx
       = LR.advanceTo(OldIdxOut, NewIdx.getRegSlot());
-    bool OldIdxDefIsDead = OldIdxOut->end.isDead();
-    if (!OldIdxDefIsDead &&
-        SlotIndex::isEarlierInstr(OldIdxOut->end, NewIdxDef)) {
-      // OldIdx is not a dead def, and NewIdxDef is inside a new interval.
-      VNInfo *DefVNI;
-      if (OldIdxOut != LR.begin() &&
-          !SlotIndex::isEarlierInstr(std::prev(OldIdxOut)->end,
-                                     OldIdxOut->start)) {
-        // There is no gap between OldIdxOut and its predecessor anymore,
-        // merge them
-        LiveRange::iterator IPrev = std::prev(OldIdxOut);
-        DefVNI = OldIdxVNI;
-        IPrev->end = OldIdxOut->end;
-      } else {
-        // The value is live in to OldIdx
-        LiveRange::iterator INext = std::next(OldIdxOut);
-        assert(INext != E && "Must have following segment");
-        // We merge OldIdxOut and its successor. As we're dealing with subreg
-        // reordering, there is always a successor to OldIdxOut in the same BB
-        // We don't need INext->valno anymore and will reuse for the new segment
-        // we create later.
-        DefVNI = INext->valno;
-        INext->start = OldIdxOut->end;
-        INext->valno = OldIdxVNI;
-        INext->valno->def = INext->start;
-      }
-      // If NewIdx is behind the last segment, extend that and append a new one.
-      if (AfterNewIdx == E) {
-        // OldIdxOut is undef at this point, Slide (OldIdxOut;AfterNewIdx] up
-        // one position.
-        //    |-  ?/OldIdxOut -| |- X0 -| ... |- Xn -| end
-        // => |- X0/OldIdxOut -| ... |- Xn -| |- undef/NewS -| end
-        std::copy(std::next(OldIdxOut), E, OldIdxOut);
-        // The last segment is undefined now, reuse it for a dead def.
-        LiveRange::iterator NewSegment = std::prev(E);
-        *NewSegment = LiveRange::Segment(NewIdxDef, NewIdxDef.getDeadSlot(),
-                                         DefVNI);
-        DefVNI->def = NewIdxDef;
-
-        LiveRange::iterator Prev = std::prev(NewSegment);
-        Prev->end = NewIdxDef;
-      } else {
-        // OldIdxOut is undef at this point, Slide (OldIdxOut;AfterNewIdx] up
-        // one position.
-        //    |-  ?/OldIdxOut -| |- X0 -| ... |- Xn/AfterNewIdx -| |- Next -|
-        // => |- X0/OldIdxOut -| ... |- Xn -| |- Xn/AfterNewIdx -| |- Next -|
-        std::copy(std::next(OldIdxOut), std::next(AfterNewIdx), OldIdxOut);
-        LiveRange::iterator Prev = std::prev(AfterNewIdx);
-        // We have two cases:
-        if (SlotIndex::isEarlierInstr(Prev->start, NewIdxDef)) {
-          // Case 1: NewIdx is inside a liverange. Split this liverange at
-          // NewIdxDef into the segment "Prev" followed by "NewSegment".
-          LiveRange::iterator NewSegment = AfterNewIdx;
-          *NewSegment = LiveRange::Segment(NewIdxDef, Prev->end, Prev->valno);
-          Prev->valno->def = NewIdxDef;
-
-          *Prev = LiveRange::Segment(Prev->start, NewIdxDef, DefVNI);
-          DefVNI->def = Prev->start;
-        } else {
-          // Case 2: NewIdx is in a lifetime hole. Keep AfterNewIdx as is and
-          // turn Prev into a segment from NewIdx to AfterNewIdx->start.
-          *Prev = LiveRange::Segment(NewIdxDef, AfterNewIdx->start, DefVNI);
-          DefVNI->def = NewIdxDef;
-          assert(DefVNI != AfterNewIdx->valno);
-        }
-      }
-      return;
-    }
-
     if (AfterNewIdx != E &&
         SlotIndex::isSameInstr(AfterNewIdx->start, NewIdxDef)) {
       // There is an existing def at NewIdx. The def at OldIdx is coalesced into
@@ -1214,18 +1130,24 @@ private:
         return;
 
       // At this point we have to move OldIdxIn->end back to the nearest
-      // previous use or (dead-)def but no further than NewIdx.
-      SlotIndex DefBeforeOldIdx = std::max(OldIdxIn->start.getDeadSlot(),
-                                           NewIdx.getRegSlot());
-      OldIdxIn->end = findLastUseBefore(DefBeforeOldIdx, Reg, LaneMask);
+      // previous use but no further than NewIdx. Moreover OldIdx is a Def then
+      // we cannot have any intermediate uses or the move would be illegal.
 
-      // Did we have a Def at OldIdx? If not we are done now.
       OldIdxOut = std::next(OldIdxIn);
-      if (OldIdxOut == E || !SlotIndex::isSameInstr(OldIdx, OldIdxOut->start))
+      // Did we have a Def at OldIdx?
+      if (OldIdxOut == E || !SlotIndex::isSameInstr(OldIdx, OldIdxOut->start)) {
+        // No def, search for the nearest previous use.
+        // This can never be an early clobber kill since there is no def.
+        OldIdxIn->end = findLastUseBefore(Reg, LaneMask).getRegSlot();
+        // We are done if there is no def at OldIdx.
         return;
+      } else {
+        // There can't have been any intermediate uses or defs, so move
+        // OldIdxIn->end to NewIdx.
+        OldIdxIn->end = NewIdx.getRegSlot(OldIdxIn->end.isEarlyClobber());
+      }
     } else {
       OldIdxOut = OldIdxIn;
-      OldIdxIn = OldIdxOut != LR.begin() ? std::prev(OldIdxOut) : E;
     }
 
     // If we are here then there is a Definition at OldIdx. OldIdxOut points
@@ -1257,49 +1179,9 @@ private:
       // Previously nothing was live after NewIdx, so all we have to do now is
       // move the begin of OldIdxOut to NewIdx.
       if (!OldIdxDefIsDead) {
-        // Do we have any intermediate Defs between OldIdx and NewIdx?
-        if (OldIdxIn != E &&
-            SlotIndex::isEarlierInstr(NewIdxDef, OldIdxIn->start)) {
-          // OldIdx is not a dead def and NewIdx is before predecessor start
-          LiveRange::iterator NewIdxIn = NewIdxOut;
-          assert(NewIdxIn == LR.find(NewIdx.getBaseIndex()));
-          const SlotIndex SplitPos = NewIdxDef;
-
-          // Merge the OldIdxIn and OldIdxOut segments into OldIdxOut.
-          *OldIdxOut = LiveRange::Segment(OldIdxIn->start, OldIdxOut->end,
-                                          OldIdxIn->valno);
-          // OldIdxIn and OldIdxVNI are now undef and can be overridden.
-          // We Slide [NewIdxIn, OldIdxIn) down one position.
-          //    |- X0/NewIdxIn -| ... |- Xn-1 -||- Xn/OldIdxIn -||- OldIdxOut -|
-          // => |- undef/NexIdxIn -| |- X0 -| ... |- Xn-1 -| |- Xn/OldIdxOut -|
-          std::copy_backward(NewIdxIn, OldIdxIn, OldIdxOut);
-          // NewIdxIn is now considered undef so we can reuse it for the moved
-          // value.
-          LiveRange::iterator NewSegment = NewIdxIn;
-          LiveRange::iterator Next = std::next(NewSegment);
-          NewSegment->valno = OldIdxVNI;
-          if (SlotIndex::isEarlierInstr(Next->start, NewIdx)) {
-            // There is no gap between NewSegment and its predecessor
-            *NewSegment = LiveRange::Segment(Next->start, SplitPos,
-                                             NewSegment->valno);
-            NewSegment->valno->def = Next->start;
-
-            *Next = LiveRange::Segment(SplitPos, Next->end, Next->valno);
-            Next->valno->def = SplitPos;
-          } else {
-            // There is a gap between NewSegment and its predecessor
-            // Value become live in
-            *NewSegment = LiveRange::Segment(SplitPos, Next->start,
-                                             NewSegment->valno);
-            NewSegment->valno->def = SplitPos;
-          }
-        } else {
-          // Leave the end point of a live def.
-          OldIdxOut->start = NewIdxDef;
-          OldIdxVNI->def = NewIdxDef;
-          if (OldIdxIn != E && SlotIndex::isEarlierInstr(NewIdx, OldIdxIn->end))
-            OldIdxIn->end = NewIdx.getRegSlot();
-        }
+        // Leave the end point of a live def.
+        OldIdxVNI->def = NewIdxDef;
+        OldIdxOut->start = NewIdxDef;
       } else {
         // OldIdxVNI is a dead def. It may have been moved across other values
         // in LR, so move OldIdxOut up to NewIdxOut. Slide [NewIdxOut;OldIdxOut)
@@ -1333,10 +1215,10 @@ private:
   }
 
   // Return the last use of reg between NewIdx and OldIdx.
-  SlotIndex findLastUseBefore(SlotIndex Before, unsigned Reg,
-                              LaneBitmask LaneMask) {
+  SlotIndex findLastUseBefore(unsigned Reg, LaneBitmask LaneMask) {
+
     if (TargetRegisterInfo::isVirtualRegister(Reg)) {
-      SlotIndex LastUse = Before;
+      SlotIndex LastUse = NewIdx;
       for (MachineOperand &MO : MRI.use_nodbg_operands(Reg)) {
         unsigned SubReg = MO.getSubReg();
         if (SubReg != 0 && LaneMask != 0
@@ -1346,16 +1228,16 @@ private:
         const MachineInstr *MI = MO.getParent();
         SlotIndex InstSlot = LIS.getSlotIndexes()->getInstructionIndex(MI);
         if (InstSlot > LastUse && InstSlot < OldIdx)
-          LastUse = InstSlot.getRegSlot();
+          LastUse = InstSlot;
       }
       return LastUse;
     }
 
     // This is a regunit interval, so scanning the use list could be very
     // expensive. Scan upwards from OldIdx instead.
-    assert(Before < OldIdx && "Expected upwards move");
+    assert(NewIdx < OldIdx && "Expected upwards move");
     SlotIndexes *Indexes = LIS.getSlotIndexes();
-    MachineBasicBlock *MBB = Indexes->getMBBFromIndex(Before);
+    MachineBasicBlock *MBB = Indexes->getMBBFromIndex(NewIdx);
 
     // OldIdx may not correspond to an instruction any longer, so set MII to
     // point to the next instruction after OldIdx, or MBB->end().
@@ -1371,19 +1253,19 @@ private:
         continue;
       SlotIndex Idx = Indexes->getInstructionIndex(MII);
 
-      // Stop searching when Before is reached.
-      if (!SlotIndex::isEarlierInstr(Before, Idx))
-        return Before;
+      // Stop searching when NewIdx is reached.
+      if (!SlotIndex::isEarlierInstr(NewIdx, Idx))
+        return NewIdx;
 
       // Check if MII uses Reg.
       for (MIBundleOperands MO(MII); MO.isValid(); ++MO)
         if (MO->isReg() &&
             TargetRegisterInfo::isPhysicalRegister(MO->getReg()) &&
             TRI.hasRegUnit(MO->getReg(), Reg))
-          return Idx.getRegSlot();
+          return Idx;
     }
-    // Didn't reach Before. It must be the first instruction in the block.
-    return Before;
+    // Didn't reach NewIdx. It must be the first instruction in the block.
+    return NewIdx;
   }
 };
 




More information about the llvm-commits mailing list