blob: db38b76cf93a982b34a5992fa3cd32d1421f09d6 [file] [log] [blame]
Andrew Trickee498d32012-02-01 22:13:57 +00001//===- 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
Andrew Trickee498d32012-02-01 22:13:57 +000022#include "llvm/CodeGen/ResourcePriorityQueue.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000023#include "llvm/CodeGen/MachineInstr.h"
24#include "llvm/CodeGen/SelectionDAGNodes.h"
Andrew Trickee498d32012-02-01 22:13:57 +000025#include "llvm/Support/CommandLine.h"
26#include "llvm/Support/Debug.h"
27#include "llvm/Support/raw_ostream.h"
Andrew Trickee498d32012-02-01 22:13:57 +000028#include "llvm/Target/TargetLowering.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000029#include "llvm/Target/TargetMachine.h"
Stephen Hines37ed9c12014-12-01 14:51:49 -080030#include "llvm/Target/TargetSubtargetInfo.h"
Andrew Trickee498d32012-02-01 22:13:57 +000031
32using namespace llvm;
33
Stephen Hinesdce4a402014-05-29 02:49:00 -070034#define DEBUG_TYPE "scheduler"
35
Andrew Trickee498d32012-02-01 22:13:57 +000036static 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
40static cl::opt<signed> RegPressureThreshold(
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
Stephen Hines37ed9c12014-12-01 14:51:49 -080044ResourcePriorityQueue::ResourcePriorityQueue(SelectionDAGISel *IS)
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 = TII->CreateTargetScheduleState(STI);
51 // This hard requirement could be relaxed, but for now
52 // do not let it procede.
53 assert(ResourcesModel && "Unimplemented CreateTargetScheduleState.");
Andrew Trickee498d32012-02-01 22:13:57 +000054
Stephen Hines37ed9c12014-12-01 14:51:49 -080055 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);
60 for (TargetRegisterInfo::regclass_iterator I = TRI->regclass_begin(),
61 E = TRI->regclass_end();
62 I != E; ++I)
63 RegLimit[(*I)->getID()] = TRI->getRegPressureLimit(*I, *IS->MF);
Andrew Trickee498d32012-02-01 22:13:57 +000064
Stephen Hines37ed9c12014-12-01 14:51:49 -080065 ParallelLiveRanges = 0;
66 HorizontalVerticalBalance = 0;
Andrew Trickee498d32012-02-01 22:13:57 +000067}
68
69unsigned
70ResourcePriorityQueue::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) {
Patrik Hagglunda61b17c2012-12-13 06:34:11 +000096 MVT VT = ScegN->getSimpleValueType(i);
Andrew Trickee498d32012-02-01 22:13:57 +000097 if (TLI->isTypeLegal(VT)
Patrik Hagglunda61b17c2012-12-13 06:34:11 +000098 && (TLI->getRegClassFor(VT)->getID() == RCId)) {
Andrew Trickee498d32012-02-01 22:13:57 +000099 NumberDeps++;
100 break;
101 }
102 }
103 }
104 return NumberDeps;
105}
106
107unsigned 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);
Patrik Hagglunda61b17c2012-12-13 06:34:11 +0000134 MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo());
Andrew Trickee498d32012-02-01 22:13:57 +0000135 if (TLI->isTypeLegal(VT)
Patrik Hagglunda61b17c2012-12-13 06:34:11 +0000136 && (TLI->getRegClassFor(VT)->getID() == RCId)) {
Andrew Trickee498d32012-02-01 22:13:57 +0000137 NumberDeps++;
138 break;
139 }
140 }
141 }
142 return NumberDeps;
143}
144
145static 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
155static 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///
168void 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.
181bool 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.
215SUnit *ResourcePriorityQueue::getSingleUnscheduledPred(SUnit *SU) {
Stephen Hinesdce4a402014-05-29 02:49:00 -0700216 SUnit *OnlyAvailablePred = nullptr;
Andrew Trickee498d32012-02-01 22:13:57 +0000217 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)
Stephen Hinesdce4a402014-05-29 02:49:00 -0700224 return nullptr;
Andrew Trickee498d32012-02-01 22:13:57 +0000225 OnlyAvailablePred = &Pred;
226 }
227 }
228 return OnlyAvailablePred;
229}
230
231void ResourcePriorityQueue::push(SUnit *SU) {
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.
246bool ResourcePriorityQueue::isResourceAvailable(SUnit *SU) {
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 alredy 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 // ignor 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.
289void ResourcePriorityQueue::reserveResources(SUnit *SU) {
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.
Stephen Hines37ed9c12014-12-01 14:51:49 -0800320 if (Packet.size() >= InstrItins->SchedModel.IssueWidth) {
Andrew Trickee498d32012-02-01 22:13:57 +0000321 ResourcesModel->clearResources();
322 Packet.clear();
323 }
324}
325
326signed ResourcePriorityQueue::rawRegPressureDelta(SUnit *SU, unsigned RCId) {
327 signed 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) {
Patrik Hagglunda61b17c2012-12-13 06:34:11 +0000334 MVT VT = SU->getNode()->getSimpleValueType(i);
Andrew Trickee498d32012-02-01 22:13:57 +0000335 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);
Patrik Hagglunda61b17c2012-12-13 06:34:11 +0000343 MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo());
Andrew Trickee498d32012-02-01 22:13:57 +0000344 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.
Benjamin Kramerd9b0b022012-06-02 10:20:22 +0000355/// It is achieved by trivial tracking of defined
Andrew Trickee498d32012-02-01 22:13:57 +0000356/// 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.
360signed ResourcePriorityQueue::regPressureDelta(SUnit *SU, bool RawPressure) {
361 signed RegBalance = 0;
362
363 if (!SU || !SU->getNode() || !SU->getNode()->isMachineOpcode())
364 return RegBalance;
365
366 if (RawPressure) {
367 for (TargetRegisterInfo::regclass_iterator I = TRI->regclass_begin(),
368 E = TRI->regclass_end(); I != E; ++I) {
369 const TargetRegisterClass *RC = *I;
370 RegBalance += rawRegPressureDelta(SU, RC->getID());
371 }
372 }
373 else {
374 for (TargetRegisterInfo::regclass_iterator I = TRI->regclass_begin(),
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.
390static const unsigned PriorityOne = 200;
Eli Friedman3b389cb2013-09-11 00:41:02 +0000391static const unsigned PriorityTwo = 50;
392static const unsigned PriorityThree = 15;
393static const unsigned PriorityFour = 5;
Andrew Trickee498d32012-02-01 22:13:57 +0000394static const unsigned ScaleOne = 20;
395static const unsigned ScaleTwo = 10;
396static const unsigned ScaleThree = 5;
397static const unsigned FactorOne = 2;
398
399/// Returns single number reflecting benefit of scheduling SU
400/// in the current cycle.
401signed ResourcePriorityQueue::SUSchedulingCost(SUnit *SU) {
402 // Initial trivial priority.
403 signed 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
Stephen Hinesc6a4f5e2014-07-21 00:45:20 -0700443 // These are platform-specific things.
Andrew Trickee498d32012-02-01 22:13:57 +0000444 // 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())
Eli Friedman3b389cb2013-09-11 00:41:02 +0000450 ResCount += (PriorityTwo + (ScaleThree*N->getNumValues()));
Andrew Trickee498d32012-02-01 22:13:57 +0000451 }
452 else
453 switch (N->getOpcode()) {
454 default: break;
455 case ISD::TokenFactor:
456 case ISD::CopyFromReg:
457 case ISD::CopyToReg:
Eli Friedman3b389cb2013-09-11 00:41:02 +0000458 ResCount += PriorityFour;
Andrew Trickee498d32012-02-01 22:13:57 +0000459 break;
460
461 case ISD::INLINEASM:
Eli Friedman3b389cb2013-09-11 00:41:02 +0000462 ResCount += PriorityThree;
Andrew Trickee498d32012-02-01 22:13:57 +0000463 break;
464 }
465 }
466 return ResCount;
467}
468
469
470/// Main resource tracking point.
Andrew Trick953be892012-03-07 23:00:49 +0000471void ResourcePriorityQueue::scheduledNode(SUnit *SU) {
Andrew Trickee498d32012-02-01 22:13:57 +0000472 // 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) {
Patrik Hagglunda61b17c2012-12-13 06:34:11 +0000486 MVT VT = ScegN->getSimpleValueType(i);
Andrew Trickee498d32012-02-01 22:13:57 +0000487
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);
Patrik Hagglunda61b17c2012-12-13 06:34:11 +0000497 MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo());
Andrew Trickee498d32012-02-01 22:13:57 +0000498
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
547void ResourcePriorityQueue::initNumRegDefsLeft(SUnit *SU) {
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.
579void ResourcePriorityQueue::adjustPriorityOfUnscheduledPreds(SUnit *SU) {
580 if (SU->isAvailable) return; // All preds scheduled.
581
582 SUnit *OnlyAvailablePred = getSingleUnscheduledPred(SU);
Stephen Hinesdce4a402014-05-29 02:49:00 -0700583 if (!OnlyAvailablePred || !OnlyAvailablePred->isAvailable)
Andrew Trickee498d32012-02-01 22:13:57 +0000584 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.
598SUnit *ResourcePriorityQueue::pop() {
599 if (empty())
Stephen Hinesdce4a402014-05-29 02:49:00 -0700600 return nullptr;
Andrew Trickee498d32012-02-01 22:13:57 +0000601
602 std::vector<SUnit *>::iterator Best = Queue.begin();
603 if (!DisableDFASched) {
604 signed BestCost = SUSchedulingCost(*Best);
Stephen Hines36b56882014-04-23 16:57:46 -0700605 for (std::vector<SUnit *>::iterator I = std::next(Queue.begin()),
Andrew Trickee498d32012-02-01 22:13:57 +0000606 E = Queue.end(); I != E; ++I) {
Andrew Trickee498d32012-02-01 22:13:57 +0000607
608 if (SUSchedulingCost(*I) > BestCost) {
609 BestCost = SUSchedulingCost(*I);
610 Best = I;
611 }
612 }
613 }
614 // Use default TD scheduling mechanism.
615 else {
Stephen Hines36b56882014-04-23 16:57:46 -0700616 for (std::vector<SUnit *>::iterator I = std::next(Queue.begin()),
Andrew Trickee498d32012-02-01 22:13:57 +0000617 E = Queue.end(); I != E; ++I)
618 if (Picker(*Best, *I))
619 Best = I;
620 }
621
622 SUnit *V = *Best;
Stephen Hines36b56882014-04-23 16:57:46 -0700623 if (Best != std::prev(Queue.end()))
Andrew Trickee498d32012-02-01 22:13:57 +0000624 std::swap(*Best, Queue.back());
625
626 Queue.pop_back();
627
628 return V;
629}
630
631
632void ResourcePriorityQueue::remove(SUnit *SU) {
633 assert(!Queue.empty() && "Queue is empty!");
634 std::vector<SUnit *>::iterator I = std::find(Queue.begin(), Queue.end(), SU);
Stephen Hines36b56882014-04-23 16:57:46 -0700635 if (I != std::prev(Queue.end()))
Andrew Trickee498d32012-02-01 22:13:57 +0000636 std::swap(*I, Queue.back());
637
638 Queue.pop_back();
639}
640
641
642#ifdef NDEBUG
643void ResourcePriorityQueue::dump(ScheduleDAG *DAG) const {}
644#else
645void ResourcePriorityQueue::dump(ScheduleDAG *DAG) const {
646 ResourcePriorityQueue q = *this;
647 while (!q.empty()) {
648 SUnit *su = q.pop();
649 dbgs() << "Height " << su->getHeight() << ": ";
650 su->dump(DAG);
651 }
652}
653#endif