[Hexagon] HexagonMachineScheduler should account for resources
The machine scheduler needs to account for available resources more accurately in order to avoid scheduling an instruction that forces a new packet to be created. This occurs in two ways: First, an instruction without an available resource may have a large priority due to other metrics and be scheduled when there are other instructions with available resources. Second, an instruction with a non-zero latency may become available prematurely. In both these cases, we attempt change the priority in order to allow a better instruction to be scheduled. Patch by Brendon Cahoon. llvm-svn: 275793
This commit is contained in:
parent
ab1b926bb9
commit
3467e9d0a9
|
@ -18,12 +18,20 @@
|
|||
#include "llvm/CodeGen/ScheduleDAGMutation.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
|
||||
static cl::opt<bool> IgnoreBBRegPressure("ignore-bb-reg-pressure",
|
||||
cl::Hidden, cl::ZeroOrMore, cl::init(false));
|
||||
|
||||
static cl::opt<bool> SchedPredsCloser("sched-preds-closer",
|
||||
cl::Hidden, cl::ZeroOrMore, cl::init(true));
|
||||
|
||||
static cl::opt<bool> SchedRetvalOptimization("sched-retval-optimization",
|
||||
cl::Hidden, cl::ZeroOrMore, cl::init(true));
|
||||
|
||||
// Check if the scheduler should penalize instructions that are available to
|
||||
// early due to a zero-latency dependence.
|
||||
static cl::opt<bool> CheckEarlyAvail("check-early-avail", cl::Hidden,
|
||||
cl::ZeroOrMore, cl::init(true));
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "misched"
|
||||
|
@ -573,15 +581,23 @@ int ConvergingVLIWScheduler::SchedulingCost(ReadyQueue &Q, SUnit *SU,
|
|||
|
||||
// If resources are available for it, multiply the
|
||||
// chance of scheduling.
|
||||
if (Top.ResourceModel->isResourceAvailable(SU))
|
||||
if (Top.ResourceModel->isResourceAvailable(SU)) {
|
||||
ResCount <<= FactorOne;
|
||||
ResCount += PriorityThree;
|
||||
DEBUG(if (verbose) dbgs() << "A|");
|
||||
} else
|
||||
DEBUG(if (verbose) dbgs() << " |");
|
||||
} else {
|
||||
ResCount += (SU->getDepth() * ScaleTwo);
|
||||
|
||||
// If resources are available for it, multiply the
|
||||
// chance of scheduling.
|
||||
if (Bot.ResourceModel->isResourceAvailable(SU))
|
||||
if (Bot.ResourceModel->isResourceAvailable(SU)) {
|
||||
ResCount <<= FactorOne;
|
||||
ResCount += PriorityThree;
|
||||
DEBUG(if (verbose) dbgs() << "A|");
|
||||
} else
|
||||
DEBUG(if (verbose) dbgs() << " |");
|
||||
}
|
||||
|
||||
unsigned NumNodesBlocking = 0;
|
||||
|
@ -590,23 +606,35 @@ int ConvergingVLIWScheduler::SchedulingCost(ReadyQueue &Q, SUnit *SU,
|
|||
// Look at all of the successors of this node.
|
||||
// Count the number of nodes that
|
||||
// this node is the sole unscheduled node for.
|
||||
for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
|
||||
I != E; ++I)
|
||||
if (getSingleUnscheduledPred(I->getSUnit()) == SU)
|
||||
for (const SDep &SI : SU->Succs)
|
||||
if (getSingleUnscheduledPred(SI.getSUnit()) == SU)
|
||||
++NumNodesBlocking;
|
||||
} else {
|
||||
// How many unscheduled predecessors block this node?
|
||||
for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
|
||||
I != E; ++I)
|
||||
if (getSingleUnscheduledSucc(I->getSUnit()) == SU)
|
||||
for (const SDep &PI : SU->Preds)
|
||||
if (getSingleUnscheduledSucc(PI.getSUnit()) == SU)
|
||||
++NumNodesBlocking;
|
||||
}
|
||||
ResCount += (NumNodesBlocking * ScaleTwo);
|
||||
|
||||
// Factor in reg pressure as a heuristic.
|
||||
ResCount -= (Delta.Excess.getUnitInc()*PriorityTwo);
|
||||
ResCount -= (Delta.CriticalMax.getUnitInc()*PriorityTwo);
|
||||
if (!IgnoreBBRegPressure) {
|
||||
// Decrease priority by the amount that register pressure exceeds the limit.
|
||||
ResCount -= (Delta.Excess.getUnitInc()*PriorityOne);
|
||||
// Decrease priority if register pressure exceeds the limit.
|
||||
ResCount -= (Delta.CriticalMax.getUnitInc()*PriorityOne);
|
||||
// Decrease priority slightly if register pressure would increase over the
|
||||
// current maximum.
|
||||
ResCount -= (Delta.CurrentMax.getUnitInc()*PriorityTwo);
|
||||
DEBUG(if (verbose) {
|
||||
dbgs() << "RP " << Delta.Excess.getUnitInc() << "/"
|
||||
<< Delta.CriticalMax.getUnitInc() <<"/"
|
||||
<< Delta.CurrentMax.getUnitInc() << ")|";
|
||||
});
|
||||
}
|
||||
|
||||
// Give a little extra priority to a .cur instruction if there is a resource
|
||||
// available for it.
|
||||
auto &QST = DAG->MF.getSubtarget<HexagonSubtarget>();
|
||||
auto &QII = *QST.getInstrInfo();
|
||||
|
||||
|
@ -660,6 +688,46 @@ int ConvergingVLIWScheduler::SchedulingCost(ReadyQueue &Q, SUnit *SU,
|
|||
}
|
||||
}
|
||||
|
||||
// If the instruction has a non-zero latency dependence with an instruction in
|
||||
// the current packet, then it should not be scheduled yet. The case occurs
|
||||
// when the dependent instruction is scheduled in a new packet, so the
|
||||
// scheduler updates the current cycle and pending instructions become
|
||||
// available.
|
||||
if (CheckEarlyAvail) {
|
||||
if (Q.getID() == TopQID) {
|
||||
for (const auto &PI : SU->Preds) {
|
||||
if (PI.getLatency() > 0 &&
|
||||
Top.ResourceModel->isInPacket(PI.getSUnit())) {
|
||||
ResCount -= PriorityOne;
|
||||
DEBUG(if (verbose) dbgs() << "D|");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const auto &SI : SU->Succs) {
|
||||
if (SI.getLatency() > 0 &&
|
||||
Bot.ResourceModel->isInPacket(SI.getSUnit())) {
|
||||
ResCount -= PriorityOne;
|
||||
DEBUG(if (verbose) dbgs() << "D|");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Give less preference to an instruction that will cause a stall with
|
||||
// an instruction in the previous packet.
|
||||
if (QII.isV60VectorInstruction(Instr)) {
|
||||
// Check for stalls in the previous packet.
|
||||
if (Q.getID() == TopQID) {
|
||||
for (auto J : Top.ResourceModel->OldPacket)
|
||||
if (QII.producesStall(J->getInstr(), Instr))
|
||||
ResCount -= PriorityOne;
|
||||
} else {
|
||||
for (auto J : Bot.ResourceModel->OldPacket)
|
||||
if (QII.producesStall(Instr, J->getInstr()))
|
||||
ResCount -= PriorityOne;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(if (verbose) dbgs() << " Total(" << ResCount << ")");
|
||||
|
||||
return ResCount;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
; XFAIL: *
|
||||
; RUN: llc -march=hexagon -mcpu=hexagonv60 -enable-hexagon-hvx-double \
|
||||
; RUN: -hexagon-bit=0 < %s | FileCheck %s
|
||||
|
||||
|
|
Loading…
Reference in New Issue