summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/MachineScheduler.cpp220
-rw-r--r--lib/CodeGen/RegisterPressure.cpp89
-rw-r--r--lib/CodeGen/RegisterPressure.h54
3 files changed, 288 insertions, 75 deletions
diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp
index 1d810fdf16..57f3506d8e 100644
--- a/lib/CodeGen/MachineScheduler.cpp
+++ b/lib/CodeGen/MachineScheduler.cpp
@@ -1,4 +1,4 @@
-//===- MachineScheduler.cpp - Machine Instruction Scheduler ---------------===//
+//===- MachineScheduler.cpp - Machine Instruction Scheduler ---------------===//excess
//
// The LLVM Compiler Infrastructure
//
@@ -326,10 +326,15 @@ class ScheduleDAGMI : public ScheduleDAGInstrs {
MachineBasicBlock::iterator LiveRegionEnd;
- // Register pressure in this region computed by buildSchedGraph.
+ /// Register pressure in this region computed by buildSchedGraph.
IntervalPressure RegPressure;
RegPressureTracker RPTracker;
+ /// List of pressure sets that exceed the target's pressure limit before
+ /// scheduling, listed in increasing set ID order. Each pressure set is paired
+ /// with its max pressure in the currently scheduled regions.
+ std::vector<PressureElement> RegionCriticalPSets;
+
/// The top of the unscheduled zone.
MachineBasicBlock::iterator CurrentTop;
IntervalPressure TopPressure;
@@ -380,8 +385,13 @@ public:
/// Get register pressure for the entire scheduling region before scheduling.
const IntervalPressure &getRegPressure() const { return RegPressure; }
+ const std::vector<PressureElement> &getRegionCriticalPSets() const {
+ return RegionCriticalPSets;
+ }
+
protected:
void initRegPressure();
+ void updateScheduledPressure(std::vector<unsigned> NewMaxPressure);
void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
bool checkSchedLimit();
@@ -515,6 +525,33 @@ void ScheduleDAGMI::initRegPressure() {
BotRPTracker.recede();
assert(BotRPTracker.getPos() == RegionEnd && "Can't find the region bottom");
+
+ // Cache the list of excess pressure sets in this region. This will also track
+ // the max pressure in the scheduled code for these sets.
+ RegionCriticalPSets.clear();
+ std::vector<unsigned> RegionPressure = RPTracker.getPressure().MaxSetPressure;
+ for (unsigned i = 0, e = RegionPressure.size(); i < e; ++i) {
+ unsigned Limit = TRI->getRegPressureSetLimit(i);
+ if (RegionPressure[i] > Limit)
+ RegionCriticalPSets.push_back(PressureElement(i, 0));
+ }
+ DEBUG(dbgs() << "Excess PSets: ";
+ for (unsigned i = 0, e = RegionCriticalPSets.size(); i != e; ++i)
+ dbgs() << TRI->getRegPressureSetName(
+ RegionCriticalPSets[i].PSetID) << " ";
+ dbgs() << "\n");
+}
+
+// FIXME: When the pressure tracker deals in pressure differences then we won't
+// iterate over all RegionCriticalPSets[i].
+void ScheduleDAGMI::
+updateScheduledPressure(std::vector<unsigned> NewMaxPressure) {
+ for (unsigned i = 0, e = RegionCriticalPSets.size(); i < e; ++i) {
+ unsigned ID = RegionCriticalPSets[i].PSetID;
+ int &MaxUnits = RegionCriticalPSets[i].UnitIncrease;
+ if ((int)NewMaxPressure[ID] > MaxUnits)
+ MaxUnits = NewMaxPressure[ID];
+ }
}
/// schedule - Called back from MachineScheduler::runOnMachineFunction
@@ -581,6 +618,7 @@ void ScheduleDAGMI::schedule() {
// Update top scheduled pressure.
TopRPTracker.advance();
assert(TopRPTracker.getPos() == CurrentTop && "out of sync");
+ updateScheduledPressure(TopRPTracker.getPressure().MaxSetPressure);
// Release dependent instructions for scheduling.
releaseSuccessors(SU);
@@ -602,6 +640,7 @@ void ScheduleDAGMI::schedule() {
// Update bottom scheduled pressure.
BotRPTracker.recede();
assert(BotRPTracker.getPos() == CurrentBottom && "out of sync");
+ updateScheduledPressure(BotRPTracker.getPressure().MaxSetPressure);
// Release dependent instructions for scheduling.
releasePredecessors(SU);
@@ -654,6 +693,8 @@ struct ReadyQ {
bool empty() const { return Queue.empty(); }
+ unsigned size() const { return Queue.size(); }
+
iterator begin() { return Queue.begin(); }
iterator end() { return Queue.end(); }
@@ -689,6 +730,9 @@ class ConvergingScheduler : public MachineSchedStrategy {
SchedCandidate(): SU(NULL) {}
};
+ /// Represent the type of SchedCandidate found within a single queue.
+ enum CandResult {
+ NoCand, NodeOrder, SingleExcess, SingleCritical, SingleMax, MultiPressure };
ScheduleDAGMI *DAG;
const TargetRegisterInfo *TRI;
@@ -732,88 +776,197 @@ public:
BotQueue.push(SU);
}
protected:
+ SUnit *pickNodeBidrectional(bool &IsTopNode);
+
+ CandResult pickNodeFromQueue(ReadyQ &Q, const RegPressureTracker &RPTracker,
+ SchedCandidate &Candidate);
#ifndef NDEBUG
void traceCandidate(const char *Label, unsigned QID, SUnit *SU,
- int RPDiff, unsigned PSetID);
+ PressureElement P = PressureElement());
#endif
- bool pickNodeFromQueue(ReadyQ &Q, const RegPressureTracker &RPTracker,
- SchedCandidate &Candidate);
};
} // namespace
#ifndef NDEBUG
void ConvergingScheduler::
traceCandidate(const char *Label, unsigned QID, SUnit *SU,
- int RPDiff, unsigned PSetID) {
+ PressureElement P) {
dbgs() << Label << getQName(QID) << " ";
- if (RPDiff)
- dbgs() << TRI->getRegPressureSetName(PSetID) << ":" << RPDiff << " ";
+ if (P.isValid())
+ dbgs() << TRI->getRegPressureSetName(P.PSetID) << ":" << P.UnitIncrease
+ << " ";
else
dbgs() << " ";
SU->dump(DAG);
}
#endif
+/// Return true if the LHS reg pressure effect is better than RHS.
+static bool compareRPDelta(const RegPressureDelta &LHS,
+ const RegPressureDelta &RHS) {
+ // Compare each component of pressure in decreasing order of importance
+ // without checking if any are valid. Invalid PressureElements are assumed to
+ // have UnitIncrease==0, so are neutral.
+ if (LHS.Excess.UnitIncrease != RHS.Excess.UnitIncrease)
+ return LHS.Excess.UnitIncrease < RHS.Excess.UnitIncrease;
+
+ if (LHS.CriticalMax.UnitIncrease != RHS.CriticalMax.UnitIncrease)
+ return LHS.CriticalMax.UnitIncrease < RHS.CriticalMax.UnitIncrease;
+
+ if (LHS.CurrentMax.UnitIncrease != RHS.CurrentMax.UnitIncrease)
+ return LHS.CurrentMax.UnitIncrease < RHS.CurrentMax.UnitIncrease;
+
+ return false;
+}
+
+
/// Pick the best candidate from the top queue.
///
/// TODO: getMaxPressureDelta results can be mostly cached for each SUnit during
/// DAG building. To adjust for the current scheduling location we need to
/// maintain the number of vreg uses remaining to be top-scheduled.
-bool ConvergingScheduler::pickNodeFromQueue(ReadyQ &Q,
- const RegPressureTracker &RPTracker,
- SchedCandidate &Candidate) {
+ConvergingScheduler::CandResult ConvergingScheduler::
+pickNodeFromQueue(ReadyQ &Q, const RegPressureTracker &RPTracker,
+ SchedCandidate &Candidate) {
+
// getMaxPressureDelta temporarily modifies the tracker.
RegPressureTracker &TempTracker = const_cast<RegPressureTracker&>(RPTracker);
// BestSU remains NULL if no top candidates beat the best existing candidate.
- bool FoundCandidate = false;
+ CandResult FoundCandidate = NoCand;
for (ReadyQ::iterator I = Q.begin(), E = Q.end(); I != E; ++I) {
RegPressureDelta RPDelta;
- TempTracker.getMaxPressureDelta((*I)->getInstr(), RPDelta);
+ TempTracker.getMaxPressureDelta((*I)->getInstr(), RPDelta,
+ DAG->getRegionCriticalPSets(),
+ DAG->getRegPressure().MaxSetPressure);
+ // Initialize the candidate if needed.
+ if (!Candidate.SU) {
+ Candidate.SU = *I;
+ Candidate.RPDelta = RPDelta;
+ FoundCandidate = NodeOrder;
+ continue;
+ }
// Avoid exceeding the target's limit.
- if (!Candidate.SU || RPDelta.ExcessUnits < Candidate.RPDelta.ExcessUnits) {
- DEBUG(traceCandidate(Candidate.SU ? "PCAND" : "ACAND", Q.ID, *I,
- RPDelta.ExcessUnits, RPDelta.ExcessSetID));
+ if (RPDelta.Excess.UnitIncrease < Candidate.RPDelta.Excess.UnitIncrease) {
+ DEBUG(traceCandidate("ECAND", Q.ID, *I, RPDelta.Excess));
Candidate.SU = *I;
Candidate.RPDelta = RPDelta;
- FoundCandidate = true;
+ FoundCandidate = SingleExcess;
continue;
}
- if (RPDelta.ExcessUnits > Candidate.RPDelta.ExcessUnits)
+ if (RPDelta.Excess.UnitIncrease > Candidate.RPDelta.Excess.UnitIncrease)
continue;
+ if (FoundCandidate == SingleExcess)
+ FoundCandidate = MultiPressure;
- // Avoid increasing the max pressure.
- if (RPDelta.MaxUnitIncrease < Candidate.RPDelta.MaxUnitIncrease) {
- DEBUG(traceCandidate("MCAND", Q.ID, *I,
- RPDelta.ExcessUnits, RPDelta.ExcessSetID));
+ // Avoid increasing the max critical pressure in the scheduled region.
+ if (RPDelta.CriticalMax.UnitIncrease
+ < Candidate.RPDelta.CriticalMax.UnitIncrease) {
+ DEBUG(traceCandidate("PCAND", Q.ID, *I, RPDelta.CriticalMax));
Candidate.SU = *I;
Candidate.RPDelta = RPDelta;
- FoundCandidate = true;
+ FoundCandidate = SingleCritical;
continue;
}
- if (RPDelta.MaxUnitIncrease > Candidate.RPDelta.MaxUnitIncrease)
+ if (RPDelta.CriticalMax.UnitIncrease
+ > Candidate.RPDelta.CriticalMax.UnitIncrease)
continue;
+ if (FoundCandidate == SingleCritical)
+ FoundCandidate = MultiPressure;
+
+ // Avoid increasing the max pressure of the entire region.
+ if (RPDelta.CurrentMax.UnitIncrease
+ < Candidate.RPDelta.CurrentMax.UnitIncrease) {
+ DEBUG(traceCandidate("MCAND", Q.ID, *I, RPDelta.CurrentMax));
+ Candidate.SU = *I;
+ Candidate.RPDelta = RPDelta;
+ FoundCandidate = SingleMax;
+ continue;
+ }
+ if (RPDelta.CurrentMax.UnitIncrease
+ > Candidate.RPDelta.CurrentMax.UnitIncrease)
+ continue;
+ if (FoundCandidate == SingleMax)
+ FoundCandidate = MultiPressure;
// Fall through to original instruction order.
- // Only consider node order if BestSU was chosen from this Q.
- if (!FoundCandidate)
+ // Only consider node order if Candidate was chosen from this Q.
+ if (FoundCandidate == NoCand)
continue;
if ((Q.ID == TopQID && (*I)->NodeNum < Candidate.SU->NodeNum)
|| (Q.ID == BotQID && (*I)->NodeNum > Candidate.SU->NodeNum)) {
- DEBUG(traceCandidate("NCAND", Q.ID, *I, 0, 0));
+ DEBUG(traceCandidate("NCAND", Q.ID, *I));
Candidate.SU = *I;
Candidate.RPDelta = RPDelta;
- FoundCandidate = true;
+ FoundCandidate = NodeOrder;
}
}
return FoundCandidate;
}
-/// Pick the best node from either the top or bottom queue to balance the
-/// schedule.
+/// Pick the best candidate node from either the top or bottom queue.
+SUnit *ConvergingScheduler::pickNodeBidrectional(bool &IsTopNode) {
+ // Schedule as far as possible in the direction of no choice. This is most
+ // efficient, but also provides the best heuristics for CriticalPSets.
+ if (BotQueue.size() == 1) {
+ IsTopNode = false;
+ return *BotQueue.begin();
+ }
+ if (TopQueue.size() == 1) {
+ IsTopNode = true;
+ return *TopQueue.begin();
+ }
+ SchedCandidate BotCandidate;
+ // Prefer bottom scheduling when heuristics are silent.
+ CandResult BotResult =
+ pickNodeFromQueue(BotQueue, DAG->getBotRPTracker(), BotCandidate);
+ assert(BotResult != NoCand && "failed to find the first candidate");
+
+ // If either Q has a single candidate that provides the least increase in
+ // Excess pressure, we can immediately schedule from that Q.
+ //
+ // RegionCriticalPSets summarizes the pressure within the scheduled region and
+ // affects picking from either Q. If scheduling in one direction must
+ // increase pressure for one of the excess PSets, then schedule in that
+ // direction first to provide more freedom in the other direction.
+ if (BotResult == SingleExcess || BotResult == SingleCritical) {
+ IsTopNode = false;
+ return BotCandidate.SU;
+ }
+ // Check if the top Q has a better candidate.
+ SchedCandidate TopCandidate;
+ CandResult TopResult =
+ pickNodeFromQueue(TopQueue, DAG->getTopRPTracker(), TopCandidate);
+ assert(TopResult != NoCand && "failed to find the first candidate");
+
+ if (TopResult == SingleExcess || TopResult == SingleCritical) {
+ IsTopNode = true;
+ return TopCandidate.SU;
+ }
+ // If either Q has a single candidate that minimizes pressure above the
+ // original region's pressure pick it.
+ if (BotResult == SingleMax) {
+ IsTopNode = false;
+ return BotCandidate.SU;
+ }
+ if (TopResult == SingleMax) {
+ IsTopNode = true;
+ return TopCandidate.SU;
+ }
+ // Check for a salient pressure difference and pick the best from either side.
+ if (compareRPDelta(TopCandidate.RPDelta, BotCandidate.RPDelta)) {
+ IsTopNode = true;
+ return TopCandidate.SU;
+ }
+ // Otherwise prefer the bottom candidate in node order.
+ IsTopNode = false;
+ return BotCandidate.SU;
+}
+
+/// Pick the best node to balance the schedule. Implements MachineSchedStrategy.
SUnit *ConvergingScheduler::pickNode(bool &IsTopNode) {
if (DAG->top() == DAG->bottom()) {
assert(TopQueue.empty() && BotQueue.empty() && "ReadyQ garbage");
@@ -829,12 +982,7 @@ SUnit *ConvergingScheduler::pickNode(bool &IsTopNode) {
IsTopNode = false;
}
else {
- SchedCandidate Candidate;
- // Prefer picking from the bottom.
- pickNodeFromQueue(BotQueue, DAG->getBotRPTracker(), Candidate);
- IsTopNode =
- pickNodeFromQueue(TopQueue, DAG->getTopRPTracker(), Candidate);
- SU = Candidate.SU;
+ SU = pickNodeBidrectional(IsTopNode);
}
if (SU->isTopReady()) {
assert(!TopQueue.empty() && "bad ready count");
diff --git a/lib/CodeGen/RegisterPressure.cpp b/lib/CodeGen/RegisterPressure.cpp
index 912ed0dd7b..b30f76d05d 100644
--- a/lib/CodeGen/RegisterPressure.cpp
+++ b/lib/CodeGen/RegisterPressure.cpp
@@ -562,12 +562,13 @@ bool RegPressureTracker::advance() {
return true;
}
-// Find the max change in excess pressure across all sets.
-static int computeMaxPressureDelta(ArrayRef<unsigned> OldPressureVec,
- ArrayRef<unsigned> NewPressureVec,
- unsigned &PSetID,
- const TargetRegisterInfo *TRI) {
+/// Find the max change in excess pressure across all sets.
+static void computeExcessPressureDelta(ArrayRef<unsigned> OldPressureVec,
+ ArrayRef<unsigned> NewPressureVec,
+ RegPressureDelta &Delta,
+ const TargetRegisterInfo *TRI) {
int ExcessUnits = 0;
+ unsigned PSetID = ~0U;
for (unsigned i = 0, e = OldPressureVec.size(); i < e; ++i) {
unsigned POld = OldPressureVec[i];
unsigned PNew = NewPressureVec[i];
@@ -590,7 +591,50 @@ static int computeMaxPressureDelta(ArrayRef<unsigned> OldPressureVec,
PSetID = i;
}
}
- return ExcessUnits;
+ Delta.Excess.PSetID = PSetID;
+ Delta.Excess.UnitIncrease = ExcessUnits;
+}
+
+/// Find the max change in max pressure that either surpasses a critical PSet
+/// limit or exceeds the current MaxPressureLimit.
+///
+/// FIXME: comparing each element of the old and new MaxPressure vectors here is
+/// silly. It's done now to demonstrate the concept but will go away with a
+/// RegPressureTracker API change to work with pressure differences.
+static void computeMaxPressureDelta(ArrayRef<unsigned> OldMaxPressureVec,
+ ArrayRef<unsigned> NewMaxPressureVec,
+ ArrayRef<PressureElement> CriticalPSets,
+ ArrayRef<unsigned> MaxPressureLimit,
+ RegPressureDelta &Delta) {
+ Delta.CriticalMax = PressureElement();
+ Delta.CurrentMax = PressureElement();
+
+ unsigned CritIdx = 0, CritEnd = CriticalPSets.size();
+ for (unsigned i = 0, e = OldMaxPressureVec.size(); i < e; ++i) {
+ unsigned POld = OldMaxPressureVec[i];
+ unsigned PNew = NewMaxPressureVec[i];
+ if (PNew == POld) // No change in this set in the common case.
+ continue;
+
+ while (CritIdx != CritEnd && CriticalPSets[CritIdx].PSetID < i)
+ ++CritIdx;
+
+ if (CritIdx != CritEnd && CriticalPSets[CritIdx].PSetID == i) {
+ int PDiff = (int)PNew - (int)CriticalPSets[CritIdx].UnitIncrease;
+ if (PDiff > Delta.CriticalMax.UnitIncrease) {
+ Delta.CriticalMax.PSetID = i;
+ Delta.CriticalMax.UnitIncrease = PDiff;
+ }
+ }
+
+ // Find the greatest increase above MaxPressureLimit.
+ // (Ignores negative MDiff).
+ int MDiff = (int)PNew - (int)MaxPressureLimit[i];
+ if (MDiff > Delta.CurrentMax.UnitIncrease) {
+ Delta.CurrentMax.PSetID = i;
+ Delta.CurrentMax.UnitIncrease = PNew;
+ }
+ }
}
/// Consider the pressure increase caused by traversing this instruction
@@ -605,13 +649,17 @@ static int computeMaxPressureDelta(ArrayRef<unsigned> OldPressureVec,
/// result per-SUnit with enough information to adjust for the current
/// scheduling position. But this works as a proof of concept.
void RegPressureTracker::
-getMaxUpwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta) {
+getMaxUpwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta,
+ ArrayRef<PressureElement> CriticalPSets,
+ ArrayRef<unsigned> MaxPressureLimit) {
// Account for register pressure similar to RegPressureTracker::recede().
PhysRegOperands PhysRegOpers;
VirtRegOperands VirtRegOpers;
collectOperands(MI, PhysRegOpers, VirtRegOpers, TRI, RCI);
// Snapshot Pressure.
+ // FIXME: The snapshot heap space should persist. But I'm planning to
+ // summarize the pressure effect so we don't need to snapshot at all.
std::vector<unsigned> SavedPressure = CurrSetPressure;
std::vector<unsigned> SavedMaxPressure = P.MaxSetPressure;
@@ -643,13 +691,11 @@ getMaxUpwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta) {
increaseVirtRegPressure(Reg);
}
}
- Delta.ExcessUnits =
- computeMaxPressureDelta(SavedPressure, CurrSetPressure,
- Delta.ExcessSetID, TRI);
- Delta.MaxUnitIncrease =
- computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure,
- Delta.MaxSetID, TRI);
- assert(Delta.MaxUnitIncrease >= 0 && "cannot increase max pressure");
+ computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, TRI);
+ computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets,
+ MaxPressureLimit, Delta);
+ assert(Delta.CriticalMax.UnitIncrease >= 0 &&
+ Delta.CurrentMax.UnitIncrease >= 0 && "cannot decrease max pressure");
// Restore the tracker's state.
P.MaxSetPressure.swap(SavedMaxPressure);
@@ -679,7 +725,9 @@ static bool findUseBetween(unsigned Reg,
///
/// This assumes that the current LiveIn set is sufficient.
void RegPressureTracker::
-getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta) {
+getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta,
+ ArrayRef<PressureElement> CriticalPSets,
+ ArrayRef<unsigned> MaxPressureLimit) {
// Account for register pressure similar to RegPressureTracker::recede().
PhysRegOperands PhysRegOpers;
VirtRegOperands VirtRegOpers;
@@ -717,12 +765,11 @@ getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta) {
decreasePhysRegPressure(PhysRegOpers.DeadDefs);
decreaseVirtRegPressure(VirtRegOpers.DeadDefs);
- Delta.ExcessUnits =
- computeMaxPressureDelta(SavedPressure, CurrSetPressure,
- Delta.ExcessSetID, TRI);
- Delta.MaxUnitIncrease =
- computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure,
- Delta.MaxSetID, TRI);
+ computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, TRI);
+ computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets,
+ MaxPressureLimit, Delta);
+ assert(Delta.CriticalMax.UnitIncrease >= 0 &&
+ Delta.CurrentMax.UnitIncrease >= 0 && "cannot decrease max pressure");
// Restore the tracker's state.
P.MaxSetPressure.swap(SavedMaxPressure);
diff --git a/lib/CodeGen/RegisterPressure.h b/lib/CodeGen/RegisterPressure.h
index b1d1378401..b424480090 100644
--- a/lib/CodeGen/RegisterPressure.h
+++ b/lib/CodeGen/RegisterPressure.h
@@ -80,28 +80,38 @@ struct RegionPressure : RegisterPressure {
void openBottom(MachineBasicBlock::const_iterator PrevBottom);
};
-/// Store the results of a change in pressure.
+/// An element of pressure difference that identifies the pressure set and
+/// amount of increase or decrease in units of pressure.
+struct PressureElement {
+ unsigned PSetID;
+ int UnitIncrease;
+
+ PressureElement(): PSetID(~0U), UnitIncrease(0) {}
+ PressureElement(unsigned id, int inc): PSetID(id), UnitIncrease(inc) {}
+
+ bool isValid() const { return PSetID != ~0U; }
+};
+
+/// Store the effects of a change in pressure on things that MI scheduler cares
+/// about.
///
-/// ExcessUnits is the value of the largest difference in register units beyond
+/// Excess records the value of the largest difference in register units beyond
/// the target's pressure limits across the affected pressure sets, where
/// largest is defined as the absolute value of the difference. Negative
/// ExcessUnits indicates a reduction in pressure that had already exceeded the
/// target's limits.
///
-/// MaxUnitIncrease is the largest increase in register units required across
-/// the scheduled region across the affected pressure sets, regardless of the
-/// target's pressure limits.
+/// CriticalMax records the largest increase in the tracker's max pressure that
+/// exceeds the critical limit for some pressure set determined by the client.
///
-/// If ExcessUnits == 0, then ExcessSetID is invalid.
-/// If MaxUnitIncrease == 0, then MaxSetID is invalid.
+/// CurrentMax records the largest increase in the tracker's max pressure that
+/// exceeds the current limit for some pressure set determined by the client.
struct RegPressureDelta {
- int ExcessUnits;
- unsigned ExcessSetID;
- int MaxUnitIncrease;
- unsigned MaxSetID;
+ PressureElement Excess;
+ PressureElement CriticalMax;
+ PressureElement CurrentMax;
- RegPressureDelta():
- ExcessUnits(0), ExcessSetID(~0U), MaxUnitIncrease(0), MaxSetID(~0U) {}
+ RegPressureDelta() {}
};
/// Track the current register pressure at some position in the instruction
@@ -203,24 +213,32 @@ public:
/// limit based on the tracker's current pressure, and record the number of
/// excess register units of that pressure set introduced by this instruction.
void getMaxUpwardPressureDelta(const MachineInstr *MI,
- RegPressureDelta &Delta);
+ RegPressureDelta &Delta,
+ ArrayRef<PressureElement> CriticalPSets,
+ ArrayRef<unsigned> MaxPressureLimit);
/// Consider the pressure increase caused by traversing this instruction
/// top-down. Find the pressure set with the most change beyond its pressure
/// limit based on the tracker's current pressure, and record the number of
/// excess register units of that pressure set introduced by this instruction.
void getMaxDownwardPressureDelta(const MachineInstr *MI,
- RegPressureDelta &Delta);
+ RegPressureDelta &Delta,
+ ArrayRef<PressureElement> CriticalPSets,
+ ArrayRef<unsigned> MaxPressureLimit);
/// Find the pressure set with the most change beyond its pressure limit after
/// traversing this instruction either upward or downward depending on the
/// closed end of the current region.
- void getMaxPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta) {
+ void getMaxPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta,
+ ArrayRef<PressureElement> CriticalPSets,
+ ArrayRef<unsigned> MaxPressureLimit) {
if (isTopClosed())
- return getMaxDownwardPressureDelta(MI, Delta);
+ return getMaxDownwardPressureDelta(MI, Delta, CriticalPSets,
+ MaxPressureLimit);
assert(isBottomClosed() && "Uninitialized pressure tracker");
- return getMaxUpwardPressureDelta(MI, Delta);
+ return getMaxUpwardPressureDelta(MI, Delta, CriticalPSets,
+ MaxPressureLimit);
}
protected: