34 #define DEBUG_TYPE "scheduler"
38 cl::desc(
"Disable use of DFA during scheduling"));
42 cl::desc(
"Track reg pressure and switch priority to in-depth"));
45 : Picker(this), InstrItins(IS->MF->getSubtarget().getInstrItineraryData()) {
53 assert(ResourcesModel &&
"Unimplemented CreateTargetScheduleState.");
56 RegLimit.resize(NumRC);
57 RegPressure.resize(NumRC);
58 std::fill(RegLimit.begin(), RegLimit.end(), 0);
59 std::fill(RegPressure.begin(), RegPressure.end(), 0);
65 ParallelLiveRanges = 0;
66 HorizontalVerticalBalance = 0;
70 ResourcePriorityQueue::numberRCValPredInSU(
SUnit *SU,
unsigned RCId) {
71 unsigned NumberDeps = 0;
77 SUnit *PredSU =
I->getSUnit();
95 for (
unsigned i = 0, e = ScegN->
getNumValues(); i != e; ++i) {
107 unsigned ResourcePriorityQueue::numberRCValSuccInSU(
SUnit *SU,
109 unsigned NumberDeps = 0;
115 SUnit *SuccSU =
I->getSUnit();
146 unsigned NumberDeps = 0;
156 unsigned NumberDeps = 0;
170 NumNodesSolelyBlocking.resize(SUnits->size(), 0);
172 for (
unsigned i = 0, e = SUnits->size(); i != e; ++i) {
173 SUnit *SU = &(*SUnits)[i];
191 unsigned LHSNum = LHS->
NodeNum;
192 unsigned RHSNum = RHS->
NodeNum;
197 if (LHSLatency < RHSLatency)
return true;
198 if (LHSLatency > RHSLatency)
return false;
204 if (LHSBlocked < RHSBlocked)
return true;
205 if (LHSBlocked > RHSBlocked)
return false;
209 return LHSNum < RHSNum;
215 SUnit *ResourcePriorityQueue::getSingleUnscheduledPred(
SUnit *SU) {
216 SUnit *OnlyAvailablePred =
nullptr;
219 SUnit &Pred = *
I->getSUnit();
223 if (OnlyAvailablePred && OnlyAvailablePred != &Pred)
225 OnlyAvailablePred = &Pred;
228 return OnlyAvailablePred;
234 unsigned NumNodesBlocking = 0;
237 if (getSingleUnscheduledPred(
I->getSUnit()) == SU)
240 NumNodesSolelyBlocking[SU->
NodeNum] = NumNodesBlocking;
260 if (!ResourcesModel->canReserveResources(&TII->
get(
273 for (
unsigned i = 0, e = Packet.size(); i != e; ++i)
275 E = Packet[i]->Succs.end();
I != E; ++
I) {
281 if (
I->getSUnit() == SU)
293 ResourcesModel->clearResources();
300 ResourcesModel->reserveResources(&TII->
get(
310 Packet.push_back(SU);
314 ResourcesModel->clearResources();
321 ResourcesModel->clearResources();
327 signed RegBalance = 0;
338 RegBalance += numberRCValSuccInSU(SU, RCId);
344 if (isa<ConstantSDNode>(Op.
getNode()))
349 RegBalance -= numberRCValPredInSU(SU, RCId);
361 signed RegBalance = 0;
377 if ((RegPressure[RC->
getID()] +
379 (RegPressure[RC->
getID()] +
447 if (
N->isMachineOpcode()) {
453 switch (
N->getOpcode()) {
475 ResourcesModel->clearResources();
485 for (
unsigned i = 0, e = ScegN->
getNumValues(); i != e; ++i) {
491 RegPressure[RC->
getID()] += numberRCValSuccInSU(SU, RC->
getID());
502 if (RegPressure[RC->
getID()] >
503 (numberRCValPredInSU(SU, RC->
getID())))
504 RegPressure[RC->
getID()] -= numberRCValPredInSU(SU, RC->
getID());
505 else RegPressure[RC->
getID()] = 0;
511 if (
I->isCtrl() || (
I->getSUnit()->NumRegDefsLeft == 0))
513 --
I->getSUnit()->NumRegDefsLeft;
523 unsigned NumberNonControlDeps = 0;
527 adjustPriorityOfUnscheduledPreds(
I->getSUnit());
529 NumberNonControlDeps++;
532 if (!NumberNonControlDeps) {
533 if (ParallelLiveRanges >= SU->
NumPreds)
536 ParallelLiveRanges = 0;
548 unsigned NodeNumDefs = 0;
550 if (
N->isMachineOpcode()) {
560 switch(
N->getOpcode()) {
579 void ResourcePriorityQueue::adjustPriorityOfUnscheduledPreds(
SUnit *SU) {
582 SUnit *OnlyAvailablePred = getSingleUnscheduledPred(SU);
583 if (!OnlyAvailablePred || !OnlyAvailablePred->
isAvailable)
588 remove(OnlyAvailablePred);
592 push(OnlyAvailablePred);
602 std::vector<SUnit *>::iterator Best = Queue.begin();
605 for (std::vector<SUnit *>::iterator
I = std::next(Queue.begin()),
606 E = Queue.end();
I != E; ++
I) {
616 for (std::vector<SUnit *>::iterator
I = std::next(Queue.begin()),
617 E = Queue.end();
I != E; ++
I)
618 if (Picker(*Best, *
I))
623 if (Best != std::prev(Queue.end()))
633 assert(!Queue.empty() &&
"Queue is empty!");
634 std::vector<SUnit *>::iterator
I = std::find(Queue.begin(), Queue.end(), SU);
635 if (I != std::prev(Queue.end()))
signed rawRegPressureDelta(SUnit *SU, unsigned RCId)
static const unsigned PriorityTwo
static const unsigned PriorityFour
static const unsigned ScaleTwo
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
Describe properties that are true of each instruction in the target description file.
SDNode * getGluedNode() const
If this node has a glue operand, return the node to which the glue operand points.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
unsigned getID() const
getID() - Return the register class ID number.
regclass_iterator regclass_end() const
unsigned getNumOperands() const
Return the number of values used by this operation.
bool empty() const override
const SDValue & getOperand(unsigned Num) const
void reserveResources(SUnit *SU)
Keep track of available resources.
unsigned getResNo() const
get the index which selects a specific result in the SDNode
SmallVector< SDep, 4 > Preds
static unsigned numberCtrlDepsInSU(SUnit *SU)
unsigned getHeight() const
getHeight - Return the height of this node, which is the length of the maximum path down to any node ...
unsigned getNumRegClasses() const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const TargetLowering * TLI
bool isCall() const
Return true if the instruction is a call.
unsigned getLatency(unsigned NodeNum) const
CopyToReg - This node has three operands: a chain, a register number to set to this value...
static cl::opt< signed > RegPressureThreshold("dfa-sched-reg-pressure-threshold", cl::Hidden, cl::ZeroOrMore, cl::init(5), cl::desc("Track reg pressure and switch priority to in-depth"))
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
void initNumRegDefsLeft(SUnit *SU)
InitNumRegDefsLeft - Determine the # of regs defined by this node.
INLINEASM - Represents an inline asm block.
ResourcePriorityQueue(SelectionDAGISel *IS)
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
static const unsigned ScaleThree
unsigned getNumSolelyBlockNodes(unsigned NodeNum) const
void scheduledNode(SUnit *Node) override
scheduledNode - Main resource tracking point.
SDNode * getNode() const
get the SDNode which holds the desired result
virtual DFAPacketizer * CreateTargetScheduleState(const TargetSubtargetInfo &) const
Create machine specific model for scheduling.
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
initializer< Ty > init(const Ty &Val)
regclass_iterator regclass_begin() const
Register class iterators.
MVT - Machine Value Type.
SDNode * getNode() const
getNode - Return the representative SDNode for this SUnit.
INSERT_SUBREG - This instruction takes three operands: a register that has subregisters, a register providing an insert value, and a subregister index.
signed regPressureDelta(SUnit *SU, bool RawPressure=false)
Estimates change in reg pressure from this SU.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
REG_SEQUENCE - This variadic instruction is used to form a register that represents a consecutive seq...
signed SUSchedulingCost(SUnit *SU)
Single cost function reflecting benefit of scheduling SU in the current cycle.
void remove(SUnit *SU) override
TokenFactor - This node takes multiple tokens as input and produces a single token result...
EXTRACT_SUBREG - This instruction takes two operands: a register that has subregisters, and a subregister index.
Represents one node in the SelectionDAG.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
virtual const TargetRegisterClass * getRegClassFor(MVT VT) const
Return the register class that should be used for the specified value type.
TargetSubtargetInfo - Generic base class for all target subtargets.
static const unsigned FactorOne
MCSchedModel SchedModel
Basic machine properties.
unsigned short NumRegDefsLeft
static const unsigned PriorityThree
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
bool isResourceAvailable(SUnit *SU)
Check if scheduling of this SU is possible in the current packet.
static const unsigned PriorityOne
virtual unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const
getRegPressureLimit - Return the register pressure "high water mark" for the specific register class...
static const unsigned ScaleOne
void push(SUnit *U) override
virtual const TargetInstrInfo * getInstrInfo() const
SmallVector< SDep, 4 > Succs
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except that the first operand is an imme...
SUnit * pop() override
Main access point - returns next instructions to be placed in scheduling sequence.
static unsigned numberCtrlPredInSU(SUnit *SU)
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
ResourcePriorityQueue * PQ
const TargetRegisterClass *const * regclass_iterator
void initNodes(std::vector< SUnit > &sunits) override
Initialize nodes.
bool operator()(const SUnit *left, const SUnit *right) const
This heuristic is used if DFA scheduling is not desired for some VLIW platform.
static cl::opt< bool > DisableDFASched("disable-dfa-sched", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Disable use of DFA during scheduling"))
SUnit - Scheduling unit. This is a node in the scheduling DAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
This file describes how to lower LLVM code to machine code.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.