1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

[MachineScheduler] improve reuse of 'releaseNode'method

The 'SchedBoundary::releaseNode' is merely invoked for releasing the Top/Bottom root nodes.
However,  'SchedBoundary::releasePending' uses its same logic to check if the Pending queue
has any releasable SUnit.
It is possible to slightly modify the body of the two, allowing re-use of the former ('releaseNode')
in the latter.

Patch by Lorenzo Casalino <lorenzo.casalino93@gmail.com>

Reviewers: MatzeB, fhahn, atrick

Reviewed By: fhahn

Differential Revision: https://reviews.llvm.org/D65506
This commit is contained in:
Lorenzo Casalino 2020-01-01 19:53:16 +00:00 committed by Florian Hahn
parent 73f08cbf02
commit e726cc64a4
2 changed files with 26 additions and 21 deletions

View File

@ -757,7 +757,8 @@ public:
unsigned getOtherResourceCount(unsigned &OtherCritIdx);
void releaseNode(SUnit *SU, unsigned ReadyCycle);
template <bool InPQueue>
void releaseNode(SUnit *SU, unsigned ReadyCycle, unsigned Idx = 0);
void bumpCycle(unsigned NextCycle);
@ -955,7 +956,7 @@ public:
if (SU->isScheduled)
return;
Top.releaseNode(SU, SU->TopReadyCycle);
Top.releaseNode<false>(SU, SU->TopReadyCycle);
TopCand.SU = nullptr;
}
@ -963,7 +964,7 @@ public:
if (SU->isScheduled)
return;
Bot.releaseNode(SU, SU->BotReadyCycle);
Bot.releaseNode<false>(SU, SU->BotReadyCycle);
BotCand.SU = nullptr;
}
@ -1043,7 +1044,7 @@ public:
void releaseTopNode(SUnit *SU) override {
if (SU->isScheduled)
return;
Top.releaseNode(SU, SU->TopReadyCycle);
Top.releaseNode<false>(SU, SU->TopReadyCycle);
}
// Only called for roots.

View File

@ -2088,7 +2088,8 @@ getOtherResourceCount(unsigned &OtherCritIdx) {
return OtherCritCount;
}
void SchedBoundary::releaseNode(SUnit *SU, unsigned ReadyCycle) {
template <bool InPQueue>
void SchedBoundary::releaseNode(SUnit *SU, unsigned ReadyCycle, unsigned Idx) {
assert(SU->getInstr() && "Scheduled SUnit must have instr");
#ifndef NDEBUG
@ -2105,11 +2106,19 @@ void SchedBoundary::releaseNode(SUnit *SU, unsigned ReadyCycle) {
// Check for interlocks first. For the purpose of other heuristics, an
// instruction that cannot issue appears as if it's not in the ReadyQueue.
bool IsBuffered = SchedModel->getMicroOpBufferSize() != 0;
if ((!IsBuffered && ReadyCycle > CurrCycle) || checkHazard(SU) ||
Available.size() >= ReadyListLimit)
Pending.push(SU);
else
bool HazardDetected = (!IsBuffered && ReadyCycle > CurrCycle) ||
checkHazard(SU) || (Available.size() >= ReadyListLimit);
if (!HazardDetected) {
Available.push(SU);
if (InPQueue)
Pending.remove(Pending.begin() + Idx);
return;
}
if (!InPQueue)
Pending.push(SU);
}
/// Move the boundary of scheduled code by one cycle.
@ -2349,26 +2358,21 @@ void SchedBoundary::releasePending() {
// Check to see if any of the pending instructions are ready to issue. If
// so, add them to the available queue.
bool IsBuffered = SchedModel->getMicroOpBufferSize() != 0;
for (unsigned i = 0, e = Pending.size(); i != e; ++i) {
SUnit *SU = *(Pending.begin()+i);
for (unsigned I = 0, E = Pending.size(); I < E; ++I) {
SUnit *SU = *(Pending.begin() + I);
unsigned ReadyCycle = isTop() ? SU->TopReadyCycle : SU->BotReadyCycle;
if (ReadyCycle < MinReadyCycle)
MinReadyCycle = ReadyCycle;
if (!IsBuffered && ReadyCycle > CurrCycle)
continue;
if (checkHazard(SU))
continue;
if (Available.size() >= ReadyListLimit)
break;
Available.push(SU);
Pending.remove(Pending.begin()+i);
--i; --e;
releaseNode<true>(SU, ReadyCycle, I);
if (E != Pending.size()) {
--I;
--E;
}
}
CheckPending = false;
}