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