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