LLVM 22.0.0git
ScheduleDAGFast.cpp
Go to the documentation of this file.
1//===----- ScheduleDAGFast.cpp - Fast poor list scheduler -----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This implements a fast scheduler.
10//
11//===----------------------------------------------------------------------===//
12
13#include "InstrEmitter.h"
14#include "SDNodeDbgValue.h"
15#include "ScheduleDAGSDNodes.h"
16#include "llvm/ADT/SmallSet.h"
17#include "llvm/ADT/Statistic.h"
22#include "llvm/IR/InlineAsm.h"
23#include "llvm/Support/Debug.h"
26using namespace llvm;
27
28#define DEBUG_TYPE "pre-RA-sched"
29
30STATISTIC(NumUnfolds, "Number of nodes unfolded");
31STATISTIC(NumDups, "Number of duplicated nodes");
32STATISTIC(NumPRCopies, "Number of physical copies");
33
35 fastDAGScheduler("fast", "Fast suboptimal list scheduling",
38 linearizeDAGScheduler("linearize", "Linearize DAG, no scheduling",
40
41
42namespace {
43 /// FastPriorityQueue - A degenerate priority queue that considers
44 /// all nodes to have the same priority.
45 ///
46 struct FastPriorityQueue {
48
49 bool empty() const { return Queue.empty(); }
50
51 void push(SUnit *U) {
52 Queue.push_back(U);
53 }
54
55 SUnit *pop() {
56 if (empty()) return nullptr;
57 return Queue.pop_back_val();
58 }
59 };
60
61//===----------------------------------------------------------------------===//
62/// ScheduleDAGFast - The actual "fast" list scheduler implementation.
63///
64class ScheduleDAGFast : public ScheduleDAGSDNodes {
65private:
66 /// AvailableQueue - The priority queue to use for the available SUnits.
67 FastPriorityQueue AvailableQueue;
68
69 /// LiveRegDefs - A set of physical registers and their definition
70 /// that are "live". These nodes must be scheduled before any other nodes that
71 /// modifies the registers can be scheduled.
72 unsigned NumLiveRegs = 0u;
73 std::vector<SUnit*> LiveRegDefs;
74 std::vector<unsigned> LiveRegCycles;
75
76public:
77 ScheduleDAGFast(MachineFunction &mf)
78 : ScheduleDAGSDNodes(mf) {}
79
80 void Schedule() override;
81
82 /// AddPred - adds a predecessor edge to SUnit SU.
83 void AddPred(SUnit *SU, const SDep &D) { SU->addPred(D); }
84
85 /// RemovePred - removes a predecessor edge from SUnit SU.
86 void RemovePred(SUnit *SU, const SDep &D) { SU->removePred(D); }
87
88private:
89 void ReleasePred(SUnit *SU, SDep *PredEdge);
90 void ReleasePredecessors(SUnit *SU, unsigned CurCycle);
91 void ScheduleNodeBottomUp(SUnit*, unsigned);
92 SUnit *CopyAndMoveSuccessors(SUnit*);
93 void InsertCopiesAndMoveSuccs(SUnit*, unsigned,
97 bool DelayForLiveRegsBottomUp(SUnit*, SmallVectorImpl<unsigned>&);
98 void ListScheduleBottomUp();
99
100 /// forceUnitLatencies - The fast scheduler doesn't care about real latencies.
101 bool forceUnitLatencies() const override { return true; }
102};
103} // end anonymous namespace
104
105
106/// Schedule - Schedule the DAG using list scheduling.
107void ScheduleDAGFast::Schedule() {
108 LLVM_DEBUG(dbgs() << "********** List Scheduling **********\n");
109
110 NumLiveRegs = 0;
111 LiveRegDefs.resize(TRI->getNumRegs(), nullptr);
112 LiveRegCycles.resize(TRI->getNumRegs(), 0);
113
114 // Build the scheduling graph.
115 BuildSchedGraph();
116
117 LLVM_DEBUG(dump());
118
119 // Execute the actual scheduling loop.
120 ListScheduleBottomUp();
121}
122
123//===----------------------------------------------------------------------===//
124// Bottom-Up Scheduling
125//===----------------------------------------------------------------------===//
126
127/// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to
128/// the AvailableQueue if the count reaches zero. Also update its cycle bound.
129void ScheduleDAGFast::ReleasePred(SUnit *SU, SDep *PredEdge) {
130 SUnit *PredSU = PredEdge->getSUnit();
131
132#ifndef NDEBUG
133 if (PredSU->NumSuccsLeft == 0) {
134 dbgs() << "*** Scheduling failed! ***\n";
135 dumpNode(*PredSU);
136 dbgs() << " has been released too many times!\n";
137 llvm_unreachable(nullptr);
138 }
139#endif
140 --PredSU->NumSuccsLeft;
141
142 // If all the node's successors are scheduled, this node is ready
143 // to be scheduled. Ignore the special EntrySU node.
144 if (PredSU->NumSuccsLeft == 0 && PredSU != &EntrySU) {
145 PredSU->isAvailable = true;
146 AvailableQueue.push(PredSU);
147 }
148}
149
150void ScheduleDAGFast::ReleasePredecessors(SUnit *SU, unsigned CurCycle) {
151 // Bottom up: release predecessors
152 for (SDep &Pred : SU->Preds) {
153 ReleasePred(SU, &Pred);
154 if (Pred.isAssignedRegDep()) {
155 // This is a physical register dependency and it's impossible or
156 // expensive to copy the register. Make sure nothing that can
157 // clobber the register is scheduled between the predecessor and
158 // this node.
159 if (!LiveRegDefs[Pred.getReg()]) {
160 ++NumLiveRegs;
161 LiveRegDefs[Pred.getReg()] = Pred.getSUnit();
162 LiveRegCycles[Pred.getReg()] = CurCycle;
163 }
164 }
165 }
166}
167
168/// ScheduleNodeBottomUp - Add the node to the schedule. Decrement the pending
169/// count of its predecessors. If a predecessor pending count is zero, add it to
170/// the Available queue.
171void ScheduleDAGFast::ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle) {
172 LLVM_DEBUG(dbgs() << "*** Scheduling [" << CurCycle << "]: ");
173 LLVM_DEBUG(dumpNode(*SU));
174
175 assert(CurCycle >= SU->getHeight() && "Node scheduled below its height!");
176 SU->setHeightToAtLeast(CurCycle);
177 Sequence.push_back(SU);
178
179 ReleasePredecessors(SU, CurCycle);
180
181 // Release all the implicit physical register defs that are live.
182 for (SDep &Succ : SU->Succs) {
183 if (Succ.isAssignedRegDep()) {
184 if (LiveRegCycles[Succ.getReg()] == Succ.getSUnit()->getHeight()) {
185 assert(NumLiveRegs > 0 && "NumLiveRegs is already zero!");
186 assert(LiveRegDefs[Succ.getReg()] == SU &&
187 "Physical register dependency violated?");
188 --NumLiveRegs;
189 LiveRegDefs[Succ.getReg()] = nullptr;
190 LiveRegCycles[Succ.getReg()] = 0;
191 }
192 }
193 }
194
195 SU->isScheduled = true;
196}
197
198/// CopyAndMoveSuccessors - Clone the specified node and move its scheduled
199/// successors to the newly created node.
200SUnit *ScheduleDAGFast::CopyAndMoveSuccessors(SUnit *SU) {
201 if (SU->getNode()->getGluedNode())
202 return nullptr;
203
204 SDNode *N = SU->getNode();
205 if (!N)
206 return nullptr;
207
208 SUnit *NewSU;
209 bool TryUnfold = false;
210 for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) {
211 MVT VT = N->getSimpleValueType(i);
212 if (VT == MVT::Glue)
213 return nullptr;
214 else if (VT == MVT::Other)
215 TryUnfold = true;
216 }
217 for (const SDValue &Op : N->op_values()) {
218 MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo());
219 if (VT == MVT::Glue)
220 return nullptr;
221 }
222
223 if (TryUnfold) {
225 if (!TII->unfoldMemoryOperand(*DAG, N, NewNodes))
226 return nullptr;
227
228 LLVM_DEBUG(dbgs() << "Unfolding SU # " << SU->NodeNum << "\n");
229 assert(NewNodes.size() == 2 && "Expected a load folding node!");
230
231 N = NewNodes[1];
232 SDNode *LoadNode = NewNodes[0];
233 unsigned NumVals = N->getNumValues();
234 unsigned OldNumVals = SU->getNode()->getNumValues();
235 for (unsigned i = 0; i != NumVals; ++i)
236 DAG->ReplaceAllUsesOfValueWith(SDValue(SU->getNode(), i), SDValue(N, i));
237 DAG->ReplaceAllUsesOfValueWith(SDValue(SU->getNode(), OldNumVals-1),
238 SDValue(LoadNode, 1));
239
240 SUnit *NewSU = newSUnit(N);
241 assert(N->getNodeId() == -1 && "Node already inserted!");
242 N->setNodeId(NewSU->NodeNum);
243
244 const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
245 for (unsigned i = 0; i != MCID.getNumOperands(); ++i) {
246 if (MCID.getOperandConstraint(i, MCOI::TIED_TO) != -1) {
247 NewSU->isTwoAddress = true;
248 break;
249 }
250 }
251 if (MCID.isCommutable())
252 NewSU->isCommutable = true;
253
254 // LoadNode may already exist. This can happen when there is another
255 // load from the same location and producing the same type of value
256 // but it has different alignment or volatileness.
257 bool isNewLoad = true;
258 SUnit *LoadSU;
259 if (LoadNode->getNodeId() != -1) {
260 LoadSU = &SUnits[LoadNode->getNodeId()];
261 isNewLoad = false;
262 } else {
263 LoadSU = newSUnit(LoadNode);
264 LoadNode->setNodeId(LoadSU->NodeNum);
265 }
266
267 SDep ChainPred;
268 SmallVector<SDep, 4> ChainSuccs;
269 SmallVector<SDep, 4> LoadPreds;
270 SmallVector<SDep, 4> NodePreds;
271 SmallVector<SDep, 4> NodeSuccs;
272 for (SDep &Pred : SU->Preds) {
273 if (Pred.isCtrl())
274 ChainPred = Pred;
275 else if (Pred.getSUnit()->getNode() &&
276 Pred.getSUnit()->getNode()->isOperandOf(LoadNode))
277 LoadPreds.push_back(Pred);
278 else
279 NodePreds.push_back(Pred);
280 }
281 for (SDep &Succ : SU->Succs) {
282 if (Succ.isCtrl())
283 ChainSuccs.push_back(Succ);
284 else
285 NodeSuccs.push_back(Succ);
286 }
287
288 if (ChainPred.getSUnit()) {
289 RemovePred(SU, ChainPred);
290 if (isNewLoad)
291 AddPred(LoadSU, ChainPred);
292 }
293 for (const SDep &Pred : LoadPreds) {
294 RemovePred(SU, Pred);
295 if (isNewLoad) {
296 AddPred(LoadSU, Pred);
297 }
298 }
299 for (const SDep &Pred : NodePreds) {
300 RemovePred(SU, Pred);
301 AddPred(NewSU, Pred);
302 }
303 for (SDep D : NodeSuccs) {
304 SUnit *SuccDep = D.getSUnit();
305 D.setSUnit(SU);
306 RemovePred(SuccDep, D);
307 D.setSUnit(NewSU);
308 AddPred(SuccDep, D);
309 }
310 for (SDep D : ChainSuccs) {
311 SUnit *SuccDep = D.getSUnit();
312 D.setSUnit(SU);
313 RemovePred(SuccDep, D);
314 if (isNewLoad) {
315 D.setSUnit(LoadSU);
316 AddPred(SuccDep, D);
317 }
318 }
319 if (isNewLoad) {
320 SDep D(LoadSU, SDep::Barrier);
321 D.setLatency(LoadSU->Latency);
322 AddPred(NewSU, D);
323 }
324
325 ++NumUnfolds;
326
327 if (NewSU->NumSuccsLeft == 0) {
328 NewSU->isAvailable = true;
329 return NewSU;
330 }
331 SU = NewSU;
332 }
333
334 LLVM_DEBUG(dbgs() << "Duplicating SU # " << SU->NodeNum << "\n");
335 NewSU = Clone(SU);
336
337 // New SUnit has the exact same predecessors.
338 for (SDep &Pred : SU->Preds)
339 if (!Pred.isArtificial())
340 AddPred(NewSU, Pred);
341
342 // Only copy scheduled successors. Cut them from old node's successor
343 // list and move them over.
345 for (SDep &Succ : SU->Succs) {
346 if (Succ.isArtificial())
347 continue;
348 SUnit *SuccSU = Succ.getSUnit();
349 if (SuccSU->isScheduled) {
350 SDep D = Succ;
351 D.setSUnit(NewSU);
352 AddPred(SuccSU, D);
353 D.setSUnit(SU);
354 DelDeps.push_back(std::make_pair(SuccSU, D));
355 }
356 }
357 for (const auto &[Del, Dep] : DelDeps)
358 RemovePred(Del, Dep);
359
360 ++NumDups;
361 return NewSU;
362}
363
364/// InsertCopiesAndMoveSuccs - Insert register copies and move all
365/// scheduled successors of the given SUnit to the last copy.
366void ScheduleDAGFast::InsertCopiesAndMoveSuccs(SUnit *SU, unsigned Reg,
367 const TargetRegisterClass *DestRC,
368 const TargetRegisterClass *SrcRC,
370 SUnit *CopyFromSU = newSUnit(static_cast<SDNode *>(nullptr));
371 CopyFromSU->CopySrcRC = SrcRC;
372 CopyFromSU->CopyDstRC = DestRC;
373
374 SUnit *CopyToSU = newSUnit(static_cast<SDNode *>(nullptr));
375 CopyToSU->CopySrcRC = DestRC;
376 CopyToSU->CopyDstRC = SrcRC;
377
378 // Only copy scheduled successors. Cut them from old node's successor
379 // list and move them over.
381 for (SDep &Succ : SU->Succs) {
382 if (Succ.isArtificial())
383 continue;
384 SUnit *SuccSU = Succ.getSUnit();
385 if (SuccSU->isScheduled) {
386 SDep D = Succ;
387 D.setSUnit(CopyToSU);
388 AddPred(SuccSU, D);
389 DelDeps.push_back(std::make_pair(SuccSU, Succ));
390 }
391 }
392 for (const auto &[Del, Dep] : DelDeps)
393 RemovePred(Del, Dep);
394 SDep FromDep(SU, SDep::Data, Reg);
395 FromDep.setLatency(SU->Latency);
396 AddPred(CopyFromSU, FromDep);
397 SDep ToDep(CopyFromSU, SDep::Data, 0);
398 ToDep.setLatency(CopyFromSU->Latency);
399 AddPred(CopyToSU, ToDep);
400
401 Copies.push_back(CopyFromSU);
402 Copies.push_back(CopyToSU);
403
404 ++NumPRCopies;
405}
406
407/// getPhysicalRegisterVT - Returns the ValueType of the physical register
408/// definition of the specified node.
409/// FIXME: Move to SelectionDAG?
410static MVT getPhysicalRegisterVT(SDNode *N, unsigned Reg,
411 const TargetInstrInfo *TII) {
412 unsigned NumRes;
413 if (N->getOpcode() == ISD::CopyFromReg) {
414 // CopyFromReg has: "chain, Val, glue" so operand 1 gives the type.
415 NumRes = 1;
416 } else {
417 const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
418 assert(!MCID.implicit_defs().empty() &&
419 "Physical reg def must be in implicit def list!");
420 NumRes = MCID.getNumDefs();
421 for (MCPhysReg ImpDef : MCID.implicit_defs()) {
422 if (Reg == ImpDef)
423 break;
424 ++NumRes;
425 }
426 }
427 return N->getSimpleValueType(NumRes);
428}
429
430/// CheckForLiveRegDef - Return true and update live register vector if the
431/// specified register def of the specified SUnit clobbers any "live" registers.
433 std::vector<SUnit *> &LiveRegDefs,
434 SmallSet<unsigned, 4> &RegAdded,
436 const TargetRegisterInfo *TRI,
437 const SDNode *Node = nullptr) {
438 bool Added = false;
439 for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) {
440 // Check if Ref is live.
441 if (!LiveRegDefs[*AI])
442 continue;
443
444 // Allow multiple uses of the same def.
445 if (LiveRegDefs[*AI] == SU)
446 continue;
447
448 // Allow multiple uses of same def
449 if (Node && LiveRegDefs[*AI]->getNode() == Node)
450 continue;
451
452 // Add Reg to the set of interfering live regs.
453 if (RegAdded.insert(*AI).second) {
454 LRegs.push_back(*AI);
455 Added = true;
456 }
457 }
458 return Added;
459}
460
461/// DelayForLiveRegsBottomUp - Returns true if it is necessary to delay
462/// scheduling of the given node to satisfy live physical register dependencies.
463/// If the specific node is the last one that's available to schedule, do
464/// whatever is necessary (i.e. backtracking or cloning) to make it possible.
465bool ScheduleDAGFast::DelayForLiveRegsBottomUp(SUnit *SU,
467 if (NumLiveRegs == 0)
468 return false;
469
470 SmallSet<unsigned, 4> RegAdded;
471 // If this node would clobber any "live" register, then it's not ready.
472 for (SDep &Pred : SU->Preds) {
473 if (Pred.isAssignedRegDep()) {
474 CheckForLiveRegDef(Pred.getSUnit(), Pred.getReg(), LiveRegDefs,
475 RegAdded, LRegs, TRI);
476 }
477 }
478
479 for (SDNode *Node = SU->getNode(); Node; Node = Node->getGluedNode()) {
480 if (Node->getOpcode() == ISD::INLINEASM ||
481 Node->getOpcode() == ISD::INLINEASM_BR) {
482 // Inline asm can clobber physical defs.
483 unsigned NumOps = Node->getNumOperands();
484 if (Node->getOperand(NumOps-1).getValueType() == MVT::Glue)
485 --NumOps; // Ignore the glue operand.
486
487 for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) {
488 unsigned Flags = Node->getConstantOperandVal(i);
489 const InlineAsm::Flag F(Flags);
490 unsigned NumVals = F.getNumOperandRegisters();
491
492 ++i; // Skip the ID value.
493 if (F.isRegDefKind() || F.isRegDefEarlyClobberKind() ||
494 F.isClobberKind()) {
495 // Check for def of register or earlyclobber register.
496 for (; NumVals; --NumVals, ++i) {
497 Register Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
498 if (Reg.isPhysical())
499 CheckForLiveRegDef(SU, Reg, LiveRegDefs, RegAdded, LRegs, TRI);
500 }
501 } else
502 i += NumVals;
503 }
504 continue;
505 }
506
507 if (Node->getOpcode() == ISD::CopyToReg) {
508 Register Reg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
509 if (Reg.isPhysical()) {
510 SDNode *SrcNode = Node->getOperand(2).getNode();
511 CheckForLiveRegDef(SU, Reg, LiveRegDefs, RegAdded, LRegs, TRI, SrcNode);
512 }
513 }
514
515 if (!Node->isMachineOpcode())
516 continue;
517 const MCInstrDesc &MCID = TII->get(Node->getMachineOpcode());
518 for (MCPhysReg Reg : MCID.implicit_defs())
519 CheckForLiveRegDef(SU, Reg, LiveRegDefs, RegAdded, LRegs, TRI);
520 }
521 return !LRegs.empty();
522}
523
524
525/// ListScheduleBottomUp - The main loop of list scheduling for bottom-up
526/// schedulers.
527void ScheduleDAGFast::ListScheduleBottomUp() {
528 unsigned CurCycle = 0;
529
530 // Release any predecessors of the special Exit node.
531 ReleasePredecessors(&ExitSU, CurCycle);
532
533 // Add root to Available queue.
534 if (!SUnits.empty()) {
535 SUnit *RootSU = &SUnits[DAG->getRoot().getNode()->getNodeId()];
536 assert(RootSU->Succs.empty() && "Graph root shouldn't have successors!");
537 RootSU->isAvailable = true;
538 AvailableQueue.push(RootSU);
539 }
540
541 // While Available queue is not empty, grab the node with the highest
542 // priority. If it is not ready put it back. Schedule the node.
543 SmallVector<SUnit*, 4> NotReady;
545 Sequence.reserve(SUnits.size());
546 while (!AvailableQueue.empty()) {
547 bool Delayed = false;
548 LRegsMap.clear();
549 SUnit *CurSU = AvailableQueue.pop();
550 while (CurSU) {
552 if (!DelayForLiveRegsBottomUp(CurSU, LRegs))
553 break;
554 Delayed = true;
555 LRegsMap.insert(std::make_pair(CurSU, LRegs));
556
557 CurSU->isPending = true; // This SU is not in AvailableQueue right now.
558 NotReady.push_back(CurSU);
559 CurSU = AvailableQueue.pop();
560 }
561
562 // All candidates are delayed due to live physical reg dependencies.
563 // Try code duplication or inserting cross class copies
564 // to resolve it.
565 if (Delayed && !CurSU) {
566 if (!CurSU) {
567 // Try duplicating the nodes that produces these
568 // "expensive to copy" values to break the dependency. In case even
569 // that doesn't work, insert cross class copies.
570 SUnit *TrySU = NotReady[0];
571 SmallVectorImpl<unsigned> &LRegs = LRegsMap[TrySU];
572 assert(LRegs.size() == 1 && "Can't handle this yet!");
573 unsigned Reg = LRegs[0];
574 SUnit *LRDef = LiveRegDefs[Reg];
575 MVT VT = getPhysicalRegisterVT(LRDef->getNode(), Reg, TII);
576 const TargetRegisterClass *RC =
577 TRI->getMinimalPhysRegClass(Reg, VT);
578 const TargetRegisterClass *DestRC = TRI->getCrossCopyRegClass(RC);
579
580 // If cross copy register class is the same as RC, then it must be
581 // possible copy the value directly. Do not try duplicate the def.
582 // If cross copy register class is not the same as RC, then it's
583 // possible to copy the value but it require cross register class copies
584 // and it is expensive.
585 // If cross copy register class is null, then it's not possible to copy
586 // the value at all.
587 SUnit *NewDef = nullptr;
588 if (DestRC != RC) {
589 NewDef = CopyAndMoveSuccessors(LRDef);
590 if (!DestRC && !NewDef)
591 report_fatal_error("Can't handle live physical "
592 "register dependency!");
593 }
594 if (!NewDef) {
595 // Issue copies, these can be expensive cross register class copies.
597 InsertCopiesAndMoveSuccs(LRDef, Reg, DestRC, RC, Copies);
598 LLVM_DEBUG(dbgs() << "Adding an edge from SU # " << TrySU->NodeNum
599 << " to SU #" << Copies.front()->NodeNum << "\n");
600 AddPred(TrySU, SDep(Copies.front(), SDep::Artificial));
601 NewDef = Copies.back();
602 }
603
604 LLVM_DEBUG(dbgs() << "Adding an edge from SU # " << NewDef->NodeNum
605 << " to SU #" << TrySU->NodeNum << "\n");
606 LiveRegDefs[Reg] = NewDef;
607 AddPred(NewDef, SDep(TrySU, SDep::Artificial));
608 TrySU->isAvailable = false;
609 CurSU = NewDef;
610 }
611
612 if (!CurSU) {
613 llvm_unreachable("Unable to resolve live physical register dependencies!");
614 }
615 }
616
617 // Add the nodes that aren't ready back onto the available list.
618 for (SUnit *SU : NotReady) {
619 SU->isPending = false;
620 // May no longer be available due to backtracking.
621 if (SU->isAvailable)
622 AvailableQueue.push(SU);
623 }
624 NotReady.clear();
625
626 if (CurSU)
627 ScheduleNodeBottomUp(CurSU, CurCycle);
628 ++CurCycle;
629 }
630
631 // Reverse the order since it is bottom up.
632 std::reverse(Sequence.begin(), Sequence.end());
633
634#ifndef NDEBUG
635 VerifyScheduledSequence(/*isBottomUp=*/true);
636#endif
637}
638
639
640namespace {
641//===----------------------------------------------------------------------===//
642// ScheduleDAGLinearize - No scheduling scheduler, it simply linearize the
643// DAG in topological order.
644// IMPORTANT: this may not work for targets with phyreg dependency.
645//
646class ScheduleDAGLinearize : public ScheduleDAGSDNodes {
647public:
648 ScheduleDAGLinearize(MachineFunction &mf) : ScheduleDAGSDNodes(mf) {}
649
650 void Schedule() override;
651
653 EmitSchedule(MachineBasicBlock::iterator &InsertPos) override;
654
655private:
656 std::vector<SDNode*> Sequence;
657 DenseMap<SDNode*, SDNode*> GluedMap; // Cache glue to its user
658
659 void ScheduleNode(SDNode *N);
660};
661} // end anonymous namespace
662
663void ScheduleDAGLinearize::ScheduleNode(SDNode *N) {
664 if (N->getNodeId() != 0)
665 llvm_unreachable(nullptr);
666
667 if (!N->isMachineOpcode() &&
668 (N->getOpcode() == ISD::EntryToken || isPassiveNode(N)))
669 // These nodes do not need to be translated into MIs.
670 return;
671
672 LLVM_DEBUG(dbgs() << "\n*** Scheduling: ");
673 LLVM_DEBUG(N->dump(DAG));
674 Sequence.push_back(N);
675
676 unsigned NumOps = N->getNumOperands();
677 if (unsigned NumLeft = NumOps) {
678 SDNode *GluedOpN = nullptr;
679 do {
680 const SDValue &Op = N->getOperand(NumLeft-1);
681 SDNode *OpN = Op.getNode();
682
683 if (NumLeft == NumOps && Op.getValueType() == MVT::Glue) {
684 // Schedule glue operand right above N.
685 GluedOpN = OpN;
686 assert(OpN->getNodeId() != 0 && "Glue operand not ready?");
687 OpN->setNodeId(0);
688 ScheduleNode(OpN);
689 continue;
690 }
691
692 if (OpN == GluedOpN)
693 // Glue operand is already scheduled.
694 continue;
695
697 if (DI != GluedMap.end() && DI->second != N)
698 // Users of glues are counted against the glued users.
699 OpN = DI->second;
700
701 unsigned Degree = OpN->getNodeId();
702 assert(Degree > 0 && "Predecessor over-released!");
703 OpN->setNodeId(--Degree);
704 if (Degree == 0)
705 ScheduleNode(OpN);
706 } while (--NumLeft);
707 }
708}
709
710/// findGluedUser - Find the representative use of a glue value by walking
711/// the use chain.
713 while (SDNode *Glued = N->getGluedUser())
714 N = Glued;
715 return N;
716}
717
718void ScheduleDAGLinearize::Schedule() {
719 LLVM_DEBUG(dbgs() << "********** DAG Linearization **********\n");
720
722 unsigned DAGSize = 0;
723 for (SDNode &Node : DAG->allnodes()) {
724 SDNode *N = &Node;
725
726 // Use node id to record degree.
727 unsigned Degree = N->use_size();
728 N->setNodeId(Degree);
729 unsigned NumVals = N->getNumValues();
730 if (NumVals && N->getValueType(NumVals-1) == MVT::Glue &&
731 N->hasAnyUseOfValue(NumVals-1)) {
733 if (User) {
734 Glues.push_back(N);
735 GluedMap.insert(std::make_pair(N, User));
736 }
737 }
738
739 if (N->isMachineOpcode() ||
740 (N->getOpcode() != ISD::EntryToken && !isPassiveNode(N)))
741 ++DAGSize;
742 }
743
744 for (SDNode *Glue : Glues) {
745 SDNode *GUser = GluedMap[Glue];
746 unsigned Degree = Glue->getNodeId();
747 unsigned UDegree = GUser->getNodeId();
748
749 // Glue user must be scheduled together with the glue operand. So other
750 // users of the glue operand must be treated as its users.
751 SDNode *ImmGUser = Glue->getGluedUser();
752 for (const SDNode *U : Glue->users())
753 if (U == ImmGUser)
754 --Degree;
755 GUser->setNodeId(UDegree + Degree);
756 Glue->setNodeId(1);
757 }
758
759 Sequence.reserve(DAGSize);
760 ScheduleNode(DAG->getRoot().getNode());
761}
762
764ScheduleDAGLinearize::EmitSchedule(MachineBasicBlock::iterator &InsertPos) {
765 InstrEmitter Emitter(DAG->getTarget(), BB, InsertPos);
767
768 LLVM_DEBUG({ dbgs() << "\n*** Final schedule ***\n"; });
769
770 unsigned NumNodes = Sequence.size();
771 MachineBasicBlock *BB = Emitter.getBlock();
772 for (unsigned i = 0; i != NumNodes; ++i) {
773 SDNode *N = Sequence[NumNodes-i-1];
774 LLVM_DEBUG(N->dump(DAG));
775 Emitter.EmitNode(N, false, false, VRBaseMap);
776
777 // Emit any debug values associated with the node.
778 if (N->getHasDebugValue()) {
779 MachineBasicBlock::iterator InsertPos = Emitter.getInsertPos();
780 for (auto *DV : DAG->GetDbgValues(N)) {
781 if (!DV->isEmitted())
782 if (auto *DbgMI = Emitter.EmitDbgValue(DV, VRBaseMap))
783 BB->insert(InsertPos, DbgMI);
784 }
785 }
786 }
787
788 LLVM_DEBUG(dbgs() << '\n');
789
790 InsertPos = Emitter.getInsertPos();
791 return Emitter.getBlock();
792}
793
794//===----------------------------------------------------------------------===//
795// Public Constructor Functions
796//===----------------------------------------------------------------------===//
797
800 return new ScheduleDAGFast(*IS->MF);
801}
802
805 return new ScheduleDAGLinearize(*IS->MF);
806}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static void push(SmallVectorImpl< uint64_t > &R, StringRef Str)
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
dxil DXContainer Global Emitter
const HexagonInstrInfo * TII
#define F(x, y, z)
Definition: MD5.cpp:55
Register const TargetRegisterInfo * TRI
SI Lower i1 Copies
static MVT getPhysicalRegisterVT(SDNode *N, unsigned Reg, const TargetInstrInfo *TII)
getPhysicalRegisterVT - Returns the ValueType of the physical register definition of the specified no...
static RegisterScheduler fastDAGScheduler("fast", "Fast suboptimal list scheduling", createFastDAGScheduler)
static bool CheckForLiveRegDef(SUnit *SU, MCRegister Reg, std::vector< SUnit * > &LiveRegDefs, SmallSet< unsigned, 4 > &RegAdded, SmallVectorImpl< unsigned > &LRegs, const TargetRegisterInfo *TRI, const SDNode *Node=nullptr)
CheckForLiveRegDef - Return true and update live register vector if the specified register def of the...
static RegisterScheduler linearizeDAGScheduler("linearize", "Linearize DAG, no scheduling", createDAGLinearizer)
static SDNode * findGluedUser(SDNode *N)
findGluedUser - Find the representative use of a glue value by walking the use chain.
This file defines the SmallSet class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
#define LLVM_DEBUG(...)
Definition: Debug.h:119
This class represents an Operation in the Expression.
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:177
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:230
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:199
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:238
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
Definition: MCInstrDesc.h:249
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
Definition: MCInstrDesc.h:220
ArrayRef< MCPhysReg > implicit_defs() const
Return a list of registers that are potentially written by any instance of this machine instruction.
Definition: MCInstrDesc.h:581
bool isCommutable() const
Return true if this may be a 2- or 3-address instruction (of the form "X = op Y, Z,...
Definition: MCInstrDesc.h:483
MCRegAliasIterator enumerates all registers aliasing Reg.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
Machine Value Type.
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Represents one node in the SelectionDAG.
int getNodeId() const
Return the unique node id.
SDNode * getGluedUser() const
If this node has a glue value with a user, return the user (there is at most one).
void setNodeId(int Id)
Set unique node id.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
LLVM_ABI bool isOperandOf(const SDNode *N) const
Return true if this node is an operand of N.
iterator_range< user_iterator > users()
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.
Scheduling dependency.
Definition: ScheduleDAG.h:51
SUnit * getSUnit() const
Definition: ScheduleDAG.h:507
@ Data
Regular data dependence (aka true-dependence).
Definition: ScheduleDAG.h:55
@ Barrier
An unknown scheduling barrier.
Definition: ScheduleDAG.h:71
@ Artificial
Arbitrary strong DAG edge (no real dependence).
Definition: ScheduleDAG.h:74
bool isAssignedRegDep() const
Tests if this is a Data dependence that is associated with a register.
Definition: ScheduleDAG.h:211
bool isArtificial() const
Tests if this is an Order dependence that is marked as "artificial", meaning it isn't necessary for c...
Definition: ScheduleDAG.h:200
bool isCtrl() const
Shorthand for getKind() != SDep::Data.
Definition: ScheduleDAG.h:161
Register getReg() const
Returns the register associated with this edge.
Definition: ScheduleDAG.h:216
Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:249
LLVM_ABI void setHeightToAtLeast(unsigned NewHeight)
If NewHeight is greater than this node's height value, set it to be the new height value.
unsigned NodeNum
Entry # of node in the node vector.
Definition: ScheduleDAG.h:277
unsigned NumSuccsLeft
Definition: ScheduleDAG.h:282
const TargetRegisterClass * CopyDstRC
Is a special copy node if != nullptr.
Definition: ScheduleDAG.h:265
unsigned getHeight() const
Returns the height of this node, which is the length of the maximum path down to any node which has n...
Definition: ScheduleDAG.h:433
LLVM_ABI void removePred(const SDep &D)
Removes the specified edge as a pred of the current node if it exists.
unsigned short Latency
Node latency.
Definition: ScheduleDAG.h:312
bool isPending
True once pending.
Definition: ScheduleDAG.h:303
bool isScheduled
True once scheduled.
Definition: ScheduleDAG.h:305
bool isAvailable
True once available.
Definition: ScheduleDAG.h:304
SmallVector< SDep, 4 > Succs
All sunit successors.
Definition: ScheduleDAG.h:270
const TargetRegisterClass * CopySrcRC
Definition: ScheduleDAG.h:267
SDNode * getNode() const
Returns the representative SDNode for this SUnit.
Definition: ScheduleDAG.h:379
bool isTwoAddress
Is a two-address instruction.
Definition: ScheduleDAG.h:298
bool isCommutable
Is a commutable instruction.
Definition: ScheduleDAG.h:299
SmallVector< SDep, 4 > Preds
All sunit predecessors.
Definition: ScheduleDAG.h:269
LLVM_ABI bool addPred(const SDep &D, bool Required=true)
Adds the specified edge as a pred of the current node if not already.
ScheduleDAGSDNodes - A ScheduleDAG for scheduling SDNode-based DAGs.
virtual void Schedule()=0
Schedule - Order nodes according to selected style, filling in the Sequence member.
virtual MachineBasicBlock * EmitSchedule(MachineBasicBlock::iterator &InsertPos)
EmitSchedule - Insert MachineInstrs into the MachineBasicBlock according to the order specified in Se...
virtual bool forceUnitLatencies() const
ForceUnitLatencies - Return true if all scheduling edges should be given a latency value of one.
std::vector< SUnit * > Sequence
The schedule. Null SUnit*'s represent noop instructions.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
MachineFunction * MF
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:182
bool empty() const
Definition: SmallVector.h:82
size_t size() const
Definition: SmallVector.h:79
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
Definition: ISDOpcodes.h:225
@ EntryToken
EntryToken - This is the marker used to indicate the start of a region.
Definition: ISDOpcodes.h:48
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
Definition: ISDOpcodes.h:219
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
Definition: ISDOpcodes.h:1207
@ INLINEASM
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:1204
Reg
All possible values of the reg field in the ModR/M byte.
Sequence
A sequence of states that a pointer may go through in which an objc_retain and objc_release are actua...
Definition: PtrState.h:41
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
LLVM_ABI ScheduleDAGSDNodes * createFastDAGScheduler(SelectionDAGISel *IS, CodeGenOptLevel OptLevel)
createFastDAGScheduler - This creates a "fast" scheduler.
LLVM_ABI ScheduleDAGSDNodes * createDAGLinearizer(SelectionDAGISel *IS, CodeGenOptLevel OptLevel)
createDAGLinearizer - This creates a "no-scheduling" scheduler which linearize the DAG using topologi...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition: Error.cpp:167
CodeGenOptLevel
Code generation optimization level.
Definition: CodeGen.h:82
#define N