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()) {
 
   49  ResourcesModel.reset(TII->CreateTargetScheduleState(STI));
 
   52  assert(ResourcesModel && 
"Unimplemented CreateTargetScheduleState.");
 
   54  unsigned NumRC = TRI->getNumRegClasses();
 
   55  RegLimit.resize(NumRC);
 
   56  RegPressure.resize(NumRC);
 
   60    RegLimit[RC->getID()] = TRI->getRegPressureLimit(RC, *IS->
MF);
 
   62  ParallelLiveRanges = 0;
 
   63  HorizontalVerticalBalance = 0;
 
 
   69ResourcePriorityQueue::numberRCValPredInSU(
SUnit *SU, 
unsigned RCId) {
 
   70  unsigned NumberDeps = 0;
 
   75    SUnit *PredSU = Pred.getSUnit();
 
   88      case ISD::INLINEASM:      
break;
 
   89      case ISD::INLINEASM_BR:   
break;
 
   94    for (
unsigned i = 0, e = ScegN->
getNumValues(); i != e; ++i) {
 
  106unsigned ResourcePriorityQueue::numberRCValSuccInSU(
SUnit *SU,
 
  108  unsigned NumberDeps = 0;
 
  109  for (
const SDep &Succ : SU->
Succs) {
 
  114    const SDNode *ScegN = SuccSU->
getNode();
 
  125      case ISD::INLINEASM:      
break;
 
  126      case ISD::INLINEASM_BR:   
break;
 
  133      MVT VT = 
Op.getNode()->getSimpleValueType(
Op.getResNo());
 
  134      if (TLI->isTypeLegal(VT)
 
  135          && (TLI->getRegClassFor(VT)->getID() == RCId)) {
 
  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;
 
  191  unsigned LHSLatency = 
PQ->getLatency(LHSNum);
 
  192  unsigned RHSLatency = 
PQ->getLatency(RHSNum);
 
  193  if (LHSLatency < RHSLatency) 
return true;
 
  194  if (LHSLatency > RHSLatency) 
return false;
 
  198  unsigned LHSBlocked = 
PQ->getNumSolelyBlockNodes(LHSNum);
 
  199  unsigned RHSBlocked = 
PQ->getNumSolelyBlockNodes(RHSNum);
 
  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;
 
  214    SUnit &PredSU = *Pred.getSUnit();
 
  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();
 
  314  if (Packet.size() >= InstrItins->SchedModel.IssueWidth) {
 
  315    ResourcesModel->clearResources();
 
 
  329      if (TLI->isTypeLegal(VT)
 
  330          && TLI->getRegClassFor(VT)
 
  331          && TLI->getRegClassFor(VT)->getID() == RCId)
 
  332        RegBalance += numberRCValSuccInSU(SU, RCId);
 
  337      MVT VT = 
Op.getNode()->getSimpleValueType(
Op.getResNo());
 
  341      if (TLI->isTypeLegal(VT) && TLI->getRegClassFor(VT)
 
  342          && TLI->getRegClassFor(VT)->getID() == RCId)
 
  343        RegBalance -= numberRCValPredInSU(SU, RCId);
 
 
  366      if ((RegPressure[RC->getID()] +
 
  368          (RegPressure[RC->getID()] +
 
 
  436    if (
N->isMachineOpcode()) {
 
  437      const MCInstrDesc &TID = TII->get(
N->getMachineOpcode());
 
  442      switch (
N->getOpcode()) {
 
  451      case ISD::INLINEASM_BR:
 
 
  465    ResourcesModel->clearResources();
 
  475    for (
unsigned i = 0, e = ScegN->
getNumValues(); i != e; ++i) {
 
  478      if (TLI->isTypeLegal(VT)) {
 
  481          RegPressure[RC->
getID()] += numberRCValSuccInSU(SU, RC->
getID());
 
  487      MVT VT = 
Op.getNode()->getSimpleValueType(
Op.getResNo());
 
  489      if (TLI->isTypeLegal(VT)) {
 
  492          if (RegPressure[RC->
getID()] >
 
  493            (numberRCValPredInSU(SU, RC->
getID())))
 
  494            RegPressure[RC->
getID()] -= numberRCValPredInSU(SU, RC->
getID());
 
  495          else RegPressure[RC->
getID()] = 0;
 
  500      if (Pred.isCtrl() || (Pred.getSUnit()->NumRegDefsLeft == 0))
 
  502      --Pred.getSUnit()->NumRegDefsLeft;
 
  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()) {
 
  539      const MCInstrDesc &TID = TII->get(
N->getMachineOpcode());
 
  541      if (
N->getMachineOpcode() == TargetOpcode::IMPLICIT_DEF) {
 
  545      NodeNumDefs = std::min(
N->getNumValues(), TID.
getNumDefs());
 
  548      switch(
N->getOpcode()) {
 
  554        case ISD::INLINEASM_BR:
 
 
  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.
 
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 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.
 
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...
 
const TargetLowering * TLI
 
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.
 
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,...
 
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
 
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.
 
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
 
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