forked from OSchip/llvm-project
Speed up eviction by stopping collectInterferingVRegs as soon as the spill
weight limit has been exceeded. llvm-svn: 129305
This commit is contained in:
parent
4f46abc15e
commit
0f175ebc32
|
@ -176,6 +176,7 @@ LiveIntervalUnion::Query::firstInterference() {
|
|||
return FirstInterference;
|
||||
CheckedFirstInterference = true;
|
||||
InterferenceResult &IR = FirstInterference;
|
||||
IR.LiveUnionI.setMap(LiveUnion->getMap());
|
||||
|
||||
// Quickly skip interference check for empty sets.
|
||||
if (VirtReg->empty() || LiveUnion->empty()) {
|
||||
|
@ -184,10 +185,10 @@ LiveIntervalUnion::Query::firstInterference() {
|
|||
// VirtReg starts first, perform double binary search.
|
||||
IR.VirtRegI = VirtReg->find(LiveUnion->startIndex());
|
||||
if (IR.VirtRegI != VirtReg->end())
|
||||
IR.LiveUnionI = LiveUnion->find(IR.VirtRegI->start);
|
||||
IR.LiveUnionI.find(IR.VirtRegI->start);
|
||||
} else {
|
||||
// LiveUnion starts first, perform double binary search.
|
||||
IR.LiveUnionI = LiveUnion->find(VirtReg->beginIndex());
|
||||
IR.LiveUnionI.find(VirtReg->beginIndex());
|
||||
if (IR.LiveUnionI.valid())
|
||||
IR.VirtRegI = VirtReg->find(IR.LiveUnionI.start());
|
||||
else
|
||||
|
@ -243,7 +244,7 @@ bool LiveIntervalUnion::Query::isSeenInterference(LiveInterval *VirtReg) const {
|
|||
//
|
||||
// For comments on how to speed it up, see Query::findIntersection().
|
||||
unsigned LiveIntervalUnion::Query::
|
||||
collectInterferingVRegs(unsigned MaxInterferingRegs) {
|
||||
collectInterferingVRegs(unsigned MaxInterferingRegs, float MaxWeight) {
|
||||
InterferenceResult IR = firstInterference();
|
||||
LiveInterval::iterator VirtRegEnd = VirtReg->end();
|
||||
LiveInterval *RecentInterferingVReg = NULL;
|
||||
|
@ -285,6 +286,11 @@ collectInterferingVRegs(unsigned MaxInterferingRegs) {
|
|||
// Cache the most recent interfering vreg to bypass isSeenInterference.
|
||||
RecentInterferingVReg = IR.LiveUnionI.value();
|
||||
++IR.LiveUnionI;
|
||||
|
||||
// Stop collecting when the max weight is exceeded.
|
||||
if (RecentInterferingVReg->weight >= MaxWeight)
|
||||
return InterferingVRegs.size();
|
||||
|
||||
continue;
|
||||
}
|
||||
// VirtRegI may have advanced far beyond LiveUnionI,
|
||||
|
|
|
@ -226,7 +226,8 @@ public:
|
|||
|
||||
// Count the virtual registers in this union that interfere with this
|
||||
// query's live virtual register, up to maxInterferingRegs.
|
||||
unsigned collectInterferingVRegs(unsigned MaxInterferingRegs = UINT_MAX);
|
||||
unsigned collectInterferingVRegs(unsigned MaxInterferingRegs = UINT_MAX,
|
||||
float MaxWeight = HUGE_VALF);
|
||||
|
||||
// Was this virtual register visited during collectInterferingVRegs?
|
||||
bool isSeenInterference(LiveInterval *VReg) const;
|
||||
|
|
|
@ -336,22 +336,24 @@ LiveInterval *RAGreedy::dequeue() {
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// canEvict - Return true if all interferences between VirtReg and PhysReg can
|
||||
/// be evicted. Set maxWeight to the maximal spill weight of an interference.
|
||||
/// be evicted.
|
||||
/// Return false if any interference is heavier than MaxWeight.
|
||||
/// On return, set MaxWeight to the maximal spill weight of an interference.
|
||||
bool RAGreedy::canEvictInterference(LiveInterval &VirtReg, unsigned PhysReg,
|
||||
float &MaxWeight) {
|
||||
float Weight = 0;
|
||||
for (const unsigned *AliasI = TRI->getOverlaps(PhysReg); *AliasI; ++AliasI) {
|
||||
LiveIntervalUnion::Query &Q = query(VirtReg, *AliasI);
|
||||
// If there is 10 or more interferences, chances are one is smaller.
|
||||
if (Q.collectInterferingVRegs(10) >= 10)
|
||||
// If there is 10 or more interferences, chances are one is heavier.
|
||||
if (Q.collectInterferingVRegs(10, MaxWeight) >= 10)
|
||||
return false;
|
||||
|
||||
// Check if any interfering live range is heavier than VirtReg.
|
||||
for (unsigned i = 0, e = Q.interferingVRegs().size(); i != e; ++i) {
|
||||
LiveInterval *Intf = Q.interferingVRegs()[i];
|
||||
// Check if any interfering live range is heavier than MaxWeight.
|
||||
for (unsigned i = Q.interferingVRegs().size(); i; --i) {
|
||||
LiveInterval *Intf = Q.interferingVRegs()[i - 1];
|
||||
if (TargetRegisterInfo::isPhysicalRegister(Intf->reg))
|
||||
return false;
|
||||
if (Intf->weight >= VirtReg.weight)
|
||||
if (Intf->weight >= MaxWeight)
|
||||
return false;
|
||||
Weight = std::max(Weight, Intf->weight);
|
||||
}
|
||||
|
@ -370,17 +372,17 @@ unsigned RAGreedy::tryEvict(LiveInterval &VirtReg,
|
|||
NamedRegionTimer T("Evict", TimerGroupName, TimePassesIsEnabled);
|
||||
|
||||
// Keep track of the lightest single interference seen so far.
|
||||
float BestWeight = 0;
|
||||
float BestWeight = VirtReg.weight;
|
||||
unsigned BestPhys = 0;
|
||||
|
||||
Order.rewind();
|
||||
while (unsigned PhysReg = Order.next()) {
|
||||
float Weight = 0;
|
||||
float Weight = BestWeight;
|
||||
if (!canEvictInterference(VirtReg, PhysReg, Weight))
|
||||
continue;
|
||||
|
||||
// This is an eviction candidate.
|
||||
DEBUG(dbgs() << "max " << PrintReg(PhysReg, TRI) << " interference = "
|
||||
DEBUG(dbgs() << PrintReg(PhysReg, TRI) << " interference = "
|
||||
<< Weight << '\n');
|
||||
if (BestPhys && Weight >= BestWeight)
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue