34#define DEBUG_TYPE "scheduler"
37 : Picker(this), InstrItins(IS->MF->getSubtarget().getInstrItineraryData()) {
42 Opts = &IS->CurDAG->getSelectionDAGOptions();
43 ResourcesModel.reset(TII->CreateTargetScheduleState(STI));
46 assert(ResourcesModel &&
"Unimplemented CreateTargetScheduleState.");
48 unsigned NumRC = TRI->getNumRegClasses();
49 RegLimit.resize(NumRC);
50 RegPressure.resize(NumRC);
54 RegLimit[RC.getID()] = TRI->getRegPressureLimit(&RC, *IS->MF);
56 ParallelLiveRanges = 0;
57 HorizontalVerticalBalance = 0;
63ResourcePriorityQueue::numberRCValPredInSU(
SUnit *SU,
unsigned RCId) {
64 unsigned NumberDeps = 0;
69 SUnit *PredSU = Pred.getSUnit();
88 for (
unsigned i = 0, e = ScegN->
getNumValues(); i != e; ++i) {
90 if (
TLI->isTypeLegal(VT)
91 && (
TLI->getRegClassFor(VT)->getID() == RCId)) {
100unsigned ResourcePriorityQueue::numberRCValSuccInSU(
SUnit *SU,
102 unsigned NumberDeps = 0;
103 for (
const SDep &Succ : SU->
Succs) {
108 const SDNode *ScegN = SuccSU->
getNode();
127 MVT VT =
Op.getNode()->getSimpleValueType(
Op.getResNo());
128 if (TLI->isTypeLegal(VT)
129 && (TLI->getRegClassFor(VT)->getID() == RCId)) {
139 unsigned NumberDeps = 0;
148 unsigned NumberDeps = 0;
161 NumNodesSolelyBlocking.resize(SUnits->size(), 0);
163 for (
SUnit &SU : *SUnits) {
175 if (LHS->isScheduleHigh && !RHS->isScheduleHigh)
178 if (!LHS->isScheduleHigh && RHS->isScheduleHigh)
181 unsigned LHSNum = LHS->NodeNum;
182 unsigned RHSNum = RHS->NodeNum;
185 unsigned LHSLatency =
PQ->getLatency(LHSNum);
186 unsigned RHSLatency =
PQ->getLatency(RHSNum);
187 if (LHSLatency < RHSLatency)
return true;
188 if (LHSLatency > RHSLatency)
return false;
192 unsigned LHSBlocked =
PQ->getNumSolelyBlockNodes(LHSNum);
193 unsigned RHSBlocked =
PQ->getNumSolelyBlockNodes(RHSNum);
194 if (LHSBlocked < RHSBlocked)
return true;
195 if (LHSBlocked > RHSBlocked)
return false;
199 return LHSNum < RHSNum;
205SUnit *ResourcePriorityQueue::getSingleUnscheduledPred(
SUnit *SU) {
206 SUnit *OnlyAvailablePred =
nullptr;
208 SUnit &PredSU = *Pred.getSUnit();
212 if (OnlyAvailablePred && OnlyAvailablePred != &PredSU)
214 OnlyAvailablePred = &PredSU;
217 return OnlyAvailablePred;
223 unsigned NumNodesBlocking = 0;
225 if (getSingleUnscheduledPred(Succ.
getSUnit()) == SU)
228 NumNodesSolelyBlocking[SU->
NodeNum] = NumNodesBlocking;
248 if (!ResourcesModel->canReserveResources(&TII->get(
252 case TargetOpcode::EXTRACT_SUBREG:
253 case TargetOpcode::INSERT_SUBREG:
254 case TargetOpcode::SUBREG_TO_REG:
255 case TargetOpcode::REG_SEQUENCE:
256 case TargetOpcode::IMPLICIT_DEF:
262 for (
const SUnit *S : Packet)
263 for (
const SDep &Succ : S->Succs) {
281 ResourcesModel->clearResources();
288 ResourcesModel->reserveResources(&TII->get(
291 case TargetOpcode::EXTRACT_SUBREG:
292 case TargetOpcode::INSERT_SUBREG:
293 case TargetOpcode::SUBREG_TO_REG:
294 case TargetOpcode::REG_SEQUENCE:
295 case TargetOpcode::IMPLICIT_DEF:
298 Packet.push_back(SU);
302 ResourcesModel->clearResources();
308 if (Packet.size() >= InstrItins->SchedModel.IssueWidth) {
309 ResourcesModel->clearResources();
323 if (TLI->isTypeLegal(VT)
324 && TLI->getRegClassFor(VT)
325 && TLI->getRegClassFor(VT)->getID() == RCId)
326 RegBalance += numberRCValSuccInSU(SU, RCId);
331 MVT VT =
Op.getNode()->getSimpleValueType(
Op.getResNo());
335 if (TLI->isTypeLegal(VT) && TLI->getRegClassFor(VT)
336 && TLI->getRegClassFor(VT)->getID() == RCId)
337 RegBalance -= numberRCValPredInSU(SU, RCId);
362 RegLimit[RC.getID()]))
398 if (HorizontalVerticalBalance > Opts->dfa_sched_reg_pressure_threshold) {
429 if (
N->isMachineOpcode()) {
430 const MCInstrDesc &TID = TII->get(
N->getMachineOpcode());
435 switch (
N->getOpcode()) {
458 ResourcesModel->clearResources();
468 for (
unsigned i = 0, e = ScegN->
getNumValues(); i != e; ++i) {
471 if (TLI->isTypeLegal(VT)) {
474 RegPressure[RC->
getID()] += numberRCValSuccInSU(SU, RC->
getID());
480 MVT VT =
Op.getNode()->getSimpleValueType(
Op.getResNo());
482 if (TLI->isTypeLegal(VT)) {
485 if (RegPressure[RC->
getID()] >
486 (numberRCValPredInSU(SU, RC->
getID())))
487 RegPressure[RC->
getID()] -= numberRCValPredInSU(SU, RC->
getID());
488 else RegPressure[RC->
getID()] = 0;
493 if (Pred.isCtrl() || (Pred.getSUnit()->NumRegDefsLeft == 0))
495 --Pred.getSUnit()->NumRegDefsLeft;
505 unsigned NumberNonControlDeps = 0;
508 adjustPriorityOfUnscheduledPreds(Succ.
getSUnit());
510 NumberNonControlDeps++;
513 if (!NumberNonControlDeps) {
514 if (ParallelLiveRanges >= SU->
NumPreds)
517 ParallelLiveRanges = 0;
529 unsigned NodeNumDefs = 0;
531 if (
N->isMachineOpcode()) {
532 const MCInstrDesc &TID = TII->get(
N->getMachineOpcode());
534 if (
N->getMachineOpcode() == TargetOpcode::IMPLICIT_DEF) {
538 NodeNumDefs = std::min(
N->getNumValues(), TID.
getNumDefs());
541 switch(
N->getOpcode()) {
561void ResourcePriorityQueue::adjustPriorityOfUnscheduledPreds(
SUnit *SU) {
564 SUnit *OnlyAvailablePred = getSingleUnscheduledPred(SU);
565 if (!OnlyAvailablePred || !OnlyAvailablePred->
isAvailable)
570 remove(OnlyAvailablePred);
574 push(OnlyAvailablePred);
584 std::vector<SUnit *>::iterator Best = Queue.begin();
585 if (!Opts->disable_dfa_sched) {
587 for (
auto I = std::next(Queue.begin()), E = Queue.end();
I != E; ++
I) {
597 for (
auto I = std::next(Queue.begin()), E = Queue.end();
I != E; ++
I)
598 if (Picker(*Best, *
I))
603 if (Best != std::prev(Queue.end()))
613 assert(!Queue.empty() &&
"Queue is empty!");
614 std::vector<SUnit *>::iterator
I =
find(Queue, SU);
615 if (
I != std::prev(Queue.end()))
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static const unsigned PriorityTwo
static const unsigned FactorOne
static const unsigned PriorityThree
static const unsigned ScaleOne
static unsigned numberCtrlPredInSU(SUnit *SU)
static const unsigned PriorityOne
static unsigned numberCtrlDepsInSU(SUnit *SU)
static const unsigned PriorityFour
static const unsigned ScaleTwo
static const unsigned ScaleThree
This file describes how to lower LLVM code to machine code.
Describe properties that are true of each instruction in the target description file.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
bool isCall() const
Return true if the instruction is a call.
unsigned getID() const
getID() - Return the register class ID number.
void push(SUnit *U) override
void scheduledNode(SUnit *SU) override
scheduledNode - Main resource tracking point.
ResourcePriorityQueue(SelectionDAGISel *IS)
void initNodes(std::vector< SUnit > &sunits) override
Initialize nodes.
bool empty() const override
SUnit * pop() override
Main access point - returns next instructions to be placed in scheduling sequence.
int rawRegPressureDelta(SUnit *SU, unsigned RCId)
int regPressureDelta(SUnit *SU, bool RawPressure=false)
Estimates change in reg pressure from this SU.
void remove(SUnit *SU) override
~ResourcePriorityQueue() override
void reserveResources(SUnit *SU)
Keep track of available resources.
int SUSchedulingCost(SUnit *SU)
Single cost function reflecting benefit of scheduling SU in the current cycle.
void initNumRegDefsLeft(SUnit *SU)
InitNumRegDefsLeft - Determine the # of regs defined by this node.
bool isResourceAvailable(SUnit *SU)
Check if scheduling of this SU is possible in the current packet.
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
const SDValue & getOperand(unsigned Num) const
SDNode * getGluedNode() const
If this node has a glue operand, return the node to which the glue operand points.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
bool isCtrl() const
Shorthand for getKind() != SDep::Data.
Scheduling unit. This is a node in the scheduling DAG.
unsigned NodeQueueId
Queue id of node.
unsigned NodeNum
Entry # of node in the node vector.
unsigned getHeight() const
Returns the height of this node, which is the length of the maximum path down to any node which has n...
unsigned short NumRegDefsLeft
bool isScheduleHigh
True if preferable to schedule high.
bool isScheduled
True once scheduled.
bool isAvailable
True once available.
SmallVector< SDep, 4 > Succs
All sunit successors.
SDNode * getNode() const
Returns the representative SDNode for this SUnit.
SmallVector< SDep, 4 > Preds
All sunit predecessors.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ INLINEASM
INLINEASM - Represents an inline asm block.
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
void fill(R &&Range, T &&Value)
Provide wrappers to std::fill which take ranges instead of having to pass begin/end explicitly.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
DWARFExpression::Operation Op
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
LLVM_ABI bool operator()(const SUnit *LHS, const SUnit *RHS) const
This heuristic is used if DFA scheduling is not desired for some VLIW platform.
ResourcePriorityQueue * PQ