forked from OSchip/llvm-project
Eliminate the last use of InterferenceResult.
The Query class now holds two iterators instead of an InterferenceResult instance. The iterators are used as bookmarks for repeated collectInterferingVRegs calls. llvm-svn: 137380
This commit is contained in:
parent
79d60d0e94
commit
cd14efaec2
|
@ -117,68 +117,35 @@ void LiveIntervalUnion::verify(LiveVirtRegBitSet& VisitedVRegs) {
|
||||||
//
|
//
|
||||||
// Assumes that segments are sorted by start position in both
|
// Assumes that segments are sorted by start position in both
|
||||||
// LiveInterval and LiveSegments.
|
// LiveInterval and LiveSegments.
|
||||||
void LiveIntervalUnion::Query::findIntersection(InterferenceResult &IR) const {
|
void LiveIntervalUnion::Query::findIntersection() {
|
||||||
// Search until reaching the end of the LiveUnion segments.
|
// Search until reaching the end of the LiveUnion segments.
|
||||||
LiveInterval::iterator VirtRegEnd = VirtReg->end();
|
LiveInterval::iterator VirtRegEnd = VirtReg->end();
|
||||||
if (IR.VirtRegI == VirtRegEnd)
|
if (VirtRegI == VirtRegEnd)
|
||||||
return;
|
return;
|
||||||
while (IR.LiveUnionI.valid()) {
|
while (LiveUnionI.valid()) {
|
||||||
// Slowly advance the live virtual reg iterator until we surpass the next
|
// Slowly advance the live virtual reg iterator until we surpass the next
|
||||||
// segment in LiveUnion.
|
// segment in LiveUnion.
|
||||||
//
|
//
|
||||||
// Note: If this is ever used for coalescing of fixed registers and we have
|
// Note: If this is ever used for coalescing of fixed registers and we have
|
||||||
// a live vreg with thousands of segments, then change this code to use
|
// a live vreg with thousands of segments, then change this code to use
|
||||||
// upperBound instead.
|
// upperBound instead.
|
||||||
IR.VirtRegI = VirtReg->advanceTo(IR.VirtRegI, IR.LiveUnionI.start());
|
VirtRegI = VirtReg->advanceTo(VirtRegI, LiveUnionI.start());
|
||||||
if (IR.VirtRegI == VirtRegEnd)
|
if (VirtRegI == VirtRegEnd)
|
||||||
break; // Retain current (nonoverlapping) LiveUnionI
|
break; // Retain current (nonoverlapping) LiveUnionI
|
||||||
|
|
||||||
// VirtRegI may have advanced far beyond LiveUnionI, catch up.
|
// VirtRegI may have advanced far beyond LiveUnionI, catch up.
|
||||||
IR.LiveUnionI.advanceTo(IR.VirtRegI->start);
|
LiveUnionI.advanceTo(VirtRegI->start);
|
||||||
|
|
||||||
// Check if no LiveUnionI exists with VirtRegI->Start < LiveUnionI.end
|
// Check if no LiveUnionI exists with VirtRegI->Start < LiveUnionI.end
|
||||||
if (!IR.LiveUnionI.valid())
|
if (!LiveUnionI.valid())
|
||||||
break;
|
break;
|
||||||
if (IR.LiveUnionI.start() < IR.VirtRegI->end) {
|
if (LiveUnionI.start() < VirtRegI->end) {
|
||||||
assert(overlap(*IR.VirtRegI, IR.LiveUnionI) &&
|
assert(overlap(*VirtRegI, LiveUnionI) && "upperBound postcondition");
|
||||||
"upperBound postcondition");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!IR.LiveUnionI.valid())
|
if (!LiveUnionI.valid())
|
||||||
IR.VirtRegI = VirtRegEnd;
|
VirtRegI = VirtRegEnd;
|
||||||
}
|
|
||||||
|
|
||||||
// Find the first intersection, and cache interference info
|
|
||||||
// (retain segment iterators into both VirtReg and LiveUnion).
|
|
||||||
const LiveIntervalUnion::InterferenceResult &
|
|
||||||
LiveIntervalUnion::Query::firstInterference() {
|
|
||||||
if (CheckedFirstInterference)
|
|
||||||
return FirstInterference;
|
|
||||||
CheckedFirstInterference = true;
|
|
||||||
InterferenceResult &IR = FirstInterference;
|
|
||||||
IR.LiveUnionI.setMap(LiveUnion->getMap());
|
|
||||||
|
|
||||||
// Quickly skip interference check for empty sets.
|
|
||||||
if (VirtReg->empty() || LiveUnion->empty()) {
|
|
||||||
IR.VirtRegI = VirtReg->end();
|
|
||||||
} else if (VirtReg->beginIndex() < LiveUnion->startIndex()) {
|
|
||||||
// VirtReg starts first, perform double binary search.
|
|
||||||
IR.VirtRegI = VirtReg->find(LiveUnion->startIndex());
|
|
||||||
if (IR.VirtRegI != VirtReg->end())
|
|
||||||
IR.LiveUnionI.find(IR.VirtRegI->start);
|
|
||||||
} else {
|
|
||||||
// LiveUnion starts first, perform double binary search.
|
|
||||||
IR.LiveUnionI.find(VirtReg->beginIndex());
|
|
||||||
if (IR.LiveUnionI.valid())
|
|
||||||
IR.VirtRegI = VirtReg->find(IR.LiveUnionI.start());
|
|
||||||
else
|
|
||||||
IR.VirtRegI = VirtReg->end();
|
|
||||||
}
|
|
||||||
findIntersection(FirstInterference);
|
|
||||||
assert((IR.VirtRegI == VirtReg->end() || IR.LiveUnionI.valid())
|
|
||||||
&& "Uninitialized iterator");
|
|
||||||
return FirstInterference;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan the vector of interfering virtual registers in this union. Assume it's
|
// Scan the vector of interfering virtual registers in this union. Assume it's
|
||||||
|
@ -200,37 +167,64 @@ bool LiveIntervalUnion::Query::isSeenInterference(LiveInterval *VirtReg) const {
|
||||||
// For comments on how to speed it up, see Query::findIntersection().
|
// For comments on how to speed it up, see Query::findIntersection().
|
||||||
unsigned LiveIntervalUnion::Query::
|
unsigned LiveIntervalUnion::Query::
|
||||||
collectInterferingVRegs(unsigned MaxInterferingRegs) {
|
collectInterferingVRegs(unsigned MaxInterferingRegs) {
|
||||||
if (InterferingVRegs.size() >= MaxInterferingRegs)
|
// Fast path return if we already have the desired information.
|
||||||
|
if (SeenAllInterferences || InterferingVRegs.size() >= MaxInterferingRegs)
|
||||||
return InterferingVRegs.size();
|
return InterferingVRegs.size();
|
||||||
InterferenceResult IR = firstInterference();
|
|
||||||
|
// Set up iterators on the first call.
|
||||||
|
if (!CheckedFirstInterference) {
|
||||||
|
CheckedFirstInterference = true;
|
||||||
|
LiveUnionI.setMap(LiveUnion->getMap());
|
||||||
|
|
||||||
|
// Quickly skip interference check for empty sets.
|
||||||
|
if (VirtReg->empty() || LiveUnion->empty()) {
|
||||||
|
VirtRegI = VirtReg->end();
|
||||||
|
} else if (VirtReg->beginIndex() < LiveUnion->startIndex()) {
|
||||||
|
// VirtReg starts first, perform double binary search.
|
||||||
|
VirtRegI = VirtReg->find(LiveUnion->startIndex());
|
||||||
|
if (VirtRegI != VirtReg->end())
|
||||||
|
LiveUnionI.find(VirtRegI->start);
|
||||||
|
} else {
|
||||||
|
// LiveUnion starts first, perform double binary search.
|
||||||
|
LiveUnionI.find(VirtReg->beginIndex());
|
||||||
|
if (LiveUnionI.valid())
|
||||||
|
VirtRegI = VirtReg->find(LiveUnionI.start());
|
||||||
|
else
|
||||||
|
VirtRegI = VirtReg->end();
|
||||||
|
}
|
||||||
|
findIntersection();
|
||||||
|
assert((VirtRegI == VirtReg->end() || LiveUnionI.valid())
|
||||||
|
&& "Uninitialized iterator");
|
||||||
|
}
|
||||||
|
|
||||||
LiveInterval::iterator VirtRegEnd = VirtReg->end();
|
LiveInterval::iterator VirtRegEnd = VirtReg->end();
|
||||||
LiveInterval *RecentInterferingVReg = NULL;
|
LiveInterval *RecentInterferingVReg = NULL;
|
||||||
if (IR.VirtRegI != VirtRegEnd) while (IR.LiveUnionI.valid()) {
|
if (VirtRegI != VirtRegEnd) while (LiveUnionI.valid()) {
|
||||||
// Advance the union's iterator to reach an unseen interfering vreg.
|
// Advance the union's iterator to reach an unseen interfering vreg.
|
||||||
do {
|
do {
|
||||||
if (IR.LiveUnionI.value() == RecentInterferingVReg)
|
if (LiveUnionI.value() == RecentInterferingVReg)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!isSeenInterference(IR.LiveUnionI.value()))
|
if (!isSeenInterference(LiveUnionI.value()))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Cache the most recent interfering vreg to bypass isSeenInterference.
|
// Cache the most recent interfering vreg to bypass isSeenInterference.
|
||||||
RecentInterferingVReg = IR.LiveUnionI.value();
|
RecentInterferingVReg = LiveUnionI.value();
|
||||||
|
|
||||||
} while ((++IR.LiveUnionI).valid());
|
} while ((++LiveUnionI).valid());
|
||||||
if (!IR.LiveUnionI.valid())
|
if (!LiveUnionI.valid())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Advance the VirtReg iterator until surpassing the next segment in
|
// Advance the VirtReg iterator until surpassing the next segment in
|
||||||
// LiveUnion.
|
// LiveUnion.
|
||||||
IR.VirtRegI = VirtReg->advanceTo(IR.VirtRegI, IR.LiveUnionI.start());
|
VirtRegI = VirtReg->advanceTo(VirtRegI, LiveUnionI.start());
|
||||||
if (IR.VirtRegI == VirtRegEnd)
|
if (VirtRegI == VirtRegEnd)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Check for intersection with the union's segment.
|
// Check for intersection with the union's segment.
|
||||||
if (overlap(*IR.VirtRegI, IR.LiveUnionI)) {
|
if (overlap(*VirtRegI, LiveUnionI)) {
|
||||||
|
|
||||||
if (!IR.LiveUnionI.value()->isSpillable())
|
if (!LiveUnionI.value()->isSpillable())
|
||||||
SeenUnspillableVReg = true;
|
SeenUnspillableVReg = true;
|
||||||
|
|
||||||
if (InterferingVRegs.size() == MaxInterferingRegs)
|
if (InterferingVRegs.size() == MaxInterferingRegs)
|
||||||
|
@ -238,17 +232,17 @@ collectInterferingVRegs(unsigned MaxInterferingRegs) {
|
||||||
// interference exists beyond those we collected.
|
// interference exists beyond those we collected.
|
||||||
return MaxInterferingRegs;
|
return MaxInterferingRegs;
|
||||||
|
|
||||||
InterferingVRegs.push_back(IR.LiveUnionI.value());
|
InterferingVRegs.push_back(LiveUnionI.value());
|
||||||
|
|
||||||
// Cache the most recent interfering vreg to bypass isSeenInterference.
|
// Cache the most recent interfering vreg to bypass isSeenInterference.
|
||||||
RecentInterferingVReg = IR.LiveUnionI.value();
|
RecentInterferingVReg = LiveUnionI.value();
|
||||||
++IR.LiveUnionI;
|
++LiveUnionI;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// VirtRegI may have advanced far beyond LiveUnionI,
|
// VirtRegI may have advanced far beyond LiveUnionI,
|
||||||
// do a fast intersection test to "catch up"
|
// do a fast intersection test to "catch up"
|
||||||
IR.LiveUnionI.advanceTo(IR.VirtRegI->start);
|
LiveUnionI.advanceTo(VirtRegI->start);
|
||||||
}
|
}
|
||||||
SeenAllInterferences = true;
|
SeenAllInterferences = true;
|
||||||
return InterferingVRegs.size();
|
return InterferingVRegs.size();
|
||||||
|
|
|
@ -142,7 +142,8 @@ public:
|
||||||
class Query {
|
class Query {
|
||||||
LiveIntervalUnion *LiveUnion;
|
LiveIntervalUnion *LiveUnion;
|
||||||
LiveInterval *VirtReg;
|
LiveInterval *VirtReg;
|
||||||
InterferenceResult FirstInterference;
|
LiveInterval::iterator VirtRegI; // current position in VirtReg
|
||||||
|
SegmentIter LiveUnionI; // current position in LiveUnion
|
||||||
SmallVector<LiveInterval*,4> InterferingVRegs;
|
SmallVector<LiveInterval*,4> InterferingVRegs;
|
||||||
bool CheckedFirstInterference;
|
bool CheckedFirstInterference;
|
||||||
bool SeenAllInterferences;
|
bool SeenAllInterferences;
|
||||||
|
@ -217,8 +218,7 @@ public:
|
||||||
void operator=(const Query&); // DO NOT IMPLEMENT
|
void operator=(const Query&); // DO NOT IMPLEMENT
|
||||||
|
|
||||||
// Private interface for queries
|
// Private interface for queries
|
||||||
const InterferenceResult &firstInterference();
|
void findIntersection();
|
||||||
void findIntersection(InterferenceResult &IR) const;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue