33#define DEBUG_TYPE "scheduler"
37 cl::desc(
"Disable use of DFA during scheduling"));
41 cl::desc(
"Track reg pressure and switch priority to in-depth"));
44 : Picker(this), InstrItins(IS->MF->getSubtarget().getInstrItineraryData()) {
52 assert(ResourcesModel &&
"Unimplemented CreateTargetScheduleState.");
55 RegLimit.resize(NumRC);
56 RegPressure.resize(NumRC);
62 ParallelLiveRanges = 0;
63 HorizontalVerticalBalance = 0;
69ResourcePriorityQueue::numberRCValPredInSU(
SUnit *SU,
unsigned RCId) {
70 unsigned NumberDeps = 0;
94 for (
unsigned i = 0, e = ScegN->
getNumValues(); i != e; ++i) {
106unsigned ResourcePriorityQueue::numberRCValSuccInSU(
SUnit *SU,
108 unsigned NumberDeps = 0;
133 MVT VT =
Op.getNode()->getSimpleValueType(
Op.getResNo());
145 unsigned NumberDeps = 0;
154 unsigned NumberDeps = 0;
167 NumNodesSolelyBlocking.resize(SUnits->size(), 0);
169 for (
SUnit &SU : *SUnits) {
181 if (
LHS->isScheduleHigh && !
RHS->isScheduleHigh)
184 if (!
LHS->isScheduleHigh &&
RHS->isScheduleHigh)
187 unsigned LHSNum =
LHS->NodeNum;
188 unsigned RHSNum =
RHS->NodeNum;
193 if (LHSLatency < RHSLatency)
return true;
194 if (LHSLatency > RHSLatency)
return false;
200 if (LHSBlocked < RHSBlocked)
return true;
201 if (LHSBlocked > RHSBlocked)
return false;
205 return LHSNum < RHSNum;
211SUnit *ResourcePriorityQueue::getSingleUnscheduledPred(
SUnit *SU) {
212 SUnit *OnlyAvailablePred =
nullptr;
218 if (OnlyAvailablePred && OnlyAvailablePred != &PredSU)
220 OnlyAvailablePred = &PredSU;
223 return OnlyAvailablePred;
229 unsigned NumNodesBlocking = 0;
231 if (getSingleUnscheduledPred(Succ.
getSUnit()) == SU)
234 NumNodesSolelyBlocking[SU->
NodeNum] = NumNodesBlocking;
254 if (!ResourcesModel->canReserveResources(&TII->
get(
258 case TargetOpcode::EXTRACT_SUBREG:
259 case TargetOpcode::INSERT_SUBREG:
260 case TargetOpcode::SUBREG_TO_REG:
261 case TargetOpcode::REG_SEQUENCE:
262 case TargetOpcode::IMPLICIT_DEF:
268 for (
const SUnit *S : Packet)
269 for (
const SDep &Succ : S->Succs) {
287 ResourcesModel->clearResources();
294 ResourcesModel->reserveResources(&TII->
get(
297 case TargetOpcode::EXTRACT_SUBREG:
298 case TargetOpcode::INSERT_SUBREG:
299 case TargetOpcode::SUBREG_TO_REG:
300 case TargetOpcode::REG_SEQUENCE:
301 case TargetOpcode::IMPLICIT_DEF:
304 Packet.push_back(SU);
308 ResourcesModel->clearResources();
315 ResourcesModel->clearResources();
332 RegBalance += numberRCValSuccInSU(SU, RCId);
337 MVT VT =
Op.getNode()->getSimpleValueType(
Op.getResNo());
338 if (isa<ConstantSDNode>(
Op.getNode()))
343 RegBalance -= numberRCValPredInSU(SU, RCId);
366 if ((RegPressure[RC->getID()] +
368 (RegPressure[RC->getID()] +
436 if (
N->isMachineOpcode()) {
442 switch (
N->getOpcode()) {
465 ResourcesModel->clearResources();
475 for (
unsigned i = 0, e = ScegN->
getNumValues(); i != e; ++i) {
481 RegPressure[RC->
getID()] += numberRCValSuccInSU(SU, RC->
getID());
487 MVT VT =
Op.getNode()->getSimpleValueType(
Op.getResNo());
492 if (RegPressure[RC->
getID()] >
493 (numberRCValPredInSU(SU, RC->
getID())))
494 RegPressure[RC->
getID()] -= numberRCValPredInSU(SU, RC->
getID());
495 else RegPressure[RC->
getID()] = 0;
512 unsigned NumberNonControlDeps = 0;
515 adjustPriorityOfUnscheduledPreds(Succ.
getSUnit());
517 NumberNonControlDeps++;
520 if (!NumberNonControlDeps) {
521 if (ParallelLiveRanges >= SU->
NumPreds)
524 ParallelLiveRanges = 0;
536 unsigned NodeNumDefs = 0;
538 if (
N->isMachineOpcode()) {
541 if (
N->getMachineOpcode() == TargetOpcode::IMPLICIT_DEF) {
545 NodeNumDefs = std::min(
N->getNumValues(), TID.
getNumDefs());
548 switch(
N->getOpcode()) {
568void ResourcePriorityQueue::adjustPriorityOfUnscheduledPreds(
SUnit *SU) {
571 SUnit *OnlyAvailablePred = getSingleUnscheduledPred(SU);
572 if (!OnlyAvailablePred || !OnlyAvailablePred->
isAvailable)
577 remove(OnlyAvailablePred);
581 push(OnlyAvailablePred);
591 std::vector<SUnit *>::iterator Best = Queue.begin();
594 for (
auto I = std::next(Queue.begin()), E = Queue.end();
I != E; ++
I) {
604 for (
auto I = std::next(Queue.begin()), E = Queue.end();
I != E; ++
I)
605 if (Picker(*Best, *
I))
610 if (Best != std::prev(Queue.end()))
620 assert(!Queue.empty() &&
"Queue is empty!");
621 std::vector<SUnit *>::iterator
I =
find(Queue, SU);
622 if (
I != std::prev(Queue.end()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static const unsigned PriorityTwo
static const unsigned FactorOne
static const unsigned PriorityThree
static cl::opt< int > RegPressureThreshold("dfa-sched-reg-pressure-threshold", cl::Hidden, cl::init(5), cl::desc("Track reg pressure and switch priority to in-depth"))
static const unsigned ScaleOne
static unsigned numberCtrlPredInSU(SUnit *SU)
static const unsigned PriorityOne
static unsigned numberCtrlDepsInSU(SUnit *SU)
static cl::opt< bool > DisableDFASched("disable-dfa-sched", cl::Hidden, cl::desc("Disable use of DFA during scheduling"))
static const unsigned PriorityFour
static const unsigned ScaleTwo
static const unsigned ScaleThree
This file describes how to lower LLVM code to machine code.
This class represents an Operation in the Expression.
MCSchedModel SchedModel
Basic machine properties.
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.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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.
unsigned getLatency(unsigned NodeNum) const
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
unsigned getNumSolelyBlockNodes(unsigned NodeNum) const
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...
const TargetLowering * TLI
virtual DFAPacketizer * CreateTargetScheduleState(const TargetSubtargetInfo &) const
Create machine specific model for scheduling.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
unsigned getID() const
Return the register class ID number.
iterator_range< regclass_iterator > regclasses() const
unsigned getNumRegClasses() const
virtual unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const
Return the register pressure "high water mark" for the specific register class.
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.
initializer< Ty > init(const Ty &Val)
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.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
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