22 #define DEBUG_TYPE "scheduler"
36 cl::desc(
"Disable use of DFA during scheduling"));
40 cl::desc(
"Track reg pressure and switch priority to in-depth"));
45 InstrItins(IS->getTargetLowering()->getTargetMachine().getInstrItineraryData())
55 assert (ResourcesModel &&
"Unimplemented CreateTargetScheduleState.");
58 RegLimit.resize(NumRC);
59 RegPressure.resize(NumRC);
60 std::fill(RegLimit.begin(), RegLimit.end(), 0);
61 std::fill(RegPressure.begin(), RegPressure.end(), 0);
66 ParallelLiveRanges = 0;
67 HorizontalVerticalBalance = 0;
71 ResourcePriorityQueue::numberRCValPredInSU(
SUnit *SU,
unsigned RCId) {
72 unsigned NumberDeps = 0;
78 SUnit *PredSU =
I->getSUnit();
96 for (
unsigned i = 0, e = ScegN->
getNumValues(); i != e; ++i) {
108 unsigned ResourcePriorityQueue::numberRCValSuccInSU(
SUnit *SU,
110 unsigned NumberDeps = 0;
116 SUnit *SuccSU =
I->getSUnit();
147 unsigned NumberDeps = 0;
157 unsigned NumberDeps = 0;
171 NumNodesSolelyBlocking.resize(SUnits->size(), 0);
173 for (
unsigned i = 0, e = SUnits->size(); i != e; ++i) {
174 SUnit *SU = &(*SUnits)[i];
192 unsigned LHSNum = LHS->
NodeNum;
193 unsigned RHSNum = RHS->
NodeNum;
198 if (LHSLatency < RHSLatency)
return true;
199 if (LHSLatency > RHSLatency)
return false;
205 if (LHSBlocked < RHSBlocked)
return true;
206 if (LHSBlocked > RHSBlocked)
return false;
210 return LHSNum < RHSNum;
216 SUnit *ResourcePriorityQueue::getSingleUnscheduledPred(
SUnit *SU) {
217 SUnit *OnlyAvailablePred = 0;
220 SUnit &Pred = *
I->getSUnit();
224 if (OnlyAvailablePred && OnlyAvailablePred != &Pred)
226 OnlyAvailablePred = &Pred;
229 return OnlyAvailablePred;
235 unsigned NumNodesBlocking = 0;
238 if (getSingleUnscheduledPred(
I->getSUnit()) == SU)
241 NumNodesSolelyBlocking[SU->
NodeNum] = NumNodesBlocking;
274 for (
unsigned i = 0, e = Packet.size(); i != e; ++i)
276 E = Packet[i]->Succs.end();
I != E; ++
I) {
282 if (
I->getSUnit() == SU)
311 Packet.push_back(SU);
328 signed RegBalance = 0;
339 RegBalance += numberRCValSuccInSU(SU, RCId);
345 if (isa<ConstantSDNode>(Op.
getNode()))
350 RegBalance -= numberRCValPredInSU(SU, RCId);
362 signed RegBalance = 0;
378 if ((RegPressure[RC->
getID()] +
380 (RegPressure[RC->
getID()] +
448 if (
N->isMachineOpcode()) {
454 switch (
N->getOpcode()) {
486 for (
unsigned i = 0, e = ScegN->
getNumValues(); i != e; ++i) {
492 RegPressure[RC->
getID()] += numberRCValSuccInSU(SU, RC->
getID());
503 if (RegPressure[RC->
getID()] >
504 (numberRCValPredInSU(SU, RC->
getID())))
505 RegPressure[RC->
getID()] -= numberRCValPredInSU(SU, RC->
getID());
506 else RegPressure[RC->
getID()] = 0;
512 if (
I->isCtrl() || (
I->getSUnit()->NumRegDefsLeft == 0))
514 --
I->getSUnit()->NumRegDefsLeft;
524 unsigned NumberNonControlDeps = 0;
528 adjustPriorityOfUnscheduledPreds(
I->getSUnit());
530 NumberNonControlDeps++;
533 if (!NumberNonControlDeps) {
534 if (ParallelLiveRanges >= SU->
NumPreds)
537 ParallelLiveRanges = 0;
549 unsigned NodeNumDefs = 0;
551 if (
N->isMachineOpcode()) {
558 NodeNumDefs = std::min(
N->getNumValues(), TID.
getNumDefs());
561 switch(
N->getOpcode()) {
580 void ResourcePriorityQueue::adjustPriorityOfUnscheduledPreds(
SUnit *SU) {
583 SUnit *OnlyAvailablePred = getSingleUnscheduledPred(SU);
584 if (OnlyAvailablePred == 0 || !OnlyAvailablePred->
isAvailable)
589 remove(OnlyAvailablePred);
593 push(OnlyAvailablePred);
603 std::vector<SUnit *>::iterator Best = Queue.begin();
606 for (std::vector<SUnit *>::iterator
I =
llvm::next(Queue.begin()),
607 E = Queue.end();
I != E; ++
I) {
617 for (std::vector<SUnit *>::iterator
I =
llvm::next(Queue.begin()),
618 E = Queue.end();
I != E; ++
I)
619 if (Picker(*Best, *
I))
624 if (Best !=
prior(Queue.end()))
634 assert(!Queue.empty() &&
"Queue is empty!");
635 std::vector<SUnit *>::iterator
I = std::find(Queue.begin(), Queue.end(), SU);
636 if (I !=
prior(Queue.end()))
bool canReserveResources(const llvm::MCInstrDesc *MID)
signed rawRegPressureDelta(SUnit *SU, unsigned RCId)
static const unsigned PriorityTwo
static const unsigned PriorityFour
const TargetMachine & getTargetMachine() const
static const unsigned ScaleTwo
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions. Register definitions always occur...
void scheduledNode(SUnit *Node)
scheduledNode - Main resource tracking point.
SDNode * getGluedNode() const
virtual void remove(SUnit *SU)
unsigned getOpcode() const
regclass_iterator regclass_end() const
unsigned getNumOperands() const
const SDValue & getOperand(unsigned Num) const
const MCSchedModel * SchedModel
Basic machine properties.
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
unsigned getNumRegClasses() const
bool isCall() const
Return true if the instruction is a call.
unsigned getLatency(unsigned NodeNum) const
const TargetLowering * getTargetLowering() const
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"))
void initNumRegDefsLeft(SUnit *SU)
ResourcePriorityQueue(SelectionDAGISel *IS)
void initNodes(std::vector< SUnit > &sunits)
unsigned getNumValues() const
virtual void dump(ScheduleDAG *DAG) const
void reserveResources(const llvm::MCInstrDesc *MID)
virtual void push(SUnit *U)
static const unsigned ScaleThree
unsigned getNumSolelyBlockNodes(unsigned NodeNum) const
virtual DFAPacketizer * CreateTargetScheduleState(const TargetMachine *, const ScheduleDAG *) const
Create machine specific model for scheduling.
SDNode * getNode() const
get the SDNode which holds the desired result
bool isTypeLegal(EVT VT) const
initializer< Ty > init(const Ty &Val)
regclass_iterator regclass_begin() const
signed regPressureDelta(SUnit *SU, bool RawPressure=false)
ItTy next(ItTy it, Dist n)
const MCInstrDesc & get(unsigned Opcode) const
signed SUSchedulingCost(SUnit *SU)
virtual const TargetInstrInfo * getInstrInfo() const
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
virtual const TargetRegisterClass * getRegClassFor(MVT VT) const
static const unsigned FactorOne
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
unsigned short NumRegDefsLeft
virtual const TargetRegisterInfo * getRegisterInfo() const
static const unsigned PriorityThree
bool isResourceAvailable(SUnit *SU)
static const unsigned PriorityOne
virtual unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const
static const unsigned ScaleOne
SmallVector< SDep, 4 > Succs
ItTy prior(ItTy it, Dist n)
static unsigned numberCtrlPredInSU(SUnit *SU)
MVT getSimpleValueType(unsigned ResNo) const
ResourcePriorityQueue * PQ
const TargetRegisterClass *const * regclass_iterator
bool operator()(const SUnit *left, const SUnit *right) const
static cl::opt< bool > DisableDFASched("disable-dfa-sched", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Disable use of DFA during scheduling"))
void dump(const ScheduleDAG *G) const
SUnit - Scheduling unit. This is a node in the scheduling DAG.
bool isMachineOpcode() const
unsigned getMachineOpcode() const