mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-23 16:19:52 +00:00
Pass LiveQueryResult by value
This makes the API a bit more natural to use and makes it easier to make LiveRanges implementation details private. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192394 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -79,6 +79,65 @@ namespace llvm {
|
|||||||
void markUnused() { def = SlotIndex(); }
|
void markUnused() { def = SlotIndex(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Result of a LiveRange query. This class hides the implementation details
|
||||||
|
/// of live ranges, and it should be used as the primary interface for
|
||||||
|
/// examining live ranges around instructions.
|
||||||
|
class LiveQueryResult {
|
||||||
|
VNInfo *const EarlyVal;
|
||||||
|
VNInfo *const LateVal;
|
||||||
|
const SlotIndex EndPoint;
|
||||||
|
const bool Kill;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LiveQueryResult(VNInfo *EarlyVal, VNInfo *LateVal, SlotIndex EndPoint,
|
||||||
|
bool Kill)
|
||||||
|
: EarlyVal(EarlyVal), LateVal(LateVal), EndPoint(EndPoint), Kill(Kill)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/// Return the value that is live-in to the instruction. This is the value
|
||||||
|
/// that will be read by the instruction's use operands. Return NULL if no
|
||||||
|
/// value is live-in.
|
||||||
|
VNInfo *valueIn() const {
|
||||||
|
return EarlyVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return true if the live-in value is killed by this instruction. This
|
||||||
|
/// means that either the live range ends at the instruction, or it changes
|
||||||
|
/// value.
|
||||||
|
bool isKill() const {
|
||||||
|
return Kill;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return true if this instruction has a dead def.
|
||||||
|
bool isDeadDef() const {
|
||||||
|
return EndPoint.isDead();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the value leaving the instruction, if any. This can be a
|
||||||
|
/// live-through value, or a live def. A dead def returns NULL.
|
||||||
|
VNInfo *valueOut() const {
|
||||||
|
return isDeadDef() ? 0 : LateVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the value defined by this instruction, if any. This includes
|
||||||
|
/// dead defs, it is the value created by the instruction's def operands.
|
||||||
|
VNInfo *valueDefined() const {
|
||||||
|
return EarlyVal == LateVal ? 0 : LateVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the end point of the last live range segment to interact with
|
||||||
|
/// the instruction, if any.
|
||||||
|
///
|
||||||
|
/// The end point is an invalid SlotIndex only if the live range doesn't
|
||||||
|
/// intersect the instruction at all.
|
||||||
|
///
|
||||||
|
/// The end point may be at or past the end of the instruction's basic
|
||||||
|
/// block. That means the value was live out of the block.
|
||||||
|
SlotIndex endPoint() const {
|
||||||
|
return EndPoint;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// This class represents the liveness of a register, stack slot, etc.
|
/// This class represents the liveness of a register, stack slot, etc.
|
||||||
/// It manages an ordered list of Segment objects.
|
/// It manages an ordered list of Segment objects.
|
||||||
/// The Segments are organized in a static single assignment form: At places
|
/// The Segments are organized in a static single assignment form: At places
|
||||||
@@ -376,6 +435,48 @@ namespace llvm {
|
|||||||
removeSegment(S.start, S.end, RemoveDeadValNo);
|
removeSegment(S.start, S.end, RemoveDeadValNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Query Liveness at Idx.
|
||||||
|
/// The sub-instruction slot of Idx doesn't matter, only the instruction
|
||||||
|
/// it refers to is considered.
|
||||||
|
LiveQueryResult Query(SlotIndex Idx) const {
|
||||||
|
// Find the segment that enters the instruction.
|
||||||
|
const_iterator I = find(Idx.getBaseIndex());
|
||||||
|
const_iterator E = end();
|
||||||
|
if (I == E)
|
||||||
|
return LiveQueryResult(0, 0, SlotIndex(), false);
|
||||||
|
|
||||||
|
// Is this an instruction live-in segment?
|
||||||
|
// If Idx is the start index of a basic block, include live-in segments
|
||||||
|
// that start at Idx.getBaseIndex().
|
||||||
|
VNInfo *EarlyVal = 0;
|
||||||
|
VNInfo *LateVal = 0;
|
||||||
|
SlotIndex EndPoint;
|
||||||
|
bool Kill = false;
|
||||||
|
if (I->start <= Idx.getBaseIndex()) {
|
||||||
|
EarlyVal = I->valno;
|
||||||
|
EndPoint = I->end;
|
||||||
|
// Move to the potentially live-out segment.
|
||||||
|
if (SlotIndex::isSameInstr(Idx, I->end)) {
|
||||||
|
Kill = true;
|
||||||
|
if (++I == E)
|
||||||
|
return LiveQueryResult(EarlyVal, LateVal, EndPoint, Kill);
|
||||||
|
}
|
||||||
|
// Special case: A PHIDef value can have its def in the middle of a
|
||||||
|
// segment if the value happens to be live out of the layout
|
||||||
|
// predecessor.
|
||||||
|
// Such a value is not live-in.
|
||||||
|
if (EarlyVal->def == Idx.getBaseIndex())
|
||||||
|
EarlyVal = 0;
|
||||||
|
}
|
||||||
|
// I now points to the segment that may be live-through, or defined by
|
||||||
|
// this instr. Ignore segments starting after the current instr.
|
||||||
|
if (!SlotIndex::isEarlierInstr(Idx, I->start)) {
|
||||||
|
LateVal = I->valno;
|
||||||
|
EndPoint = I->end;
|
||||||
|
}
|
||||||
|
return LiveQueryResult(EarlyVal, LateVal, EndPoint, Kill);
|
||||||
|
}
|
||||||
|
|
||||||
/// removeValNo - Remove all the segments defined by the specified value#.
|
/// removeValNo - Remove all the segments defined by the specified value#.
|
||||||
/// Also remove the value# from value# list.
|
/// Also remove the value# from value# list.
|
||||||
void removeValNo(VNInfo *ValNo);
|
void removeValNo(VNInfo *ValNo);
|
||||||
@@ -532,102 +633,6 @@ namespace llvm {
|
|||||||
return OS;
|
return OS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// LiveRangeQuery - Query information about a live range around a given
|
|
||||||
/// instruction. This class hides the implementation details of live ranges,
|
|
||||||
/// and it should be used as the primary interface for examining live ranges
|
|
||||||
/// around instructions.
|
|
||||||
///
|
|
||||||
class LiveRangeQuery {
|
|
||||||
VNInfo *EarlyVal;
|
|
||||||
VNInfo *LateVal;
|
|
||||||
SlotIndex EndPoint;
|
|
||||||
bool Kill;
|
|
||||||
|
|
||||||
void init(const LiveRange &LR, SlotIndex Idx) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// Create a LiveRangeQuery for the given live range and instruction index.
|
|
||||||
/// The sub-instruction slot of Idx doesn't matter, only the instruction it
|
|
||||||
/// refers to is considered.
|
|
||||||
LiveRangeQuery(const LiveRange &LR, SlotIndex Idx)
|
|
||||||
: EarlyVal(0), LateVal(0), Kill(false) {
|
|
||||||
// Find the segment that enters the instruction.
|
|
||||||
LiveRange::const_iterator I = LR.find(Idx.getBaseIndex());
|
|
||||||
LiveRange::const_iterator E = LR.end();
|
|
||||||
if (I == E)
|
|
||||||
return;
|
|
||||||
// Is this an instruction live-in segment?
|
|
||||||
// If Idx is the start index of a basic block, include live-in segments
|
|
||||||
// that start at Idx.getBaseIndex().
|
|
||||||
if (I->start <= Idx.getBaseIndex()) {
|
|
||||||
EarlyVal = I->valno;
|
|
||||||
EndPoint = I->end;
|
|
||||||
// Move to the potentially live-out segment.
|
|
||||||
if (SlotIndex::isSameInstr(Idx, I->end)) {
|
|
||||||
Kill = true;
|
|
||||||
if (++I == E)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Special case: A PHIDef value can have its def in the middle of a
|
|
||||||
// segment if the value happens to be live out of the layout
|
|
||||||
// predecessor.
|
|
||||||
// Such a value is not live-in.
|
|
||||||
if (EarlyVal->def == Idx.getBaseIndex())
|
|
||||||
EarlyVal = 0;
|
|
||||||
}
|
|
||||||
// I now points to the segment that may be live-through, or defined by
|
|
||||||
// this instr. Ignore segments starting after the current instr.
|
|
||||||
if (SlotIndex::isEarlierInstr(Idx, I->start))
|
|
||||||
return;
|
|
||||||
LateVal = I->valno;
|
|
||||||
EndPoint = I->end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the value that is live-in to the instruction. This is the value
|
|
||||||
/// that will be read by the instruction's use operands. Return NULL if no
|
|
||||||
/// value is live-in.
|
|
||||||
VNInfo *valueIn() const {
|
|
||||||
return EarlyVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return true if the live-in value is killed by this instruction. This
|
|
||||||
/// means that either the live range ends at the instruction, or it changes
|
|
||||||
/// value.
|
|
||||||
bool isKill() const {
|
|
||||||
return Kill;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return true if this instruction has a dead def.
|
|
||||||
bool isDeadDef() const {
|
|
||||||
return EndPoint.isDead();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the value leaving the instruction, if any. This can be a
|
|
||||||
/// live-through value, or a live def. A dead def returns NULL.
|
|
||||||
VNInfo *valueOut() const {
|
|
||||||
return isDeadDef() ? 0 : LateVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the value defined by this instruction, if any. This includes
|
|
||||||
/// dead defs, it is the value created by the instruction's def operands.
|
|
||||||
VNInfo *valueDefined() const {
|
|
||||||
return EarlyVal == LateVal ? 0 : LateVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the end point of the last live range segment to interact with
|
|
||||||
/// the instruction, if any.
|
|
||||||
///
|
|
||||||
/// The end point is an invalid SlotIndex only if the live range doesn't
|
|
||||||
/// intersect the instruction at all.
|
|
||||||
///
|
|
||||||
/// The end point may be at or past the end of the instruction's basic
|
|
||||||
/// block. That means the value was live out of the block.
|
|
||||||
SlotIndex endPoint() const {
|
|
||||||
return EndPoint;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// ConnectedVNInfoEqClasses - Helper class that can divide VNInfos in a
|
/// ConnectedVNInfoEqClasses - Helper class that can divide VNInfos in a
|
||||||
/// LiveInterval into equivalence clases of connected components. A
|
/// LiveInterval into equivalence clases of connected components. A
|
||||||
/// LiveInterval that has multiple connected components can be broken into
|
/// LiveInterval that has multiple connected components can be broken into
|
||||||
|
|||||||
@@ -578,7 +578,7 @@ MachineInstr *InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI,
|
|||||||
if (unsigned SrcReg = isFullCopyOf(MI, Reg)) {
|
if (unsigned SrcReg = isFullCopyOf(MI, Reg)) {
|
||||||
if (isSibling(SrcReg)) {
|
if (isSibling(SrcReg)) {
|
||||||
LiveInterval &SrcLI = LIS.getInterval(SrcReg);
|
LiveInterval &SrcLI = LIS.getInterval(SrcReg);
|
||||||
LiveRangeQuery SrcQ(SrcLI, VNI->def);
|
LiveQueryResult SrcQ = SrcLI.Query(VNI->def);
|
||||||
assert(SrcQ.valueIn() && "Copy from non-existing value");
|
assert(SrcQ.valueIn() && "Copy from non-existing value");
|
||||||
// Check if this COPY kills its source.
|
// Check if this COPY kills its source.
|
||||||
SVI->second.KillsSource = SrcQ.isKill();
|
SVI->second.KillsSource = SrcQ.isKill();
|
||||||
|
|||||||
@@ -908,7 +908,7 @@ void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[],
|
|||||||
Idx = LIS.getSlotIndexes()->getIndexBefore(MI);
|
Idx = LIS.getSlotIndexes()->getIndexBefore(MI);
|
||||||
else
|
else
|
||||||
Idx = LIS.getInstructionIndex(MI);
|
Idx = LIS.getInstructionIndex(MI);
|
||||||
LiveRangeQuery LRQ(LI, Idx);
|
LiveQueryResult LRQ = LI.Query(Idx);
|
||||||
const VNInfo *VNI = MO.readsReg() ? LRQ.valueIn() : LRQ.valueDefined();
|
const VNInfo *VNI = MO.readsReg() ? LRQ.valueIn() : LRQ.valueDefined();
|
||||||
// In the case of an <undef> use that isn't tied to any def, VNI will be
|
// In the case of an <undef> use that isn't tied to any def, VNI will be
|
||||||
// NULL. If the use is tied to a def, VNI will be the defined value.
|
// NULL. If the use is tied to a def, VNI will be the defined value.
|
||||||
|
|||||||
@@ -329,7 +329,7 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li,
|
|||||||
if (UseMI->isDebugValue() || !UseMI->readsVirtualRegister(li->reg))
|
if (UseMI->isDebugValue() || !UseMI->readsVirtualRegister(li->reg))
|
||||||
continue;
|
continue;
|
||||||
SlotIndex Idx = getInstructionIndex(UseMI).getRegSlot();
|
SlotIndex Idx = getInstructionIndex(UseMI).getRegSlot();
|
||||||
LiveRangeQuery LRQ(*li, Idx);
|
LiveQueryResult LRQ = li->Query(Idx);
|
||||||
VNInfo *VNI = LRQ.valueIn();
|
VNInfo *VNI = LRQ.valueIn();
|
||||||
if (!VNI) {
|
if (!VNI) {
|
||||||
// This shouldn't happen: readsVirtualRegister returns true, but there is
|
// This shouldn't happen: readsVirtualRegister returns true, but there is
|
||||||
@@ -450,7 +450,7 @@ void LiveIntervals::extendToIndices(LiveInterval *LI,
|
|||||||
|
|
||||||
void LiveIntervals::pruneValue(LiveInterval *LI, SlotIndex Kill,
|
void LiveIntervals::pruneValue(LiveInterval *LI, SlotIndex Kill,
|
||||||
SmallVectorImpl<SlotIndex> *EndPoints) {
|
SmallVectorImpl<SlotIndex> *EndPoints) {
|
||||||
LiveRangeQuery LRQ(*LI, Kill);
|
LiveQueryResult LRQ = LI->Query(Kill);
|
||||||
VNInfo *VNI = LRQ.valueOut();
|
VNInfo *VNI = LRQ.valueOut();
|
||||||
if (!VNI)
|
if (!VNI)
|
||||||
return;
|
return;
|
||||||
@@ -485,7 +485,7 @@ void LiveIntervals::pruneValue(LiveInterval *LI, SlotIndex Kill,
|
|||||||
|
|
||||||
// Check if VNI is live in to MBB.
|
// Check if VNI is live in to MBB.
|
||||||
tie(MBBStart, MBBEnd) = Indexes->getMBBRange(MBB);
|
tie(MBBStart, MBBEnd) = Indexes->getMBBRange(MBB);
|
||||||
LiveRangeQuery LRQ(*LI, MBBStart);
|
LiveQueryResult LRQ = LI->Query(MBBStart);
|
||||||
if (LRQ.valueIn() != VNI) {
|
if (LRQ.valueIn() != VNI) {
|
||||||
// This block isn't part of the VNI segment. Prune the search.
|
// This block isn't part of the VNI segment. Prune the search.
|
||||||
I.skipChildren();
|
I.skipChildren();
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) {
|
|||||||
// Always shrink COPY uses that probably come from live range splitting.
|
// Always shrink COPY uses that probably come from live range splitting.
|
||||||
if (MI->readsVirtualRegister(Reg) &&
|
if (MI->readsVirtualRegister(Reg) &&
|
||||||
(MI->isCopy() || MOI->isDef() || MRI.hasOneNonDBGUse(Reg) ||
|
(MI->isCopy() || MOI->isDef() || MRI.hasOneNonDBGUse(Reg) ||
|
||||||
LiveRangeQuery(LI, Idx).isKill()))
|
LI.Query(Idx).isKill()))
|
||||||
ToShrink.insert(&LI);
|
ToShrink.insert(&LI);
|
||||||
|
|
||||||
// Remove defined value.
|
// Remove defined value.
|
||||||
|
|||||||
@@ -610,7 +610,7 @@ void ScheduleDAGMI::updatePressureDiffs(ArrayRef<unsigned> LiveUses) {
|
|||||||
if (I == BB->end())
|
if (I == BB->end())
|
||||||
VNI = LI.getVNInfoBefore(LIS->getMBBEndIdx(BB));
|
VNI = LI.getVNInfoBefore(LIS->getMBBEndIdx(BB));
|
||||||
else {
|
else {
|
||||||
LiveRangeQuery LRQ(LI, LIS->getInstructionIndex(I));
|
LiveQueryResult LRQ = LI.Query(LIS->getInstructionIndex(I));
|
||||||
VNI = LRQ.valueIn();
|
VNI = LRQ.valueIn();
|
||||||
}
|
}
|
||||||
// RegisterPressureTracker guarantees that readsReg is true for LiveUses.
|
// RegisterPressureTracker guarantees that readsReg is true for LiveUses.
|
||||||
@@ -623,7 +623,8 @@ void ScheduleDAGMI::updatePressureDiffs(ArrayRef<unsigned> LiveUses) {
|
|||||||
// If this use comes before the reaching def, it cannot be a last use, so
|
// If this use comes before the reaching def, it cannot be a last use, so
|
||||||
// descrease its pressure change.
|
// descrease its pressure change.
|
||||||
if (!SU->isScheduled && SU != &ExitSU) {
|
if (!SU->isScheduled && SU != &ExitSU) {
|
||||||
LiveRangeQuery LRQ(LI, LIS->getInstructionIndex(SU->getInstr()));
|
LiveQueryResult LRQ
|
||||||
|
= LI.Query(LIS->getInstructionIndex(SU->getInstr()));
|
||||||
if (LRQ.valueIn() == VNI)
|
if (LRQ.valueIn() == VNI)
|
||||||
getPressureDiff(SU).addPressureChange(Reg, true, &MRI);
|
getPressureDiff(SU).addPressureChange(Reg, true, &MRI);
|
||||||
}
|
}
|
||||||
@@ -800,7 +801,8 @@ unsigned ScheduleDAGMI::computeCyclicCriticalPath() {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Only consider uses of the phi.
|
// Only consider uses of the phi.
|
||||||
LiveRangeQuery LRQ(LI, LIS->getInstructionIndex(UI->SU->getInstr()));
|
LiveQueryResult LRQ =
|
||||||
|
LI.Query(LIS->getInstructionIndex(UI->SU->getInstr()));
|
||||||
if (!LRQ.valueIn()->isPHIDef())
|
if (!LRQ.valueIn()->isPHIDef())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@@ -1002,7 +1002,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
|
|||||||
if (TargetRegisterInfo::isPhysicalRegister(Reg) && !isReserved(Reg)) {
|
if (TargetRegisterInfo::isPhysicalRegister(Reg) && !isReserved(Reg)) {
|
||||||
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) {
|
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) {
|
||||||
if (const LiveInterval *LI = LiveInts->getCachedRegUnit(*Units)) {
|
if (const LiveInterval *LI = LiveInts->getCachedRegUnit(*Units)) {
|
||||||
LiveRangeQuery LRQ(*LI, UseIdx);
|
LiveQueryResult LRQ = LI->Query(UseIdx);
|
||||||
if (!LRQ.valueIn()) {
|
if (!LRQ.valueIn()) {
|
||||||
report("No live segment at use", MO, MONum);
|
report("No live segment at use", MO, MONum);
|
||||||
*OS << UseIdx << " is not live in " << PrintRegUnit(*Units, TRI)
|
*OS << UseIdx << " is not live in " << PrintRegUnit(*Units, TRI)
|
||||||
@@ -1020,7 +1020,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
|
|||||||
if (LiveInts->hasInterval(Reg)) {
|
if (LiveInts->hasInterval(Reg)) {
|
||||||
// This is a virtual register interval.
|
// This is a virtual register interval.
|
||||||
const LiveInterval &LI = LiveInts->getInterval(Reg);
|
const LiveInterval &LI = LiveInts->getInterval(Reg);
|
||||||
LiveRangeQuery LRQ(LI, UseIdx);
|
LiveQueryResult LRQ = LI.Query(UseIdx);
|
||||||
if (!LRQ.valueIn()) {
|
if (!LRQ.valueIn()) {
|
||||||
report("No live segment at use", MO, MONum);
|
report("No live segment at use", MO, MONum);
|
||||||
*OS << UseIdx << " is not live in " << LI << '\n';
|
*OS << UseIdx << " is not live in " << LI << '\n';
|
||||||
|
|||||||
@@ -612,7 +612,7 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
|
|||||||
|
|
||||||
MachineOperand &NewDstMO = DefMI->getOperand(NewDstIdx);
|
MachineOperand &NewDstMO = DefMI->getOperand(NewDstIdx);
|
||||||
unsigned NewReg = NewDstMO.getReg();
|
unsigned NewReg = NewDstMO.getReg();
|
||||||
if (NewReg != IntB.reg || !LiveRangeQuery(IntB, AValNo->def).isKill())
|
if (NewReg != IntB.reg || !IntB.Query(AValNo->def).isKill())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Make sure there are no other definitions of IntB that would reach the
|
// Make sure there are no other definitions of IntB that would reach the
|
||||||
@@ -742,7 +742,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(CoalescerPair &CP,
|
|||||||
|
|
||||||
LiveInterval &SrcInt = LIS->getInterval(SrcReg);
|
LiveInterval &SrcInt = LIS->getInterval(SrcReg);
|
||||||
SlotIndex CopyIdx = LIS->getInstructionIndex(CopyMI);
|
SlotIndex CopyIdx = LIS->getInstructionIndex(CopyMI);
|
||||||
VNInfo *ValNo = LiveRangeQuery(SrcInt, CopyIdx).valueIn();
|
VNInfo *ValNo = SrcInt.Query(CopyIdx).valueIn();
|
||||||
assert(ValNo && "CopyMI input register not live");
|
assert(ValNo && "CopyMI input register not live");
|
||||||
if (ValNo->isPHIDef() || ValNo->isUnused())
|
if (ValNo->isPHIDef() || ValNo->isUnused())
|
||||||
return false;
|
return false;
|
||||||
@@ -1046,7 +1046,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
|
|||||||
if (CP.getSrcReg() == CP.getDstReg()) {
|
if (CP.getSrcReg() == CP.getDstReg()) {
|
||||||
LiveInterval &LI = LIS->getInterval(CP.getSrcReg());
|
LiveInterval &LI = LIS->getInterval(CP.getSrcReg());
|
||||||
DEBUG(dbgs() << "\tCopy already coalesced: " << LI << '\n');
|
DEBUG(dbgs() << "\tCopy already coalesced: " << LI << '\n');
|
||||||
LiveRangeQuery LRQ(LI, LIS->getInstructionIndex(CopyMI));
|
LiveQueryResult LRQ = LI.Query(LIS->getInstructionIndex(CopyMI));
|
||||||
if (VNInfo *DefVNI = LRQ.valueDefined()) {
|
if (VNInfo *DefVNI = LRQ.valueDefined()) {
|
||||||
VNInfo *ReadVNI = LRQ.valueIn();
|
VNInfo *ReadVNI = LRQ.valueIn();
|
||||||
assert(ReadVNI && "No value before copy and no <undef> flag.");
|
assert(ReadVNI && "No value before copy and no <undef> flag.");
|
||||||
@@ -1441,7 +1441,7 @@ VNInfo *JoinVals::stripCopies(VNInfo *VNI) {
|
|||||||
unsigned Reg = MI->getOperand(1).getReg();
|
unsigned Reg = MI->getOperand(1).getReg();
|
||||||
if (!TargetRegisterInfo::isVirtualRegister(Reg))
|
if (!TargetRegisterInfo::isVirtualRegister(Reg))
|
||||||
break;
|
break;
|
||||||
LiveRangeQuery LRQ(LIS->getInterval(Reg), VNI->def);
|
LiveQueryResult LRQ = LIS->getInterval(Reg).Query(VNI->def);
|
||||||
if (!LRQ.valueIn())
|
if (!LRQ.valueIn())
|
||||||
break;
|
break;
|
||||||
VNI = LRQ.valueIn();
|
VNI = LRQ.valueIn();
|
||||||
@@ -1492,7 +1492,7 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
|
|||||||
// The <read-undef> flag on the def operand means that old lane values are
|
// The <read-undef> flag on the def operand means that old lane values are
|
||||||
// not important.
|
// not important.
|
||||||
if (Redef) {
|
if (Redef) {
|
||||||
V.RedefVNI = LiveRangeQuery(LI, VNI->def).valueIn();
|
V.RedefVNI = LI.Query(VNI->def).valueIn();
|
||||||
assert(V.RedefVNI && "Instruction is reading nonexistent value");
|
assert(V.RedefVNI && "Instruction is reading nonexistent value");
|
||||||
computeAssignment(V.RedefVNI->id, Other);
|
computeAssignment(V.RedefVNI->id, Other);
|
||||||
V.ValidLanes |= Vals[V.RedefVNI->id].ValidLanes;
|
V.ValidLanes |= Vals[V.RedefVNI->id].ValidLanes;
|
||||||
@@ -1509,7 +1509,7 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find the value in Other that overlaps VNI->def, if any.
|
// Find the value in Other that overlaps VNI->def, if any.
|
||||||
LiveRangeQuery OtherLRQ(Other.LI, VNI->def);
|
LiveQueryResult OtherLRQ = Other.LI.Query(VNI->def);
|
||||||
|
|
||||||
// It is possible that both values are defined by the same instruction, or
|
// It is possible that both values are defined by the same instruction, or
|
||||||
// the values are PHIs defined in the same block. When that happens, the two
|
// the values are PHIs defined in the same block. When that happens, the two
|
||||||
|
|||||||
@@ -513,7 +513,7 @@ bool RegPressureTracker::recede(SmallVectorImpl<unsigned> *LiveUses,
|
|||||||
const LiveInterval *LI = getInterval(Reg);
|
const LiveInterval *LI = getInterval(Reg);
|
||||||
// Check if this LR is killed and not redefined here.
|
// Check if this LR is killed and not redefined here.
|
||||||
if (LI) {
|
if (LI) {
|
||||||
LiveRangeQuery LRQ(*LI, SlotIdx);
|
LiveQueryResult LRQ = LI->Query(SlotIdx);
|
||||||
if (!LRQ.isKill() && !LRQ.valueDefined())
|
if (!LRQ.isKill() && !LRQ.valueDefined())
|
||||||
discoverLiveOut(Reg);
|
discoverLiveOut(Reg);
|
||||||
}
|
}
|
||||||
@@ -571,7 +571,7 @@ bool RegPressureTracker::advance() {
|
|||||||
bool lastUse = false;
|
bool lastUse = false;
|
||||||
if (RequireIntervals) {
|
if (RequireIntervals) {
|
||||||
const LiveInterval *LI = getInterval(Reg);
|
const LiveInterval *LI = getInterval(Reg);
|
||||||
lastUse = LI && LiveRangeQuery(*LI, SlotIdx).isKill();
|
lastUse = LI && LI->Query(SlotIdx).isKill();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Allocatable physregs are always single-use before register rewriting.
|
// Allocatable physregs are always single-use before register rewriting.
|
||||||
@@ -896,7 +896,7 @@ void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
|
|||||||
SlotIndex CurrIdx = getCurrSlot();
|
SlotIndex CurrIdx = getCurrSlot();
|
||||||
const LiveInterval *LI = getInterval(Reg);
|
const LiveInterval *LI = getInterval(Reg);
|
||||||
if (LI) {
|
if (LI) {
|
||||||
LiveRangeQuery LRQ(*LI, SlotIdx);
|
LiveQueryResult LRQ = LI->Query(SlotIdx);
|
||||||
if (LRQ.isKill() && !findUseBetween(Reg, CurrIdx, SlotIdx, MRI, LIS))
|
if (LRQ.isKill() && !findUseBetween(Reg, CurrIdx, SlotIdx, MRI, LIS))
|
||||||
decreaseRegPressure(Reg);
|
decreaseRegPressure(Reg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -415,7 +415,8 @@ void ScheduleDAGInstrs::addVRegUseDeps(SUnit *SU, unsigned OperIdx) {
|
|||||||
|
|
||||||
// Lookup this operand's reaching definition.
|
// Lookup this operand's reaching definition.
|
||||||
assert(LIS && "vreg dependencies requires LiveIntervals");
|
assert(LIS && "vreg dependencies requires LiveIntervals");
|
||||||
LiveRangeQuery LRQ(LIS->getInterval(Reg), LIS->getInstructionIndex(MI));
|
LiveQueryResult LRQ
|
||||||
|
= LIS->getInterval(Reg).Query(LIS->getInstructionIndex(MI));
|
||||||
VNInfo *VNI = LRQ.valueIn();
|
VNInfo *VNI = LRQ.valueIn();
|
||||||
|
|
||||||
// VNI will be valid because MachineOperand::readsReg() is checked by caller.
|
// VNI will be valid because MachineOperand::readsReg() is checked by caller.
|
||||||
|
|||||||
Reference in New Issue
Block a user