Commit f9f78cf6 authored by Lorenzo Casalino's avatar Lorenzo Casalino Committed by Florian Hahn
Browse files

[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
parent 11552433
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -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.
+21 −17
Original line number Diff line number Diff line
@@ -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;
}