mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-17 20:23:59 +00:00
MI-Sched: Track multiple candidates with the same priority level.
This eliminates the MultiPressure scheduling "reason". It was sensitive to queue order. We don't like being sensitive to queue order. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184129 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -305,7 +305,7 @@ void MachineScheduler::print(raw_ostream &O, const Module* m) const {
|
|||||||
|
|
||||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||||
void ReadyQueue::dump() {
|
void ReadyQueue::dump() {
|
||||||
dbgs() << " " << Name << ": ";
|
dbgs() << Name << ": ";
|
||||||
for (unsigned i = 0, e = Queue.size(); i < e; ++i)
|
for (unsigned i = 0, e = Queue.size(); i < e; ++i)
|
||||||
dbgs() << Queue[i]->NodeNum << " ";
|
dbgs() << Queue[i]->NodeNum << " ";
|
||||||
dbgs() << "\n";
|
dbgs() << "\n";
|
||||||
@ -1108,10 +1108,9 @@ public:
|
|||||||
/// Represent the type of SchedCandidate found within a single queue.
|
/// Represent the type of SchedCandidate found within a single queue.
|
||||||
/// pickNodeBidirectional depends on these listed by decreasing priority.
|
/// pickNodeBidirectional depends on these listed by decreasing priority.
|
||||||
enum CandReason {
|
enum CandReason {
|
||||||
NoCand, PhysRegCopy, SingleExcess, SingleCritical, Cluster, Weak,
|
NoCand, PhysRegCopy, RegExcess, RegCritical, Cluster, Weak,
|
||||||
ResourceReduce, ResourceDemand, BotHeightReduce, BotPathReduce,
|
ResourceReduce, ResourceDemand, BotHeightReduce, BotPathReduce,
|
||||||
TopDepthReduce, TopPathReduce, SingleMax, MultiPressure, NextDefUse,
|
TopDepthReduce, TopPathReduce, SingleMax, NextDefUse, NodeOrder};
|
||||||
NodeOrder};
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
static const char *getReasonStr(ConvergingScheduler::CandReason Reason);
|
static const char *getReasonStr(ConvergingScheduler::CandReason Reason);
|
||||||
@ -1156,6 +1155,9 @@ public:
|
|||||||
// The reason for this candidate.
|
// The reason for this candidate.
|
||||||
CandReason Reason;
|
CandReason Reason;
|
||||||
|
|
||||||
|
// Set of reasons that apply to multiple candidates.
|
||||||
|
uint32_t RepeatReasonSet;
|
||||||
|
|
||||||
// Register pressure values for the best candidate.
|
// Register pressure values for the best candidate.
|
||||||
RegPressureDelta RPDelta;
|
RegPressureDelta RPDelta;
|
||||||
|
|
||||||
@ -1163,7 +1165,7 @@ public:
|
|||||||
SchedResourceDelta ResDelta;
|
SchedResourceDelta ResDelta;
|
||||||
|
|
||||||
SchedCandidate(const CandPolicy &policy)
|
SchedCandidate(const CandPolicy &policy)
|
||||||
: Policy(policy), SU(NULL), Reason(NoCand) {}
|
: Policy(policy), SU(NULL), Reason(NoCand), RepeatReasonSet(0) {}
|
||||||
|
|
||||||
bool isValid() const { return SU; }
|
bool isValid() const { return SU; }
|
||||||
|
|
||||||
@ -1176,6 +1178,9 @@ public:
|
|||||||
ResDelta = Best.ResDelta;
|
ResDelta = Best.ResDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isRepeat(CandReason R) { return RepeatReasonSet & (1 << R); }
|
||||||
|
void setRepeat(CandReason R) { RepeatReasonSet |= (1 << R); }
|
||||||
|
|
||||||
void initResourceDelta(const ScheduleDAGMI *DAG,
|
void initResourceDelta(const ScheduleDAGMI *DAG,
|
||||||
const TargetSchedModel *SchedModel);
|
const TargetSchedModel *SchedModel);
|
||||||
};
|
};
|
||||||
@ -1983,6 +1988,7 @@ initResourceDelta(const ScheduleDAGMI *DAG,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Return true if this heuristic determines order.
|
/// Return true if this heuristic determines order.
|
||||||
static bool tryLess(int TryVal, int CandVal,
|
static bool tryLess(int TryVal, int CandVal,
|
||||||
ConvergingScheduler::SchedCandidate &TryCand,
|
ConvergingScheduler::SchedCandidate &TryCand,
|
||||||
@ -1997,6 +2003,7 @@ static bool tryLess(int TryVal, int CandVal,
|
|||||||
Cand.Reason = Reason;
|
Cand.Reason = Reason;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Cand.setRepeat(Reason);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2013,6 +2020,7 @@ static bool tryGreater(int TryVal, int CandVal,
|
|||||||
Cand.Reason = Reason;
|
Cand.Reason = Reason;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Cand.setRepeat(Reason);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2083,18 +2091,14 @@ void ConvergingScheduler::tryCandidate(SchedCandidate &Cand,
|
|||||||
|
|
||||||
// Avoid exceeding the target's limit.
|
// Avoid exceeding the target's limit.
|
||||||
if (tryLess(TryCand.RPDelta.Excess.UnitIncrease,
|
if (tryLess(TryCand.RPDelta.Excess.UnitIncrease,
|
||||||
Cand.RPDelta.Excess.UnitIncrease, TryCand, Cand, SingleExcess))
|
Cand.RPDelta.Excess.UnitIncrease, TryCand, Cand, RegExcess))
|
||||||
return;
|
return;
|
||||||
if (Cand.Reason == SingleExcess)
|
|
||||||
Cand.Reason = MultiPressure;
|
|
||||||
|
|
||||||
// Avoid increasing the max critical pressure in the scheduled region.
|
// Avoid increasing the max critical pressure in the scheduled region.
|
||||||
if (tryLess(TryCand.RPDelta.CriticalMax.UnitIncrease,
|
if (tryLess(TryCand.RPDelta.CriticalMax.UnitIncrease,
|
||||||
Cand.RPDelta.CriticalMax.UnitIncrease,
|
Cand.RPDelta.CriticalMax.UnitIncrease,
|
||||||
TryCand, Cand, SingleCritical))
|
TryCand, Cand, RegCritical))
|
||||||
return;
|
return;
|
||||||
if (Cand.Reason == SingleCritical)
|
|
||||||
Cand.Reason = MultiPressure;
|
|
||||||
|
|
||||||
// Keep clustered nodes together to encourage downstream peephole
|
// Keep clustered nodes together to encourage downstream peephole
|
||||||
// optimizations which may reduce resource requirements.
|
// optimizations which may reduce resource requirements.
|
||||||
@ -2158,8 +2162,6 @@ void ConvergingScheduler::tryCandidate(SchedCandidate &Cand,
|
|||||||
if (tryLess(TryCand.RPDelta.CurrentMax.UnitIncrease,
|
if (tryLess(TryCand.RPDelta.CurrentMax.UnitIncrease,
|
||||||
Cand.RPDelta.CurrentMax.UnitIncrease, TryCand, Cand, SingleMax))
|
Cand.RPDelta.CurrentMax.UnitIncrease, TryCand, Cand, SingleMax))
|
||||||
return;
|
return;
|
||||||
if (Cand.Reason == SingleMax)
|
|
||||||
Cand.Reason = MultiPressure;
|
|
||||||
|
|
||||||
// Prefer immediate defs/users of the last scheduled instruction. This is a
|
// Prefer immediate defs/users of the last scheduled instruction. This is a
|
||||||
// local pressure avoidance strategy that also makes the machine code
|
// local pressure avoidance strategy that also makes the machine code
|
||||||
@ -2212,12 +2214,11 @@ const char *ConvergingScheduler::getReasonStr(
|
|||||||
switch (Reason) {
|
switch (Reason) {
|
||||||
case NoCand: return "NOCAND ";
|
case NoCand: return "NOCAND ";
|
||||||
case PhysRegCopy: return "PREG-COPY";
|
case PhysRegCopy: return "PREG-COPY";
|
||||||
case SingleExcess: return "REG-EXCESS";
|
case RegExcess: return "REG-EXCESS";
|
||||||
case SingleCritical: return "REG-CRIT ";
|
case RegCritical: return "REG-CRIT ";
|
||||||
case Cluster: return "CLUSTER ";
|
case Cluster: return "CLUSTER ";
|
||||||
case Weak: return "WEAK ";
|
case Weak: return "WEAK ";
|
||||||
case SingleMax: return "REG-MAX ";
|
case SingleMax: return "REG-MAX ";
|
||||||
case MultiPressure: return "REG-MULTI ";
|
|
||||||
case ResourceReduce: return "RES-REDUCE";
|
case ResourceReduce: return "RES-REDUCE";
|
||||||
case ResourceDemand: return "RES-DEMAND";
|
case ResourceDemand: return "RES-DEMAND";
|
||||||
case TopDepthReduce: return "TOP-DEPTH ";
|
case TopDepthReduce: return "TOP-DEPTH ";
|
||||||
@ -2237,10 +2238,10 @@ void ConvergingScheduler::traceCandidate(const SchedCandidate &Cand) {
|
|||||||
switch (Cand.Reason) {
|
switch (Cand.Reason) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case SingleExcess:
|
case RegExcess:
|
||||||
P = Cand.RPDelta.Excess;
|
P = Cand.RPDelta.Excess;
|
||||||
break;
|
break;
|
||||||
case SingleCritical:
|
case RegCritical:
|
||||||
P = Cand.RPDelta.CriticalMax;
|
P = Cand.RPDelta.CriticalMax;
|
||||||
break;
|
break;
|
||||||
case SingleMax:
|
case SingleMax:
|
||||||
@ -2350,7 +2351,10 @@ SUnit *ConvergingScheduler::pickNodeBidirectional(bool &IsTopNode) {
|
|||||||
// affects picking from either Q. If scheduling in one direction must
|
// affects picking from either Q. If scheduling in one direction must
|
||||||
// increase pressure for one of the excess PSets, then schedule in that
|
// increase pressure for one of the excess PSets, then schedule in that
|
||||||
// direction first to provide more freedom in the other direction.
|
// direction first to provide more freedom in the other direction.
|
||||||
if (BotCand.Reason == SingleExcess || BotCand.Reason == SingleCritical) {
|
if ((BotCand.Reason == RegExcess && !BotCand.isRepeat(RegExcess))
|
||||||
|
|| (BotCand.Reason == RegCritical
|
||||||
|
&& !BotCand.isRepeat(RegCritical)))
|
||||||
|
{
|
||||||
IsTopNode = false;
|
IsTopNode = false;
|
||||||
tracePick(BotCand, IsTopNode);
|
tracePick(BotCand, IsTopNode);
|
||||||
return BotCand.SU;
|
return BotCand.SU;
|
||||||
@ -2359,30 +2363,19 @@ SUnit *ConvergingScheduler::pickNodeBidirectional(bool &IsTopNode) {
|
|||||||
pickNodeFromQueue(Top, DAG->getTopRPTracker(), TopCand);
|
pickNodeFromQueue(Top, DAG->getTopRPTracker(), TopCand);
|
||||||
assert(TopCand.Reason != NoCand && "failed to find the first candidate");
|
assert(TopCand.Reason != NoCand && "failed to find the first candidate");
|
||||||
|
|
||||||
// If either Q has a single candidate that minimizes pressure above the
|
|
||||||
// original region's pressure pick it.
|
|
||||||
if (TopCand.Reason <= SingleMax || BotCand.Reason <= SingleMax) {
|
|
||||||
if (TopCand.Reason < BotCand.Reason) {
|
|
||||||
IsTopNode = true;
|
|
||||||
tracePick(TopCand, IsTopNode);
|
|
||||||
return TopCand.SU;
|
|
||||||
}
|
|
||||||
IsTopNode = false;
|
|
||||||
tracePick(BotCand, IsTopNode);
|
|
||||||
return BotCand.SU;
|
|
||||||
}
|
|
||||||
// Check for a salient pressure difference and pick the best from either side.
|
// Check for a salient pressure difference and pick the best from either side.
|
||||||
if (compareRPDelta(TopCand.RPDelta, BotCand.RPDelta)) {
|
if (compareRPDelta(TopCand.RPDelta, BotCand.RPDelta)) {
|
||||||
IsTopNode = true;
|
IsTopNode = true;
|
||||||
tracePick(TopCand, IsTopNode);
|
tracePick(TopCand, IsTopNode);
|
||||||
return TopCand.SU;
|
return TopCand.SU;
|
||||||
}
|
}
|
||||||
// Otherwise prefer the bottom candidate, in node order if all else failed.
|
// Choose the queue with the most important (lowest enum) reason.
|
||||||
if (TopCand.Reason < BotCand.Reason) {
|
if (TopCand.Reason < BotCand.Reason) {
|
||||||
IsTopNode = true;
|
IsTopNode = true;
|
||||||
tracePick(TopCand, IsTopNode);
|
tracePick(TopCand, IsTopNode);
|
||||||
return TopCand.SU;
|
return TopCand.SU;
|
||||||
}
|
}
|
||||||
|
// Otherwise prefer the bottom candidate, in node order if all else failed.
|
||||||
IsTopNode = false;
|
IsTopNode = false;
|
||||||
tracePick(BotCand, IsTopNode);
|
tracePick(BotCand, IsTopNode);
|
||||||
return BotCand.SU;
|
return BotCand.SU;
|
||||||
|
Reference in New Issue
Block a user