LLVM  4.0.0
ResourcePriorityQueue.cpp
Go to the documentation of this file.
1 //===- ResourcePriorityQueue.cpp - A DFA-oriented priority queue -*- C++ -*-==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the ResourcePriorityQueue class, which is a
11 // SchedulingPriorityQueue that prioritizes instructions using DFA state to
12 // reduce the length of the critical path through the basic block
13 // on VLIW platforms.
14 // The scheduler is basically a top-down adaptable list scheduler with DFA
15 // resource tracking added to the cost function.
16 // DFA is queried as a state machine to model "packets/bundles" during
17 // schedule. Currently packets/bundles are discarded at the end of
18 // scheduling, affecting only order of instructions.
19 //
20 //===----------------------------------------------------------------------===//
21 
26 #include "llvm/Support/Debug.h"
31 
32 using namespace llvm;
33 
34 #define DEBUG_TYPE "scheduler"
35 
36 static cl::opt<bool> DisableDFASched("disable-dfa-sched", cl::Hidden,
37  cl::ZeroOrMore, cl::init(false),
38  cl::desc("Disable use of DFA during scheduling"));
39 
41  "dfa-sched-reg-pressure-threshold", cl::Hidden, cl::ZeroOrMore, cl::init(5),
42  cl::desc("Track reg pressure and switch priority to in-depth"));
43 
45  : Picker(this), InstrItins(IS->MF->getSubtarget().getInstrItineraryData()) {
46  const TargetSubtargetInfo &STI = IS->MF->getSubtarget();
47  TRI = STI.getRegisterInfo();
48  TLI = IS->TLI;
49  TII = STI.getInstrInfo();
50  ResourcesModel.reset(TII->CreateTargetScheduleState(STI));
51  // This hard requirement could be relaxed, but for now
52  // do not let it proceed.
53  assert(ResourcesModel && "Unimplemented CreateTargetScheduleState.");
54 
55  unsigned NumRC = TRI->getNumRegClasses();
56  RegLimit.resize(NumRC);
57  RegPressure.resize(NumRC);
58  std::fill(RegLimit.begin(), RegLimit.end(), 0);
59  std::fill(RegPressure.begin(), RegPressure.end(), 0);
61  E = TRI->regclass_end();
62  I != E; ++I)
63  RegLimit[(*I)->getID()] = TRI->getRegPressureLimit(*I, *IS->MF);
64 
65  ParallelLiveRanges = 0;
66  HorizontalVerticalBalance = 0;
67 }
68 
69 unsigned
70 ResourcePriorityQueue::numberRCValPredInSU(SUnit *SU, unsigned RCId) {
71  unsigned NumberDeps = 0;
72  for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
73  I != E; ++I) {
74  if (I->isCtrl())
75  continue;
76 
77  SUnit *PredSU = I->getSUnit();
78  const SDNode *ScegN = PredSU->getNode();
79 
80  if (!ScegN)
81  continue;
82 
83  // If value is passed to CopyToReg, it is probably
84  // live outside BB.
85  switch (ScegN->getOpcode()) {
86  default: break;
87  case ISD::TokenFactor: break;
88  case ISD::CopyFromReg: NumberDeps++; break;
89  case ISD::CopyToReg: break;
90  case ISD::INLINEASM: break;
91  }
92  if (!ScegN->isMachineOpcode())
93  continue;
94 
95  for (unsigned i = 0, e = ScegN->getNumValues(); i != e; ++i) {
96  MVT VT = ScegN->getSimpleValueType(i);
97  if (TLI->isTypeLegal(VT)
98  && (TLI->getRegClassFor(VT)->getID() == RCId)) {
99  NumberDeps++;
100  break;
101  }
102  }
103  }
104  return NumberDeps;
105 }
106 
107 unsigned ResourcePriorityQueue::numberRCValSuccInSU(SUnit *SU,
108  unsigned RCId) {
109  unsigned NumberDeps = 0;
110  for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
111  I != E; ++I) {
112  if (I->isCtrl())
113  continue;
114 
115  SUnit *SuccSU = I->getSUnit();
116  const SDNode *ScegN = SuccSU->getNode();
117  if (!ScegN)
118  continue;
119 
120  // If value is passed to CopyToReg, it is probably
121  // live outside BB.
122  switch (ScegN->getOpcode()) {
123  default: break;
124  case ISD::TokenFactor: break;
125  case ISD::CopyFromReg: break;
126  case ISD::CopyToReg: NumberDeps++; break;
127  case ISD::INLINEASM: break;
128  }
129  if (!ScegN->isMachineOpcode())
130  continue;
131 
132  for (unsigned i = 0, e = ScegN->getNumOperands(); i != e; ++i) {
133  const SDValue &Op = ScegN->getOperand(i);
134  MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo());
135  if (TLI->isTypeLegal(VT)
136  && (TLI->getRegClassFor(VT)->getID() == RCId)) {
137  NumberDeps++;
138  break;
139  }
140  }
141  }
142  return NumberDeps;
143 }
144 
145 static unsigned numberCtrlDepsInSU(SUnit *SU) {
146  unsigned NumberDeps = 0;
147  for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
148  I != E; ++I)
149  if (I->isCtrl())
150  NumberDeps++;
151 
152  return NumberDeps;
153 }
154 
155 static unsigned numberCtrlPredInSU(SUnit *SU) {
156  unsigned NumberDeps = 0;
157  for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
158  I != E; ++I)
159  if (I->isCtrl())
160  NumberDeps++;
161 
162  return NumberDeps;
163 }
164 
165 ///
166 /// Initialize nodes.
167 ///
168 void ResourcePriorityQueue::initNodes(std::vector<SUnit> &sunits) {
169  SUnits = &sunits;
170  NumNodesSolelyBlocking.resize(SUnits->size(), 0);
171 
172  for (unsigned i = 0, e = SUnits->size(); i != e; ++i) {
173  SUnit *SU = &(*SUnits)[i];
174  initNumRegDefsLeft(SU);
175  SU->NodeQueueId = 0;
176  }
177 }
178 
179 /// This heuristic is used if DFA scheduling is not desired
180 /// for some VLIW platform.
181 bool resource_sort::operator()(const SUnit *LHS, const SUnit *RHS) const {
182  // The isScheduleHigh flag allows nodes with wraparound dependencies that
183  // cannot easily be modeled as edges with latencies to be scheduled as
184  // soon as possible in a top-down schedule.
185  if (LHS->isScheduleHigh && !RHS->isScheduleHigh)
186  return false;
187 
188  if (!LHS->isScheduleHigh && RHS->isScheduleHigh)
189  return true;
190 
191  unsigned LHSNum = LHS->NodeNum;
192  unsigned RHSNum = RHS->NodeNum;
193 
194  // The most important heuristic is scheduling the critical path.
195  unsigned LHSLatency = PQ->getLatency(LHSNum);
196  unsigned RHSLatency = PQ->getLatency(RHSNum);
197  if (LHSLatency < RHSLatency) return true;
198  if (LHSLatency > RHSLatency) return false;
199 
200  // After that, if two nodes have identical latencies, look to see if one will
201  // unblock more other nodes than the other.
202  unsigned LHSBlocked = PQ->getNumSolelyBlockNodes(LHSNum);
203  unsigned RHSBlocked = PQ->getNumSolelyBlockNodes(RHSNum);
204  if (LHSBlocked < RHSBlocked) return true;
205  if (LHSBlocked > RHSBlocked) return false;
206 
207  // Finally, just to provide a stable ordering, use the node number as a
208  // deciding factor.
209  return LHSNum < RHSNum;
210 }
211 
212 
213 /// getSingleUnscheduledPred - If there is exactly one unscheduled predecessor
214 /// of SU, return it, otherwise return null.
215 SUnit *ResourcePriorityQueue::getSingleUnscheduledPred(SUnit *SU) {
216  SUnit *OnlyAvailablePred = nullptr;
217  for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
218  I != E; ++I) {
219  SUnit &Pred = *I->getSUnit();
220  if (!Pred.isScheduled) {
221  // We found an available, but not scheduled, predecessor. If it's the
222  // only one we have found, keep track of it... otherwise give up.
223  if (OnlyAvailablePred && OnlyAvailablePred != &Pred)
224  return nullptr;
225  OnlyAvailablePred = &Pred;
226  }
227  }
228  return OnlyAvailablePred;
229 }
230 
232  // Look at all of the successors of this node. Count the number of nodes that
233  // this node is the sole unscheduled node for.
234  unsigned NumNodesBlocking = 0;
235  for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
236  I != E; ++I)
237  if (getSingleUnscheduledPred(I->getSUnit()) == SU)
238  ++NumNodesBlocking;
239 
240  NumNodesSolelyBlocking[SU->NodeNum] = NumNodesBlocking;
241  Queue.push_back(SU);
242 }
243 
244 /// Check if scheduling of this SU is possible
245 /// in the current packet.
247  if (!SU || !SU->getNode())
248  return false;
249 
250  // If this is a compound instruction,
251  // it is likely to be a call. Do not delay it.
252  if (SU->getNode()->getGluedNode())
253  return true;
254 
255  // First see if the pipeline could receive this instruction
256  // in the current cycle.
257  if (SU->getNode()->isMachineOpcode())
258  switch (SU->getNode()->getMachineOpcode()) {
259  default:
260  if (!ResourcesModel->canReserveResources(&TII->get(
261  SU->getNode()->getMachineOpcode())))
262  return false;
263  case TargetOpcode::EXTRACT_SUBREG:
264  case TargetOpcode::INSERT_SUBREG:
265  case TargetOpcode::SUBREG_TO_REG:
266  case TargetOpcode::REG_SEQUENCE:
267  case TargetOpcode::IMPLICIT_DEF:
268  break;
269  }
270 
271  // Now see if there are no other dependencies
272  // to instructions already in the packet.
273  for (unsigned i = 0, e = Packet.size(); i != e; ++i)
274  for (SUnit::const_succ_iterator I = Packet[i]->Succs.begin(),
275  E = Packet[i]->Succs.end(); I != E; ++I) {
276  // Since we do not add pseudos to packets, might as well
277  // ignore order deps.
278  if (I->isCtrl())
279  continue;
280 
281  if (I->getSUnit() == SU)
282  return false;
283  }
284 
285  return true;
286 }
287 
288 /// Keep track of available resources.
290  // If this SU does not fit in the packet
291  // start a new one.
292  if (!isResourceAvailable(SU) || SU->getNode()->getGluedNode()) {
293  ResourcesModel->clearResources();
294  Packet.clear();
295  }
296 
297  if (SU->getNode() && SU->getNode()->isMachineOpcode()) {
298  switch (SU->getNode()->getMachineOpcode()) {
299  default:
300  ResourcesModel->reserveResources(&TII->get(
301  SU->getNode()->getMachineOpcode()));
302  break;
303  case TargetOpcode::EXTRACT_SUBREG:
304  case TargetOpcode::INSERT_SUBREG:
305  case TargetOpcode::SUBREG_TO_REG:
306  case TargetOpcode::REG_SEQUENCE:
307  case TargetOpcode::IMPLICIT_DEF:
308  break;
309  }
310  Packet.push_back(SU);
311  }
312  // Forcefully end packet for PseudoOps.
313  else {
314  ResourcesModel->clearResources();
315  Packet.clear();
316  }
317 
318  // If packet is now full, reset the state so in the next cycle
319  // we start fresh.
320  if (Packet.size() >= InstrItins->SchedModel.IssueWidth) {
321  ResourcesModel->clearResources();
322  Packet.clear();
323  }
324 }
325 
327  int RegBalance = 0;
328 
329  if (!SU || !SU->getNode() || !SU->getNode()->isMachineOpcode())
330  return RegBalance;
331 
332  // Gen estimate.
333  for (unsigned i = 0, e = SU->getNode()->getNumValues(); i != e; ++i) {
334  MVT VT = SU->getNode()->getSimpleValueType(i);
335  if (TLI->isTypeLegal(VT)
336  && TLI->getRegClassFor(VT)
337  && TLI->getRegClassFor(VT)->getID() == RCId)
338  RegBalance += numberRCValSuccInSU(SU, RCId);
339  }
340  // Kill estimate.
341  for (unsigned i = 0, e = SU->getNode()->getNumOperands(); i != e; ++i) {
342  const SDValue &Op = SU->getNode()->getOperand(i);
343  MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo());
344  if (isa<ConstantSDNode>(Op.getNode()))
345  continue;
346 
347  if (TLI->isTypeLegal(VT) && TLI->getRegClassFor(VT)
348  && TLI->getRegClassFor(VT)->getID() == RCId)
349  RegBalance -= numberRCValPredInSU(SU, RCId);
350  }
351  return RegBalance;
352 }
353 
354 /// Estimates change in reg pressure from this SU.
355 /// It is achieved by trivial tracking of defined
356 /// and used vregs in dependent instructions.
357 /// The RawPressure flag makes this function to ignore
358 /// existing reg file sizes, and report raw def/use
359 /// balance.
360 int ResourcePriorityQueue::regPressureDelta(SUnit *SU, bool RawPressure) {
361  int RegBalance = 0;
362 
363  if (!SU || !SU->getNode() || !SU->getNode()->isMachineOpcode())
364  return RegBalance;
365 
366  if (RawPressure) {
368  E = TRI->regclass_end(); I != E; ++I) {
369  const TargetRegisterClass *RC = *I;
370  RegBalance += rawRegPressureDelta(SU, RC->getID());
371  }
372  }
373  else {
375  E = TRI->regclass_end(); I != E; ++I) {
376  const TargetRegisterClass *RC = *I;
377  if ((RegPressure[RC->getID()] +
378  rawRegPressureDelta(SU, RC->getID()) > 0) &&
379  (RegPressure[RC->getID()] +
380  rawRegPressureDelta(SU, RC->getID()) >= RegLimit[RC->getID()]))
381  RegBalance += rawRegPressureDelta(SU, RC->getID());
382  }
383  }
384 
385  return RegBalance;
386 }
387 
388 // Constants used to denote relative importance of
389 // heuristic components for cost computation.
390 static const unsigned PriorityOne = 200;
391 static const unsigned PriorityTwo = 50;
392 static const unsigned PriorityThree = 15;
393 static const unsigned PriorityFour = 5;
394 static const unsigned ScaleOne = 20;
395 static const unsigned ScaleTwo = 10;
396 static const unsigned ScaleThree = 5;
397 static const unsigned FactorOne = 2;
398 
399 /// Returns single number reflecting benefit of scheduling SU
400 /// in the current cycle.
402  // Initial trivial priority.
403  int ResCount = 1;
404 
405  // Do not waste time on a node that is already scheduled.
406  if (SU->isScheduled)
407  return ResCount;
408 
409  // Forced priority is high.
410  if (SU->isScheduleHigh)
411  ResCount += PriorityOne;
412 
413  // Adaptable scheduling
414  // A small, but very parallel
415  // region, where reg pressure is an issue.
416  if (HorizontalVerticalBalance > RegPressureThreshold) {
417  // Critical path first
418  ResCount += (SU->getHeight() * ScaleTwo);
419  // If resources are available for it, multiply the
420  // chance of scheduling.
421  if (isResourceAvailable(SU))
422  ResCount <<= FactorOne;
423 
424  // Consider change to reg pressure from scheduling
425  // this SU.
426  ResCount -= (regPressureDelta(SU,true) * ScaleOne);
427  }
428  // Default heuristic, greeady and
429  // critical path driven.
430  else {
431  // Critical path first.
432  ResCount += (SU->getHeight() * ScaleTwo);
433  // Now see how many instructions is blocked by this SU.
434  ResCount += (NumNodesSolelyBlocking[SU->NodeNum] * ScaleTwo);
435  // If resources are available for it, multiply the
436  // chance of scheduling.
437  if (isResourceAvailable(SU))
438  ResCount <<= FactorOne;
439 
440  ResCount -= (regPressureDelta(SU) * ScaleTwo);
441  }
442 
443  // These are platform-specific things.
444  // Will need to go into the back end
445  // and accessed from here via a hook.
446  for (SDNode *N = SU->getNode(); N; N = N->getGluedNode()) {
447  if (N->isMachineOpcode()) {
448  const MCInstrDesc &TID = TII->get(N->getMachineOpcode());
449  if (TID.isCall())
450  ResCount += (PriorityTwo + (ScaleThree*N->getNumValues()));
451  }
452  else
453  switch (N->getOpcode()) {
454  default: break;
455  case ISD::TokenFactor:
456  case ISD::CopyFromReg:
457  case ISD::CopyToReg:
458  ResCount += PriorityFour;
459  break;
460 
461  case ISD::INLINEASM:
462  ResCount += PriorityThree;
463  break;
464  }
465  }
466  return ResCount;
467 }
468 
469 
470 /// Main resource tracking point.
472  // Use NULL entry as an event marker to reset
473  // the DFA state.
474  if (!SU) {
475  ResourcesModel->clearResources();
476  Packet.clear();
477  return;
478  }
479 
480  const SDNode *ScegN = SU->getNode();
481  // Update reg pressure tracking.
482  // First update current node.
483  if (ScegN->isMachineOpcode()) {
484  // Estimate generated regs.
485  for (unsigned i = 0, e = ScegN->getNumValues(); i != e; ++i) {
486  MVT VT = ScegN->getSimpleValueType(i);
487 
488  if (TLI->isTypeLegal(VT)) {
489  const TargetRegisterClass *RC = TLI->getRegClassFor(VT);
490  if (RC)
491  RegPressure[RC->getID()] += numberRCValSuccInSU(SU, RC->getID());
492  }
493  }
494  // Estimate killed regs.
495  for (unsigned i = 0, e = ScegN->getNumOperands(); i != e; ++i) {
496  const SDValue &Op = ScegN->getOperand(i);
497  MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo());
498 
499  if (TLI->isTypeLegal(VT)) {
500  const TargetRegisterClass *RC = TLI->getRegClassFor(VT);
501  if (RC) {
502  if (RegPressure[RC->getID()] >
503  (numberRCValPredInSU(SU, RC->getID())))
504  RegPressure[RC->getID()] -= numberRCValPredInSU(SU, RC->getID());
505  else RegPressure[RC->getID()] = 0;
506  }
507  }
508  }
509  for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
510  I != E; ++I) {
511  if (I->isCtrl() || (I->getSUnit()->NumRegDefsLeft == 0))
512  continue;
513  --I->getSUnit()->NumRegDefsLeft;
514  }
515  }
516 
517  // Reserve resources for this SU.
518  reserveResources(SU);
519 
520  // Adjust number of parallel live ranges.
521  // Heuristic is simple - node with no data successors reduces
522  // number of live ranges. All others, increase it.
523  unsigned NumberNonControlDeps = 0;
524 
525  for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
526  I != E; ++I) {
527  adjustPriorityOfUnscheduledPreds(I->getSUnit());
528  if (!I->isCtrl())
529  NumberNonControlDeps++;
530  }
531 
532  if (!NumberNonControlDeps) {
533  if (ParallelLiveRanges >= SU->NumPreds)
534  ParallelLiveRanges -= SU->NumPreds;
535  else
536  ParallelLiveRanges = 0;
537 
538  }
539  else
540  ParallelLiveRanges += SU->NumRegDefsLeft;
541 
542  // Track parallel live chains.
543  HorizontalVerticalBalance += (SU->Succs.size() - numberCtrlDepsInSU(SU));
544  HorizontalVerticalBalance -= (SU->Preds.size() - numberCtrlPredInSU(SU));
545 }
546 
548  unsigned NodeNumDefs = 0;
549  for (SDNode *N = SU->getNode(); N; N = N->getGluedNode())
550  if (N->isMachineOpcode()) {
551  const MCInstrDesc &TID = TII->get(N->getMachineOpcode());
552  // No register need be allocated for this.
553  if (N->getMachineOpcode() == TargetOpcode::IMPLICIT_DEF) {
554  NodeNumDefs = 0;
555  break;
556  }
557  NodeNumDefs = std::min(N->getNumValues(), TID.getNumDefs());
558  }
559  else
560  switch(N->getOpcode()) {
561  default: break;
562  case ISD::CopyFromReg:
563  NodeNumDefs++;
564  break;
565  case ISD::INLINEASM:
566  NodeNumDefs++;
567  break;
568  }
569 
570  SU->NumRegDefsLeft = NodeNumDefs;
571 }
572 
573 /// adjustPriorityOfUnscheduledPreds - One of the predecessors of SU was just
574 /// scheduled. If SU is not itself available, then there is at least one
575 /// predecessor node that has not been scheduled yet. If SU has exactly ONE
576 /// unscheduled predecessor, we want to increase its priority: it getting
577 /// scheduled will make this node available, so it is better than some other
578 /// node of the same priority that will not make a node available.
579 void ResourcePriorityQueue::adjustPriorityOfUnscheduledPreds(SUnit *SU) {
580  if (SU->isAvailable) return; // All preds scheduled.
581 
582  SUnit *OnlyAvailablePred = getSingleUnscheduledPred(SU);
583  if (!OnlyAvailablePred || !OnlyAvailablePred->isAvailable)
584  return;
585 
586  // Okay, we found a single predecessor that is available, but not scheduled.
587  // Since it is available, it must be in the priority queue. First remove it.
588  remove(OnlyAvailablePred);
589 
590  // Reinsert the node into the priority queue, which recomputes its
591  // NumNodesSolelyBlocking value.
592  push(OnlyAvailablePred);
593 }
594 
595 
596 /// Main access point - returns next instructions
597 /// to be placed in scheduling sequence.
599  if (empty())
600  return nullptr;
601 
602  std::vector<SUnit *>::iterator Best = Queue.begin();
603  if (!DisableDFASched) {
604  int BestCost = SUSchedulingCost(*Best);
605  for (std::vector<SUnit *>::iterator I = std::next(Queue.begin()),
606  E = Queue.end(); I != E; ++I) {
607 
608  if (SUSchedulingCost(*I) > BestCost) {
609  BestCost = SUSchedulingCost(*I);
610  Best = I;
611  }
612  }
613  }
614  // Use default TD scheduling mechanism.
615  else {
616  for (std::vector<SUnit *>::iterator I = std::next(Queue.begin()),
617  E = Queue.end(); I != E; ++I)
618  if (Picker(*Best, *I))
619  Best = I;
620  }
621 
622  SUnit *V = *Best;
623  if (Best != std::prev(Queue.end()))
624  std::swap(*Best, Queue.back());
625 
626  Queue.pop_back();
627 
628  return V;
629 }
630 
631 
633  assert(!Queue.empty() && "Queue is empty!");
634  std::vector<SUnit *>::iterator I = find(Queue, SU);
635  if (I != std::prev(Queue.end()))
636  std::swap(*I, Queue.back());
637 
638  Queue.pop_back();
639 }
static const unsigned PriorityTwo
static const unsigned PriorityFour
unsigned NumPreds
Definition: ScheduleDAG.h:268
size_t i
unsigned IssueWidth
Definition: MCSchedule.h:139
static const unsigned ScaleTwo
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
Definition: MCInstrDesc.h:216
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:163
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
Return the register class ID number.
regclass_iterator regclass_end() const
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
static cl::opt< int > 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 reserveResources(SUnit *SU)
Keep track of available resources.
unsigned getResNo() const
get the index which selects a specific result in the SDNode
MachineFunction * MF
SmallVector< SDep, 4 > Preds
Definition: ScheduleDAG.h:258
static unsigned numberCtrlDepsInSU(SUnit *SU)
bool isScheduled
Definition: ScheduleDAG.h:286
unsigned getHeight() const
getHeight - Return the height of this node, which is the length of the maximum path down to any node ...
Definition: ScheduleDAG.h:425
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.
Definition: MCInstrDesc.h:242
unsigned getLatency(unsigned NodeNum) const
CopyToReg - This node has three operands: a chain, a register number to set to this value...
Definition: ISDOpcodes.h:170
void initNumRegDefsLeft(SUnit *SU)
InitNumRegDefsLeft - Determine the # of regs defined by this node.
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:589
ResourcePriorityQueue(SelectionDAGISel *IS)
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
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.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:395
int rawRegPressureDelta(SUnit *SU, unsigned RCId)
regclass_iterator regclass_begin() const
Register class iterators.
MVT - Machine Value Type.
SDNode * getNode() const
getNode - Return the representative SDNode for this SUnit.
Definition: ScheduleDAG.h:371
int SUSchedulingCost(SUnit *SU)
Single cost function reflecting benefit of scheduling SU in the current cycle.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
void remove(SUnit *SU) override
TokenFactor - This node takes multiple tokens as input and produces a single token result...
Definition: ISDOpcodes.h:50
bool isScheduleHigh
Definition: ScheduleDAG.h:287
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:757
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.
Definition: BitVector.h:586
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.
bool isAvailable
Definition: ScheduleDAG.h:285
unsigned NodeQueueId
Definition: ScheduleDAG.h:267
static const unsigned FactorOne
MCSchedModel SchedModel
Basic machine properties.
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
unsigned short NumRegDefsLeft
Definition: ScheduleDAG.h:274
static const unsigned PriorityThree
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
Definition: ISDOpcodes.h:175
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
Return the register pressure "high water mark" for the specific register class.
unsigned NodeNum
Definition: ScheduleDAG.h:266
static const unsigned ScaleOne
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual const TargetInstrInfo * getInstrInfo() const
SmallVector< SDep, 4 > Succs
Definition: ScheduleDAG.h:259
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
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
int regPressureDelta(SUnit *SU, bool RawPressure=false)
Estimates change in reg pressure from this SU.
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.
Definition: ScheduleDAG.h:244
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.