[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