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