diff --git a/llvm/include/llvm/CodeGen/MachineScheduler.h b/llvm/include/llvm/CodeGen/MachineScheduler.h --- a/llvm/include/llvm/CodeGen/MachineScheduler.h +++ b/llvm/include/llvm/CodeGen/MachineScheduler.h @@ -757,7 +757,8 @@ unsigned getOtherResourceCount(unsigned &OtherCritIdx); - void releaseNode(SUnit *SU, unsigned ReadyCycle); + template + void releaseNode(SUnit *SU, unsigned ReadyCycle, unsigned Idx = 0); void bumpCycle(unsigned NextCycle); @@ -955,7 +956,7 @@ if (SU->isScheduled) return; - Top.releaseNode(SU, SU->TopReadyCycle); + Top.releaseNode(SU, SU->TopReadyCycle); TopCand.SU = nullptr; } @@ -963,7 +964,7 @@ if (SU->isScheduled) return; - Bot.releaseNode(SU, SU->BotReadyCycle); + Bot.releaseNode(SU, SU->BotReadyCycle); BotCand.SU = nullptr; } @@ -1043,7 +1044,7 @@ void releaseTopNode(SUnit *SU) override { if (SU->isScheduled) return; - Top.releaseNode(SU, SU->TopReadyCycle); + Top.releaseNode(SU, SU->TopReadyCycle); } // Only called for roots. diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp --- a/llvm/lib/CodeGen/MachineScheduler.cpp +++ b/llvm/lib/CodeGen/MachineScheduler.cpp @@ -2088,7 +2088,8 @@ return OtherCritCount; } -void SchedBoundary::releaseNode(SUnit *SU, unsigned ReadyCycle) { +template +void SchedBoundary::releaseNode(SUnit *SU, unsigned ReadyCycle, unsigned Idx) { assert(SU->getInstr() && "Scheduled SUnit must have instr"); #ifndef NDEBUG @@ -2105,11 +2106,19 @@ // 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 @@ // 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(SU, ReadyCycle, I); + if (E != Pending.size()) { + --I; + --E; + } } CheckPending = false; }