LLVM 24.0.0git
ScheduleDAG.h
Go to the documentation of this file.
1//===- llvm/CodeGen/ScheduleDAG.h - Common Base Class -----------*- C++ -*-===//
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/// \file Implements the ScheduleDAG class, which is used as the common base
10/// class for instruction schedulers. This encapsulates the scheduling DAG,
11/// which is shared between SelectionDAG and MachineInstr scheduling.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CODEGEN_SCHEDULEDAG_H
16#define LLVM_CODEGEN_SCHEDULEDAG_H
17
18#include "llvm/ADT/BitVector.h"
20#include "llvm/ADT/SmallSet.h"
22#include "llvm/ADT/iterator.h"
27#include <cassert>
28#include <cstddef>
29#include <iterator>
30#include <string>
31#include <vector>
32
33namespace llvm {
34
35template <class GraphType> struct GraphTraits;
36template<class Graph> class GraphWriter;
37class TargetMachine;
38class MachineFunction;
40class MCInstrDesc;
41struct MCSchedClassDesc;
42class raw_ostream;
43class SDNode;
44class SUnit;
45class ScheduleDAG;
46class TargetInstrInfo;
47class MCRegisterClass;
50
51 /// Scheduling dependency. This represents one direction of an edge in the
52 /// scheduling DAG.
53 class SDep {
54 public:
55 /// These are the different kinds of scheduling dependencies.
56 enum Kind {
57 Data, ///< Regular data dependence (aka true-dependence).
58 Anti, ///< A register anti-dependence (aka WAR).
59 Output, ///< A register output-dependence (aka WAW).
60 Order ///< Any other ordering dependency.
61 };
62
63 // Strong dependencies must be respected by the scheduler. Artificial
64 // dependencies may be removed only if they are redundant with another
65 // strong dependence.
66 //
67 // Weak dependencies may be violated by the scheduling strategy, but only if
68 // the strategy can prove it is correct to do so.
69 //
70 // Strong OrderKinds must occur before "Weak".
71 // Weak OrderKinds must occur after "Weak".
72 enum OrderKind {
73 Barrier, ///< An unknown scheduling barrier.
74 MayAliasMem, ///< Nonvolatile load/Store instructions that may alias.
75 MustAliasMem, ///< Nonvolatile load/Store instructions that must alias.
76 Artificial, ///< Arbitrary strong DAG edge (no real dependence).
77 Weak, ///< Arbitrary weak DAG edge.
78 Cluster ///< Weak DAG edge linking a chain of clustered instrs.
79 };
80
81 private:
82 /// A pointer to the depending/depended-on SUnit, and an enum
83 /// indicating the kind of the dependency.
85
86 /// A union discriminated by the dependence kind.
87 union {
88 /// For Data, Anti, and Output dependencies, the associated register. For
89 /// Data dependencies that don't currently have a register/ assigned, this
90 /// is set to zero.
91 unsigned Reg;
92
93 /// Additional information about Order dependencies.
94 unsigned OrdKind; // enum OrderKind
95 } Contents;
96
97 /// The time associated with this edge. Often this is just the value of the
98 /// Latency field of the predecessor, however advanced models may provide
99 /// additional information about specific edges.
100 unsigned Latency = 0u;
101
102 public:
103 /// Constructs a null SDep. This is only for use by container classes which
104 /// require default constructors. SUnits may not/ have null SDep edges.
105 SDep() : Dep(nullptr, Data) {}
106
107 /// Constructs an SDep with the specified values.
108 SDep(SUnit *S, Kind kind, Register Reg) : Dep(S, kind), Contents() {
109 switch (kind) {
110 default:
111 llvm_unreachable("Reg given for non-register dependence!");
112 case Anti:
113 case Output:
114 assert(Reg && "SDep::Anti and SDep::Output must use a non-zero Reg!");
115 Contents.Reg = Reg.id();
116 Latency = 0;
117 break;
118 case Data:
119 Contents.Reg = Reg.id();
120 Latency = 1;
121 break;
122 }
123 }
124
126 : Dep(S, Order), Contents(), Latency(0) {
127 Contents.OrdKind = kind;
128 }
129
130 /// Returns true if the specified SDep is equivalent except for latency.
131 bool overlaps(const SDep &Other) const;
132
133 bool operator==(const SDep &Other) const {
134 return overlaps(Other) && Latency == Other.Latency;
135 }
136
137 bool operator!=(const SDep &Other) const {
138 return !operator==(Other);
139 }
140
141 /// Returns the latency value for this edge, which roughly means the
142 /// minimum number of cycles that must elapse between the predecessor and
143 /// the successor, given that they have this edge between them.
144 unsigned getLatency() const {
145 return Latency;
146 }
147
148 /// Sets the latency for this edge.
149 void setLatency(unsigned Lat) {
150 Latency = Lat;
151 }
152
153 //// Returns the SUnit to which this edge points.
154 SUnit *getSUnit() const;
155
156 //// Assigns the SUnit to which this edge points.
157 void setSUnit(SUnit *SU);
158
159 /// Returns an enum value representing the kind of the dependence.
160 Kind getKind() const;
161
162 /// Shorthand for getKind() != SDep::Data.
163 bool isCtrl() const {
164 return getKind() != Data;
165 }
166
167 /// Tests if this is an Order dependence between two memory accesses
168 /// where both sides of the dependence access memory in non-volatile and
169 /// fully modeled ways.
170 bool isNormalMemory() const {
171 return getKind() == Order && (Contents.OrdKind == MayAliasMem
172 || Contents.OrdKind == MustAliasMem);
173 }
174
175 /// Tests if this is an Order dependence that is marked as a barrier.
176 bool isBarrier() const {
177 return getKind() == Order && Contents.OrdKind == Barrier;
178 }
179
180 /// Tests if this is could be any kind of memory dependence.
182 return (isNormalMemory() || isBarrier());
183 }
184
185 /// Tests if this is an Order dependence that is marked as
186 /// "must alias", meaning that the SUnits at either end of the edge have a
187 /// memory dependence on a known memory location.
188 bool isMustAlias() const {
189 return getKind() == Order && Contents.OrdKind == MustAliasMem;
190 }
191
192 /// Tests if this a weak dependence. Weak dependencies are considered DAG
193 /// edges for height computation and other heuristics, but do not force
194 /// ordering. Breaking a weak edge may require the scheduler to compensate,
195 /// for example by inserting a copy.
196 bool isWeak() const {
197 return getKind() == Order && Contents.OrdKind >= Weak;
198 }
199
200 /// Tests if this is an Order dependence that is marked as
201 /// "artificial", meaning it isn't necessary for correctness.
202 bool isArtificial() const {
203 return getKind() == Order && Contents.OrdKind == Artificial;
204 }
205
206 /// Tests if this is an Order dependence that is marked as "cluster",
207 /// meaning it is artificial and wants to be adjacent.
208 bool isCluster() const {
209 return getKind() == Order && Contents.OrdKind == Cluster;
210 }
211
212 /// Tests if this is a Data dependence that is associated with a register.
213 bool isAssignedRegDep() const { return getKind() == Data && Contents.Reg; }
214
215 /// Returns the register associated with this edge. This is only valid on
216 /// Data, Anti, and Output edges. On Data edges, this value may be zero,
217 /// meaning there is no associated register.
218 Register getReg() const {
219 assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
220 "getReg called on non-register dependence edge!");
221 return Contents.Reg;
222 }
223
224 /// Assigns the associated register for this edge. This is only valid on
225 /// Data, Anti, and Output edges. On Anti and Output edges, this value must
226 /// not be zero. On Data edges, the value may be zero, which would mean that
227 /// no specific register is associated with this edge.
229 assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
230 "setReg called on non-register dependence edge!");
231 assert((getKind() != Anti || Reg) &&
232 "SDep::Anti edge cannot use the zero register!");
233 assert((getKind() != Output || Reg) &&
234 "SDep::Output edge cannot use the zero register!");
235 Contents.Reg = Reg.id();
236 }
237
238 LLVM_ABI void dump(const TargetRegisterInfo *TRI = nullptr) const;
239 };
240
241 /// Keep record of which SUnit are in the same cluster group.
243 constexpr unsigned InvalidClusterId = ~0u;
244
245 /// Return whether the input cluster ID's are the same and valid.
246 inline bool isTheSameCluster(unsigned A, unsigned B) {
247 return A != InvalidClusterId && A == B;
248 }
249
250 /// Scheduling unit. This is a node in the scheduling DAG.
251 class SUnit {
252 private:
253 enum : unsigned { BoundaryID = ~0u };
254
255 union {
256 SDNode *Node; ///< Representative node.
257 MachineInstr *Instr; ///< Alternatively, a MachineInstr.
258 };
259
260 public:
261 SUnit *OrigNode = nullptr; ///< If not this, the node from which this node
262 /// was cloned. (SD scheduling only)
263
265 nullptr; ///< nullptr or resolved SchedClass.
266
268 nullptr; ///< Is a special copy node if != nullptr.
270
271 SmallVector<SDep, 4> Preds; ///< All sunit predecessors.
272 SmallVector<SDep, 4> Succs; ///< All sunit successors.
273
278
279 unsigned NodeNum = BoundaryID; ///< Entry # of node in the node vector.
280 unsigned NodeQueueId = 0; ///< Queue id of node.
281 unsigned NumPreds = 0; ///< # of SDep::Data preds.
282 unsigned NumSuccs = 0; ///< # of SDep::Data sucss.
283 unsigned NumPredsLeft = 0; ///< # of preds not scheduled.
284 unsigned NumSuccsLeft = 0; ///< # of succs not scheduled.
285 unsigned WeakPredsLeft = 0; ///< # of weak preds not scheduled.
286 unsigned WeakSuccsLeft = 0; ///< # of weak succs not scheduled.
287 unsigned TopReadyCycle = 0; ///< Cycle relative to start when node is ready.
288 unsigned BotReadyCycle = 0; ///< Cycle relative to end when node is ready.
289
290 unsigned ParentClusterIdx = InvalidClusterId; ///< The parent cluster id.
291
292 private:
293 unsigned Depth = 0; ///< Node depth.
294 unsigned Height = 0; ///< Node height.
295
296 public:
297 bool isVRegCycle : 1; ///< May use and def the same vreg.
298 bool isCall : 1; ///< Is a function call.
299 bool isCallOp : 1; ///< Is a function call operand.
300 bool isTwoAddress : 1; ///< Is a two-address instruction.
301 bool isCommutable : 1; ///< Is a commutable instruction.
302 bool hasPhysRegUses : 1; ///< Has physreg uses.
303 bool hasPhysRegDefs : 1; ///< Has physreg defs that are being used.
304 bool hasPhysRegClobbers : 1; ///< Has any physreg defs, used or not.
305 bool isPending : 1; ///< True once pending.
306 bool isAvailable : 1; ///< True once available.
307 bool isScheduled : 1; ///< True once scheduled.
308 bool isScheduleHigh : 1; ///< True if preferable to schedule high.
309 bool isScheduleLow : 1; ///< True if preferable to schedule low.
310 bool isCloned : 1; ///< True if this node has been cloned.
311 bool isUnbuffered : 1; ///< Uses an unbuffered resource.
312 bool hasReservedResource : 1; ///< Uses a reserved resource.
313 unsigned short NumRegDefsLeft = 0; ///< # of reg defs with no scheduled use.
314 unsigned short Latency = 0; ///< Node latency.
315
316 private:
317 bool isDepthCurrent : 1; ///< True if Depth is current.
318 bool isHeightCurrent : 1; ///< True if Height is current.
319 bool isNode : 1; ///< True if the representative is an SDNode
320 bool isInst : 1; ///< True if the representative is a MachineInstr
321
322 public:
323 Sched::Preference SchedulingPref : 4; ///< Scheduling preference.
324 static_assert(Sched::Preference::Last <= (1 << 4),
325 "not enough bits in bitfield");
326
327 /// Constructs an SUnit for pre-regalloc scheduling to represent an
328 /// SDNode and any nodes flagged to it.
338
339 /// Constructs an SUnit for post-regalloc scheduling to represent a
340 /// MachineInstr.
350
351 /// Constructs a placeholder SUnit.
361
362 /// Boundary nodes are placeholders for the boundary of the
363 /// scheduling region.
364 ///
365 /// BoundaryNodes can have DAG edges, including Data edges, but they do not
366 /// correspond to schedulable entities (e.g. instructions) and do not have a
367 /// valid ID. Consequently, always check for boundary nodes before accessing
368 /// an associative data structure keyed on node ID.
369 bool isBoundaryNode() const { return NodeNum == BoundaryID; }
370
371 /// Assigns the representative SDNode for this SUnit. This may be used
372 /// during pre-regalloc scheduling.
373 void setNode(SDNode *N) {
374 assert(!isInst && "Setting SDNode of SUnit with MachineInstr!");
375 Node = N;
376 isNode = true;
377 }
378
379 /// Returns the representative SDNode for this SUnit. This may be used
380 /// during pre-regalloc scheduling.
381 SDNode *getNode() const {
382 assert(!isInst && (isNode || !Instr) &&
383 "Reading SDNode of SUnit without SDNode!");
384 return Node;
385 }
386
387 /// Returns true if this SUnit refers to a machine instruction as
388 /// opposed to an SDNode.
389 bool isInstr() const { return isInst && Instr; }
390
391 /// Assigns the instruction for the SUnit. This may be used during
392 /// post-regalloc scheduling.
394 assert(!isNode && "Setting MachineInstr of SUnit with SDNode!");
395 Instr = MI;
396 isInst = true;
397 }
398
399 /// Returns the representative MachineInstr for this SUnit. This may be used
400 /// during post-regalloc scheduling.
402 assert(!isNode && (isInst || !Node) &&
403 "Reading MachineInstr of SUnit without MachineInstr!");
404 return Instr;
405 }
406
407 /// Adds the specified edge as a pred of the current node if not already.
408 /// It also adds the current node as a successor of the specified node.
409 LLVM_ABI bool addPred(const SDep &D, bool Required = true);
410
411 /// Adds a barrier edge to SU by calling addPred(), with latency 0
412 /// generally or latency 1 for a store followed by a load.
414 SDep Dep(SU, SDep::Barrier);
415 unsigned TrueMemOrderLatency =
416 ((SU->getInstr()->mayStore() && this->getInstr()->mayLoad()) ? 1 : 0);
417 Dep.setLatency(TrueMemOrderLatency);
418 return addPred(Dep);
419 }
420
421 /// Removes the specified edge as a pred of the current node if it exists.
422 /// It also removes the current node as a successor of the specified node.
423 LLVM_ABI void removePred(const SDep &D);
424
425 /// Returns the depth of this node, which is the length of the maximum path
426 /// up to any node which has no predecessors.
427 unsigned getDepth() const {
428 if (!isDepthCurrent)
429 const_cast<SUnit *>(this)->ComputeDepth();
430 return Depth;
431 }
432
433 /// Returns the height of this node, which is the length of the
434 /// maximum path down to any node which has no successors.
435 unsigned getHeight() const {
436 if (!isHeightCurrent)
437 const_cast<SUnit *>(this)->ComputeHeight();
438 return Height;
439 }
440
441 /// If NewDepth is greater than this node's depth value, sets it to
442 /// be the new depth value. This also recursively marks successor nodes
443 /// dirty.
444 LLVM_ABI void setDepthToAtLeast(unsigned NewDepth);
445
446 /// If NewHeight is greater than this node's height value, set it to be
447 /// the new height value. This also recursively marks predecessor nodes
448 /// dirty.
449 LLVM_ABI void setHeightToAtLeast(unsigned NewHeight);
450
451 /// Sets a flag in this node to indicate that its stored Depth value
452 /// will require recomputation the next time getDepth() is called.
453 LLVM_ABI void setDepthDirty();
454
455 /// Sets a flag in this node to indicate that its stored Height value
456 /// will require recomputation the next time getHeight() is called.
458
459 /// Tests if node N is a predecessor of this node.
460 bool isPred(const SUnit *N) const {
461 for (const SDep &Pred : Preds)
462 if (Pred.getSUnit() == N)
463 return true;
464 return false;
465 }
466
467 /// Tests if node N is a successor of this node.
468 bool isSucc(const SUnit *N) const {
469 for (const SDep &Succ : Succs)
470 if (Succ.getSUnit() == N)
471 return true;
472 return false;
473 }
474
475 bool isTopReady() const {
476 return NumPredsLeft == 0;
477 }
478 bool isBottomReady() const {
479 return NumSuccsLeft == 0;
480 }
481
482 /// Orders this node's predecessor edges such that the critical path
483 /// edge occurs first.
485
487
488 LLVM_ABI void dumpAttributes() const;
489
490 private:
491 LLVM_ABI void ComputeDepth();
492 LLVM_ABI void ComputeHeight();
493 };
494
495 LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, const SUnit &SU);
496
497 /// Returns true if the specified SDep is equivalent except for latency.
498 inline bool SDep::overlaps(const SDep &Other) const {
499 if (Dep != Other.Dep)
500 return false;
501 switch (Dep.getInt()) {
502 case Data:
503 case Anti:
504 case Output:
505 return Contents.Reg == Other.Contents.Reg;
506 case Order:
507 return Contents.OrdKind == Other.Contents.OrdKind;
508 }
509 llvm_unreachable("Invalid dependency kind!");
510 }
511
512 //// Returns the SUnit to which this edge points.
513 inline SUnit *SDep::getSUnit() const { return Dep.getPointer(); }
514
515 //// Assigns the SUnit to which this edge points.
516 inline void SDep::setSUnit(SUnit *SU) { Dep.setPointer(SU); }
517
518 /// Returns an enum value representing the kind of the dependence.
519 inline SDep::Kind SDep::getKind() const { return Dep.getInt(); }
520
521 //===--------------------------------------------------------------------===//
522
523 /// This interface is used to plug different priorities computation
524 /// algorithms into the list scheduler. It implements the interface of a
525 /// standard priority queue, where nodes are inserted in arbitrary order and
526 /// returned in priority order. The computation of the priority and the
527 /// representation of the queue are totally up to the implementation to
528 /// decide.
530 virtual void anchor();
531
532 unsigned CurCycle = 0;
533 bool HasReadyFilter;
534
535 public:
536 SchedulingPriorityQueue(bool rf = false) : HasReadyFilter(rf) {}
537
538 virtual ~SchedulingPriorityQueue() = default;
539
540 virtual bool isBottomUp() const = 0;
541
542 virtual void initNodes(std::vector<SUnit> &SUnits) = 0;
543 virtual void addNode(const SUnit *SU) = 0;
544 virtual void updateNode(const SUnit *SU) = 0;
545 virtual void releaseState() = 0;
546
547 virtual bool empty() const = 0;
548
549 bool hasReadyFilter() const { return HasReadyFilter; }
550
551 virtual bool tracksRegPressure() const { return false; }
552
553 virtual bool isReady(SUnit *) const {
554 assert(!HasReadyFilter && "The ready filter must override isReady()");
555 return true;
556 }
557
558 virtual void push(SUnit *U) = 0;
559
560 void push_all(const std::vector<SUnit *> &Nodes) {
561 for (SUnit *SU : Nodes)
562 push(SU);
563 }
564
565 virtual SUnit *pop() = 0;
566
567 virtual void remove(SUnit *SU) = 0;
568
569 virtual void dump(ScheduleDAG *) const {}
570
571 /// As each node is scheduled, this method is invoked. This allows the
572 /// priority function to adjust the priority of related unscheduled nodes,
573 /// for example.
574 virtual void scheduledNode(SUnit *) {}
575
576 virtual void unscheduledNode(SUnit *) {}
577
578 void setCurCycle(unsigned Cycle) {
579 CurCycle = Cycle;
580 }
581
582 unsigned getCurCycle() const {
583 return CurCycle;
584 }
585 };
586
588 public:
589 const TargetMachine &TM; ///< Target processor
590 const TargetInstrInfo *TII; ///< Target instruction information
591 const TargetRegisterInfo *TRI; ///< Target processor register info
592 MachineFunction &MF; ///< Machine function
593 MachineRegisterInfo &MRI; ///< Virtual/real register map
594 std::vector<SUnit> SUnits; ///< The scheduling units.
595 SUnit EntrySU; ///< Special node for the region entry.
596 SUnit ExitSU; ///< Special node for the region exit.
597
598#ifdef NDEBUG
599 static const bool StressSched = false;
600#else
602#endif
603
604 // This class is designed to be passed by reference only. Copy constructor
605 // is declared as deleted here to make the derived classes have deleted
606 // implicit-declared copy constructor, which suppresses the warnings from
607 // static analyzer when the derived classes own resources that are freed in
608 // their destructors, but don't have user-written copy constructors (rule
609 // of three).
610 ScheduleDAG(const ScheduleDAG &) = delete;
612
613 explicit ScheduleDAG(MachineFunction &mf);
614
615 virtual ~ScheduleDAG();
616
617 /// Clears the DAG state (between regions).
618 void clearDAG();
619
620 /// Returns the MCInstrDesc of this SUnit.
621 /// Returns NULL for SDNodes without a machine opcode.
622 const MCInstrDesc *getInstrDesc(const SUnit *SU) const {
623 if (SU->isInstr()) return &SU->getInstr()->getDesc();
624 return getNodeDesc(SU->getNode());
625 }
626
627 /// Pops up a GraphViz/gv window with the ScheduleDAG rendered using 'dot'.
628 virtual void viewGraph(const Twine &Name, const Twine &Title);
629 virtual void viewGraph();
630
631 virtual void dumpNode(const SUnit &SU) const = 0;
632 virtual void dump() const = 0;
633 void dumpNodeName(const SUnit &SU) const;
634
635 /// Returns a label for an SUnit node in a visualization of the ScheduleDAG.
636 virtual std::string getGraphNodeLabel(const SUnit *SU) const = 0;
637
638 /// Returns a label for the region of code covered by the DAG.
639 virtual std::string getDAGName() const = 0;
640
641 /// Adds custom features for a visualization of the ScheduleDAG.
643
644#ifndef NDEBUG
645 /// Verifies that all SUnits were scheduled and that their state is
646 /// consistent. Returns the number of scheduled SUnits.
647 unsigned VerifyScheduledDAG(bool isBottomUp);
648#endif
649
650 protected:
651 void dumpNodeAll(const SUnit &SU) const;
652
653 private:
654 /// Returns the MCInstrDesc of this SDNode or NULL.
655 const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
656 };
657
658 class SUnitIterator {
659 SUnit *Node;
660 unsigned Operand;
661
662 SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
663
664 public:
665 using iterator_category = std::forward_iterator_tag;
667 using difference_type = std::ptrdiff_t;
670
671 bool operator==(const SUnitIterator& x) const {
672 return Operand == x.Operand;
673 }
674 bool operator!=(const SUnitIterator& x) const { return !operator==(x); }
675
677 return Node->Preds[Operand].getSUnit();
678 }
679 pointer operator->() const { return operator*(); }
680
681 SUnitIterator& operator++() { // Preincrement
682 ++Operand;
683 return *this;
684 }
685 SUnitIterator operator++(int) { // Postincrement
686 SUnitIterator tmp = *this; ++*this; return tmp;
687 }
688
689 static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); }
690 static SUnitIterator end (SUnit *N) {
691 return SUnitIterator(N, (unsigned)N->Preds.size());
692 }
693
694 unsigned getOperand() const { return Operand; }
695 const SUnit *getNode() const { return Node; }
696
697 /// Tests if this is not an SDep::Data dependence.
698 bool isCtrlDep() const {
699 return getSDep().isCtrl();
700 }
701 bool isArtificialDep() const {
702 return getSDep().isArtificial();
703 }
704 const SDep &getSDep() const {
705 return Node->Preds[Operand];
706 }
707 };
708
709 template <> struct GraphTraits<SUnit*> {
710 typedef SUnit *NodeRef;
712 static NodeRef getEntryNode(SUnit *N) { return N; }
719 };
720
721 template <> struct GraphTraits<ScheduleDAG*> : public GraphTraits<SUnit*> {
724 return nodes_iterator(G->SUnits.begin());
725 }
727 return nodes_iterator(G->SUnits.end());
728 }
729 };
730
731 /// This class can compute a topological ordering for SUnits and provides
732 /// methods for dynamically updating the ordering as new edges are added.
733 ///
734 /// This allows a very fast implementation of IsReachable, for example.
736 /// A reference to the ScheduleDAG's SUnits.
737 std::vector<SUnit> &SUnits;
738 SUnit *ExitSU;
739
740 // Have any new nodes been added?
741 bool Dirty = false;
742
743 // Outstanding added edges, that have not been applied to the ordering.
745
746 /// Maps topological index to the node number.
747 std::vector<int> Index2Node;
748 /// Maps the node number to its topological index.
749 std::vector<int> Node2Index;
750 /// a set of nodes visited during a DFS traversal.
751 BitVector Visited;
752 /// Cache of reachability queries. {A, B} -> true if B is reachable from A.
753 /// The keys are SUnit NodeNums.
754 DenseMap<std::pair<int, int>, bool> Reachable;
755
756 /// Makes a DFS traversal and mark all nodes affected by the edge insertion.
757 /// These nodes will later get new topological indexes by means of the Shift
758 /// method.
759 void DFS(const SUnit *SU, int UpperBound, bool& HasLoop);
760
761 /// Reassigns topological indexes for the nodes in the DAG to
762 /// preserve the topological ordering.
763 void Shift(BitVector& Visited, int LowerBound, int UpperBound);
764
765 /// Assigns the topological index to the node n.
766 void Allocate(int n, int index);
767
768 /// Fix the ordering, by either recomputing from scratch or by applying
769 /// any outstanding updates. Uses a heuristic to estimate what will be
770 /// cheaper.
771 void FixOrder();
772
773 public:
774 LLVM_ABI ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits,
775 SUnit *ExitSU);
776
777 /// Add a SUnit without predecessors to the end of the topological order. It
778 /// also must be the first new node added to the DAG.
780
781 /// Creates the initial topological ordering from the DAG to be scheduled.
783
784 /// Returns an array of SUs that are both in the successor
785 /// subtree of StartSU and in the predecessor subtree of TargetSU.
786 /// StartSU and TargetSU are not in the array.
787 /// Success is false if TargetSU is not in the successor subtree of
788 /// StartSU, else it is true.
789 LLVM_ABI std::vector<int> GetSubGraph(const SUnit &StartSU,
790 const SUnit &TargetSU, bool &Success);
791
792 /// Checks if \p SU is reachable from \p TargetSU.
793 LLVM_ABI bool IsReachable(const SUnit *SU, const SUnit *TargetSU);
794
795 /// Returns true if addPred(TargetSU, SU) creates a cycle.
796 LLVM_ABI bool WillCreateCycle(SUnit *TargetSU, SUnit *SU);
797
798 /// Updates the topological ordering to accommodate an edge to be
799 /// added from SUnit \p X to SUnit \p Y.
800 LLVM_ABI void AddPred(SUnit *Y, SUnit *X);
801
802 /// Queues an update to the topological ordering to accommodate an edge to
803 /// be added from SUnit \p X to SUnit \p Y.
805
806 /// Updates the topological ordering to accommodate an edge to be
807 /// removed from the specified node \p N from the predecessors of the
808 /// current node \p M.
809 LLVM_ABI void RemovePred(SUnit *M, SUnit *N);
810
811 /// Mark the ordering as temporarily broken, after a new node has been
812 /// added.
813 void MarkDirty() { Dirty = true; }
814
815 typedef std::vector<int>::iterator iterator;
816 typedef std::vector<int>::const_iterator const_iterator;
817 iterator begin() { return Index2Node.begin(); }
818 const_iterator begin() const { return Index2Node.begin(); }
819 iterator end() { return Index2Node.end(); }
820 const_iterator end() const { return Index2Node.end(); }
821
822 typedef std::vector<int>::reverse_iterator reverse_iterator;
823 typedef std::vector<int>::const_reverse_iterator const_reverse_iterator;
824 reverse_iterator rbegin() { return Index2Node.rbegin(); }
825 const_reverse_iterator rbegin() const { return Index2Node.rbegin(); }
826 reverse_iterator rend() { return Index2Node.rend(); }
827 const_reverse_iterator rend() const { return Index2Node.rend(); }
828 };
829
830} // end namespace llvm
831
832#endif // LLVM_CODEGEN_SCHEDULEDAG_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
This file implements the BitVector class.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
IRTranslator LLVM IR MI
#define G(x, y, z)
Definition MD5.cpp:55
Register const TargetRegisterInfo * TRI
This file defines the PointerIntPair class.
This file defines the SmallSet class.
This file defines the SmallVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file describes how to lower LLVM code to machine code.
Describe properties that are true of each instruction in the target description file.
MCRegisterClass - Base class of TargetRegisterClass.
Representation of each machine instruction.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
PointerIntPair - This class implements a pair of a pointer and small integer.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Represents one node in the SelectionDAG.
Scheduling dependency.
Definition ScheduleDAG.h:53
SUnit * getSUnit() const
bool overlaps(const SDep &Other) const
Returns true if the specified SDep is equivalent except for latency.
Kind getKind() const
Returns an enum value representing the kind of the dependence.
Kind
These are the different kinds of scheduling dependencies.
Definition ScheduleDAG.h:56
@ Output
A register output-dependence (aka WAW).
Definition ScheduleDAG.h:59
@ Order
Any other ordering dependency.
Definition ScheduleDAG.h:60
@ Anti
A register anti-dependence (aka WAR).
Definition ScheduleDAG.h:58
@ Data
Regular data dependence (aka true-dependence).
Definition ScheduleDAG.h:57
void setLatency(unsigned Lat)
Sets the latency for this edge.
bool isWeak() const
Tests if this a weak dependence.
@ Cluster
Weak DAG edge linking a chain of clustered instrs.
Definition ScheduleDAG.h:78
@ Barrier
An unknown scheduling barrier.
Definition ScheduleDAG.h:73
@ Artificial
Arbitrary strong DAG edge (no real dependence).
Definition ScheduleDAG.h:76
@ MayAliasMem
Nonvolatile load/Store instructions that may alias.
Definition ScheduleDAG.h:74
@ Weak
Arbitrary weak DAG edge.
Definition ScheduleDAG.h:77
@ MustAliasMem
Nonvolatile load/Store instructions that must alias.
Definition ScheduleDAG.h:75
unsigned OrdKind
Additional information about Order dependencies.
Definition ScheduleDAG.h:94
unsigned getLatency() const
Returns the latency value for this edge, which roughly means the minimum number of cycles that must e...
bool isAssignedRegDep() const
Tests if this is a Data dependence that is associated with a register.
bool isNormalMemory() const
Tests if this is an Order dependence between two memory accesses where both sides of the dependence a...
bool isArtificial() const
Tests if this is an Order dependence that is marked as "artificial", meaning it isn't necessary for c...
bool operator==(const SDep &Other) const
bool isCtrl() const
Shorthand for getKind() != SDep::Data.
SDep(SUnit *S, OrderKind kind)
SDep()
Constructs a null SDep.
bool operator!=(const SDep &Other) const
void setSUnit(SUnit *SU)
SDep(SUnit *S, Kind kind, Register Reg)
Constructs an SDep with the specified values.
unsigned Reg
For Data, Anti, and Output dependencies, the associated register.
Definition ScheduleDAG.h:91
Register getReg() const
Returns the register associated with this edge.
bool isCluster() const
Tests if this is an Order dependence that is marked as "cluster", meaning it is artificial and wants ...
LLVM_ABI void dump(const TargetRegisterInfo *TRI=nullptr) const
void setReg(Register Reg)
Assigns the associated register for this edge.
bool isBarrier() const
Tests if this is an Order dependence that is marked as a barrier.
bool isNormalMemoryOrBarrier() const
Tests if this is could be any kind of memory dependence.
bool isMustAlias() const
Tests if this is an Order dependence that is marked as "must alias", meaning that the SUnits at eithe...
const SUnit * getNode() const
std::forward_iterator_tag iterator_category
unsigned getOperand() const
static SUnitIterator end(SUnit *N)
pointer operator*() const
value_type * pointer
SUnitIterator operator++(int)
value_type & reference
static SUnitIterator begin(SUnit *N)
SUnitIterator & operator++()
pointer operator->() const
bool operator==(const SUnitIterator &x) const
const SDep & getSDep() const
bool operator!=(const SUnitIterator &x) const
bool isArtificialDep() const
bool isCtrlDep() const
Tests if this is not an SDep::Data dependence.
std::ptrdiff_t difference_type
Scheduling unit. This is a node in the scheduling DAG.
bool isCloned
True if this node has been cloned.
bool isCall
Is a function call.
LLVM_ABI void setHeightToAtLeast(unsigned NewHeight)
If NewHeight is greater than this node's height value, set it to be the new height value.
bool addPredBarrier(SUnit *SU)
Adds a barrier edge to SU by calling addPred(), with latency 0 generally or latency 1 for a store fol...
unsigned NumSuccs
void setNode(SDNode *N)
Assigns the representative SDNode for this SUnit.
unsigned NumPreds
unsigned NodeQueueId
Queue id of node.
bool isInstr() const
Returns true if this SUnit refers to a machine instruction as opposed to an SDNode.
unsigned TopReadyCycle
Cycle relative to start when node is ready.
SmallVectorImpl< SDep >::const_iterator const_succ_iterator
const MCSchedClassDesc * SchedClass
nullptr or resolved SchedClass.
unsigned NodeNum
Entry # of node in the node vector.
unsigned NumSuccsLeft
bool hasPhysRegClobbers
Has any physreg defs, used or not.
LLVM_ABI void biasCriticalPath()
Orders this node's predecessor edges such that the critical path edge occurs first.
bool isUnbuffered
Uses an unbuffered resource.
bool isCallOp
Is a function call operand.
const TargetRegisterClass * CopyDstRC
Is a special copy node if != nullptr.
SUnit(MachineInstr *instr, unsigned nodenum)
Constructs an SUnit for post-regalloc scheduling to represent a MachineInstr.
SmallVectorImpl< SDep >::const_iterator const_pred_iterator
unsigned getHeight() const
Returns the height of this node, which is the length of the maximum path down to any node which has n...
void setInstr(MachineInstr *MI)
Assigns the instruction for the SUnit.
LLVM_ABI void setHeightDirty()
Sets a flag in this node to indicate that its stored Height value will require recomputation the next...
bool isSucc(const SUnit *N) const
Tests if node N is a successor of this node.
LLVM_ABI void removePred(const SDep &D)
Removes the specified edge as a pred of the current node if it exists.
bool isPred(const SUnit *N) const
Tests if node N is a predecessor of this node.
unsigned short Latency
Node latency.
SmallVectorImpl< SDep >::iterator pred_iterator
bool isBoundaryNode() const
Boundary nodes are placeholders for the boundary of the scheduling region.
unsigned short NumRegDefsLeft
bool isScheduleHigh
True if preferable to schedule high.
bool isPending
True once pending.
unsigned getDepth() const
Returns the depth of this node, which is the length of the maximum path up to any node which has no p...
bool isScheduled
True once scheduled.
unsigned ParentClusterIdx
The parent cluster id.
bool isAvailable
True once available.
unsigned NumPredsLeft
bool isScheduleLow
True if preferable to schedule low.
bool hasPhysRegDefs
Has physreg defs that are being used.
unsigned BotReadyCycle
Cycle relative to end when node is ready.
bool isClustered() const
LLVM_ABI void dumpAttributes() const
SmallVector< SDep, 4 > Succs
All sunit successors.
Sched::Preference SchedulingPref
Scheduling preference.
SUnit(SDNode *node, unsigned nodenum)
Constructs an SUnit for pre-regalloc scheduling to represent an SDNode and any nodes flagged to it.
bool hasReservedResource
Uses a reserved resource.
unsigned WeakPredsLeft
const TargetRegisterClass * CopySrcRC
bool isBottomReady() const
SDNode * getNode() const
Returns the representative SDNode for this SUnit.
bool isTwoAddress
Is a two-address instruction.
bool isCommutable
Is a commutable instruction.
bool isVRegCycle
May use and def the same vreg.
SUnit()
Constructs a placeholder SUnit.
SDNode * Node
Representative node.
bool hasPhysRegUses
Has physreg uses.
LLVM_ABI void setDepthDirty()
Sets a flag in this node to indicate that its stored Depth value will require recomputation the next ...
MachineInstr * Instr
Alternatively, a MachineInstr.
bool isTopReady() const
SmallVector< SDep, 4 > Preds
All sunit predecessors.
unsigned WeakSuccsLeft
SmallVectorImpl< SDep >::iterator succ_iterator
LLVM_ABI void setDepthToAtLeast(unsigned NewDepth)
If NewDepth is greater than this node's depth value, sets it to be the new depth value.
SUnit * OrigNode
If not this, the node from which this node was cloned.
LLVM_ABI bool addPred(const SDep &D, bool Required=true)
Adds the specified edge as a pred of the current node if not already.
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
LLVM_ABI void RemovePred(SUnit *M, SUnit *N)
Updates the topological ordering to accommodate an edge to be removed from the specified node N from ...
LLVM_ABI bool WillCreateCycle(SUnit *TargetSU, SUnit *SU)
Returns true if addPred(TargetSU, SU) creates a cycle.
void MarkDirty()
Mark the ordering as temporarily broken, after a new node has been added.
LLVM_ABI void AddSUnitWithoutPredecessors(const SUnit *SU)
Add a SUnit without predecessors to the end of the topological order.
const_reverse_iterator rbegin() const
std::vector< int >::reverse_iterator reverse_iterator
LLVM_ABI ScheduleDAGTopologicalSort(std::vector< SUnit > &SUnits, SUnit *ExitSU)
LLVM_ABI std::vector< int > GetSubGraph(const SUnit &StartSU, const SUnit &TargetSU, bool &Success)
Returns an array of SUs that are both in the successor subtree of StartSU and in the predecessor subt...
const_iterator end() const
LLVM_ABI void InitDAGTopologicalSorting()
Creates the initial topological ordering from the DAG to be scheduled.
LLVM_ABI void AddPred(SUnit *Y, SUnit *X)
Updates the topological ordering to accommodate an edge to be added from SUnit X to SUnit Y.
std::vector< int >::const_iterator const_iterator
std::vector< int >::iterator iterator
const_reverse_iterator rend() const
const_iterator begin() const
LLVM_ABI bool IsReachable(const SUnit *SU, const SUnit *TargetSU)
Checks if SU is reachable from TargetSU.
LLVM_ABI void AddPredQueued(SUnit *Y, SUnit *X)
Queues an update to the topological ordering to accommodate an edge to be added from SUnit X to SUnit...
std::vector< int >::const_reverse_iterator const_reverse_iterator
const MCInstrDesc * getInstrDesc(const SUnit *SU) const
Returns the MCInstrDesc of this SUnit.
MachineRegisterInfo & MRI
Virtual/real register map.
void clearDAG()
Clears the DAG state (between regions).
virtual std::string getGraphNodeLabel(const SUnit *SU) const =0
Returns a label for an SUnit node in a visualization of the ScheduleDAG.
const TargetInstrInfo * TII
Target instruction information.
virtual std::string getDAGName() const =0
Returns a label for the region of code covered by the DAG.
std::vector< SUnit > SUnits
The scheduling units.
virtual ~ScheduleDAG()
const TargetRegisterInfo * TRI
Target processor register info.
SUnit EntrySU
Special node for the region entry.
MachineFunction & MF
Machine function.
ScheduleDAG & operator=(const ScheduleDAG &)=delete
virtual void dump() const =0
ScheduleDAG(const ScheduleDAG &)=delete
const TargetMachine & TM
Target processor.
virtual void addCustomGraphFeatures(GraphWriter< ScheduleDAG * > &) const
Adds custom features for a visualization of the ScheduleDAG.
virtual void dumpNode(const SUnit &SU) const =0
void dumpNodeName(const SUnit &SU) const
SUnit ExitSU
Special node for the region exit.
void setCurCycle(unsigned Cycle)
SchedulingPriorityQueue(bool rf=false)
virtual void remove(SUnit *SU)=0
virtual bool isBottomUp() const =0
virtual void releaseState()=0
virtual SUnit * pop()=0
virtual void scheduledNode(SUnit *)
As each node is scheduled, this method is invoked.
virtual bool isReady(SUnit *) const
virtual bool tracksRegPressure() const
virtual void dump(ScheduleDAG *) const
virtual void initNodes(std::vector< SUnit > &SUnits)=0
virtual ~SchedulingPriorityQueue()=default
virtual bool empty() const =0
virtual void unscheduledNode(SUnit *)
void push_all(const std::vector< SUnit * > &Nodes)
virtual void addNode(const SUnit *SU)=0
virtual void updateNode(const SUnit *SU)=0
virtual void push(SUnit *U)=0
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
typename SuperClass::const_iterator const_iterator
typename SuperClass::iterator iterator
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
Primary interface to the complete machine description for the target machine.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
@ Success
The lock was released successfully.
constexpr unsigned InvalidClusterId
@ Other
Any other memory.
Definition ModRef.h:68
bool isTheSameCluster(unsigned A, unsigned B)
Return whether the input cluster ID's are the same and valid.
DWARFExpression::Operation Op
SmallPtrSet< SUnit *, 8 > ClusterInfo
Keep record of which SUnit are in the same cluster group.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
#define N
static ChildIteratorType child_begin(NodeRef N)
static NodeRef getEntryNode(SUnit *N)
static ChildIteratorType child_end(NodeRef N)
static nodes_iterator nodes_begin(ScheduleDAG *G)
static nodes_iterator nodes_end(ScheduleDAG *G)
pointer_iterator< std::vector< SUnit >::iterator > nodes_iterator
Summarize the scheduling resources required for an instruction of a particular scheduling class.
Definition MCSchedule.h:129