aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2013-10-10 21:28:52 +0000
committerMatthias Braun <matze@braunis.de>2013-10-10 21:28:52 +0000
commit5649e25ce86b9d89d228ae7c392413571b0f8c19 (patch)
tree5d52d34808f1ab241f9cdc53e4fe889d76a0f6cb
parent87a86058fa0726328de42ace85b5532d18775646 (diff)
downloadexternal_llvm-5649e25ce86b9d89d228ae7c392413571b0f8c19.zip
external_llvm-5649e25ce86b9d89d228ae7c392413571b0f8c19.tar.gz
external_llvm-5649e25ce86b9d89d228ae7c392413571b0f8c19.tar.bz2
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
-rw-r--r--include/llvm/CodeGen/LiveInterval.h197
-rw-r--r--lib/CodeGen/InlineSpiller.cpp2
-rw-r--r--lib/CodeGen/LiveInterval.cpp2
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp6
-rw-r--r--lib/CodeGen/LiveRangeEdit.cpp2
-rw-r--r--lib/CodeGen/MachineScheduler.cpp8
-rw-r--r--lib/CodeGen/MachineVerifier.cpp4
-rw-r--r--lib/CodeGen/RegisterCoalescer.cpp12
-rw-r--r--lib/CodeGen/RegisterPressure.cpp6
-rw-r--r--lib/CodeGen/ScheduleDAGInstrs.cpp3
10 files changed, 125 insertions, 117 deletions
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index 11c45e4..d28cb04 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -79,6 +79,65 @@ namespace llvm {
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.
/// It manages an ordered list of Segment objects.
/// The Segments are organized in a static single assignment form: At places
@@ -376,6 +435,48 @@ namespace llvm {
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#.
/// Also remove the value# from value# list.
void removeValNo(VNInfo *ValNo);
@@ -532,102 +633,6 @@ namespace llvm {
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
/// LiveInterval into equivalence clases of connected components. A
/// LiveInterval that has multiple connected components can be broken into
diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp
index 2ee6755..85bf4ef 100644
--- a/lib/CodeGen/InlineSpiller.cpp
+++ b/lib/CodeGen/InlineSpiller.cpp
@@ -578,7 +578,7 @@ MachineInstr *InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI,
if (unsigned SrcReg = isFullCopyOf(MI, Reg)) {
if (isSibling(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");
// Check if this COPY kills its source.
SVI->second.KillsSource = SrcQ.isKill();
diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp
index e231d27..f7b5d64 100644
--- a/lib/CodeGen/LiveInterval.cpp
+++ b/lib/CodeGen/LiveInterval.cpp
@@ -908,7 +908,7 @@ void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[],
Idx = LIS.getSlotIndexes()->getIndexBefore(MI);
else
Idx = LIS.getInstructionIndex(MI);
- LiveRangeQuery LRQ(LI, Idx);
+ LiveQueryResult LRQ = LI.Query(Idx);
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
// NULL. If the use is tied to a def, VNI will be the defined value.
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 5111785..4c0e058 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -329,7 +329,7 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li,
if (UseMI->isDebugValue() || !UseMI->readsVirtualRegister(li->reg))
continue;
SlotIndex Idx = getInstructionIndex(UseMI).getRegSlot();
- LiveRangeQuery LRQ(*li, Idx);
+ LiveQueryResult LRQ = li->Query(Idx);
VNInfo *VNI = LRQ.valueIn();
if (!VNI) {
// 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,
SmallVectorImpl<SlotIndex> *EndPoints) {
- LiveRangeQuery LRQ(*LI, Kill);
+ LiveQueryResult LRQ = LI->Query(Kill);
VNInfo *VNI = LRQ.valueOut();
if (!VNI)
return;
@@ -485,7 +485,7 @@ void LiveIntervals::pruneValue(LiveInterval *LI, SlotIndex Kill,
// Check if VNI is live in to MBB.
tie(MBBStart, MBBEnd) = Indexes->getMBBRange(MBB);
- LiveRangeQuery LRQ(*LI, MBBStart);
+ LiveQueryResult LRQ = LI->Query(MBBStart);
if (LRQ.valueIn() != VNI) {
// This block isn't part of the VNI segment. Prune the search.
I.skipChildren();
diff --git a/lib/CodeGen/LiveRangeEdit.cpp b/lib/CodeGen/LiveRangeEdit.cpp
index 9c374b1..d5990ef 100644
--- a/lib/CodeGen/LiveRangeEdit.cpp
+++ b/lib/CodeGen/LiveRangeEdit.cpp
@@ -278,7 +278,7 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) {
// Always shrink COPY uses that probably come from live range splitting.
if (MI->readsVirtualRegister(Reg) &&
(MI->isCopy() || MOI->isDef() || MRI.hasOneNonDBGUse(Reg) ||
- LiveRangeQuery(LI, Idx).isKill()))
+ LI.Query(Idx).isKill()))
ToShrink.insert(&LI);
// Remove defined value.
diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp
index 764adaf..3144dfe 100644
--- a/lib/CodeGen/MachineScheduler.cpp
+++ b/lib/CodeGen/MachineScheduler.cpp
@@ -610,7 +610,7 @@ void ScheduleDAGMI::updatePressureDiffs(ArrayRef<unsigned> LiveUses) {
if (I == BB->end())
VNI = LI.getVNInfoBefore(LIS->getMBBEndIdx(BB));
else {
- LiveRangeQuery LRQ(LI, LIS->getInstructionIndex(I));
+ LiveQueryResult LRQ = LI.Query(LIS->getInstructionIndex(I));
VNI = LRQ.valueIn();
}
// 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
// descrease its pressure change.
if (!SU->isScheduled && SU != &ExitSU) {
- LiveRangeQuery LRQ(LI, LIS->getInstructionIndex(SU->getInstr()));
+ LiveQueryResult LRQ
+ = LI.Query(LIS->getInstructionIndex(SU->getInstr()));
if (LRQ.valueIn() == VNI)
getPressureDiff(SU).addPressureChange(Reg, true, &MRI);
}
@@ -800,7 +801,8 @@ unsigned ScheduleDAGMI::computeCyclicCriticalPath() {
continue;
// 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())
continue;
diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp
index e3c4432..5c2976e 100644
--- a/lib/CodeGen/MachineVerifier.cpp
+++ b/lib/CodeGen/MachineVerifier.cpp
@@ -1002,7 +1002,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
if (TargetRegisterInfo::isPhysicalRegister(Reg) && !isReserved(Reg)) {
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) {
if (const LiveInterval *LI = LiveInts->getCachedRegUnit(*Units)) {
- LiveRangeQuery LRQ(*LI, UseIdx);
+ LiveQueryResult LRQ = LI->Query(UseIdx);
if (!LRQ.valueIn()) {
report("No live segment at use", MO, MONum);
*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)) {
// This is a virtual register interval.
const LiveInterval &LI = LiveInts->getInterval(Reg);
- LiveRangeQuery LRQ(LI, UseIdx);
+ LiveQueryResult LRQ = LI.Query(UseIdx);
if (!LRQ.valueIn()) {
report("No live segment at use", MO, MONum);
*OS << UseIdx << " is not live in " << LI << '\n';
diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp
index ef54663..578653d 100644
--- a/lib/CodeGen/RegisterCoalescer.cpp
+++ b/lib/CodeGen/RegisterCoalescer.cpp
@@ -612,7 +612,7 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
MachineOperand &NewDstMO = DefMI->getOperand(NewDstIdx);
unsigned NewReg = NewDstMO.getReg();
- if (NewReg != IntB.reg || !LiveRangeQuery(IntB, AValNo->def).isKill())
+ if (NewReg != IntB.reg || !IntB.Query(AValNo->def).isKill())
return false;
// 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);
SlotIndex CopyIdx = LIS->getInstructionIndex(CopyMI);
- VNInfo *ValNo = LiveRangeQuery(SrcInt, CopyIdx).valueIn();
+ VNInfo *ValNo = SrcInt.Query(CopyIdx).valueIn();
assert(ValNo && "CopyMI input register not live");
if (ValNo->isPHIDef() || ValNo->isUnused())
return false;
@@ -1046,7 +1046,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
if (CP.getSrcReg() == CP.getDstReg()) {
LiveInterval &LI = LIS->getInterval(CP.getSrcReg());
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()) {
VNInfo *ReadVNI = LRQ.valueIn();
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();
if (!TargetRegisterInfo::isVirtualRegister(Reg))
break;
- LiveRangeQuery LRQ(LIS->getInterval(Reg), VNI->def);
+ LiveQueryResult LRQ = LIS->getInterval(Reg).Query(VNI->def);
if (!LRQ.valueIn())
break;
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
// not important.
if (Redef) {
- V.RedefVNI = LiveRangeQuery(LI, VNI->def).valueIn();
+ V.RedefVNI = LI.Query(VNI->def).valueIn();
assert(V.RedefVNI && "Instruction is reading nonexistent value");
computeAssignment(V.RedefVNI->id, Other);
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.
- 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
// the values are PHIs defined in the same block. When that happens, the two
diff --git a/lib/CodeGen/RegisterPressure.cpp b/lib/CodeGen/RegisterPressure.cpp
index 260eacd..2f273a3 100644
--- a/lib/CodeGen/RegisterPressure.cpp
+++ b/lib/CodeGen/RegisterPressure.cpp
@@ -513,7 +513,7 @@ bool RegPressureTracker::recede(SmallVectorImpl<unsigned> *LiveUses,
const LiveInterval *LI = getInterval(Reg);
// Check if this LR is killed and not redefined here.
if (LI) {
- LiveRangeQuery LRQ(*LI, SlotIdx);
+ LiveQueryResult LRQ = LI->Query(SlotIdx);
if (!LRQ.isKill() && !LRQ.valueDefined())
discoverLiveOut(Reg);
}
@@ -571,7 +571,7 @@ bool RegPressureTracker::advance() {
bool lastUse = false;
if (RequireIntervals) {
const LiveInterval *LI = getInterval(Reg);
- lastUse = LI && LiveRangeQuery(*LI, SlotIdx).isKill();
+ lastUse = LI && LI->Query(SlotIdx).isKill();
}
else {
// Allocatable physregs are always single-use before register rewriting.
@@ -896,7 +896,7 @@ void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
SlotIndex CurrIdx = getCurrSlot();
const LiveInterval *LI = getInterval(Reg);
if (LI) {
- LiveRangeQuery LRQ(*LI, SlotIdx);
+ LiveQueryResult LRQ = LI->Query(SlotIdx);
if (LRQ.isKill() && !findUseBetween(Reg, CurrIdx, SlotIdx, MRI, LIS))
decreaseRegPressure(Reg);
}
diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp
index d940dbc..7f1f9c4 100644
--- a/lib/CodeGen/ScheduleDAGInstrs.cpp
+++ b/lib/CodeGen/ScheduleDAGInstrs.cpp
@@ -415,7 +415,8 @@ void ScheduleDAGInstrs::addVRegUseDeps(SUnit *SU, unsigned OperIdx) {
// Lookup this operand's reaching definition.
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();
// VNI will be valid because MachineOperand::readsReg() is checked by caller.