LLVM 20.0.0git
Scheduler.h
Go to the documentation of this file.
1//===- Scheduler.h ----------------------------------------------*- 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// This is the bottom-up list scheduler used by the vectorizer. It is used for
10// checking the legality of vectorization and for scheduling instructions in
11// such a way that makes vectorization possible, if legal.
12//
13// The legality check is performed by `trySchedule(Instrs)`, which will try to
14// schedule the IR until all instructions in `Instrs` can be scheduled together
15// back-to-back. If this fails then it is illegal to vectorize `Instrs`.
16//
17// Internally the scheduler uses the vectorizer-specific DependencyGraph class.
18//
19//===----------------------------------------------------------------------===//
20
21#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SCHEDULER_H
22#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SCHEDULER_H
23
26#include <queue>
27
28namespace llvm::sandboxir {
29
31public:
32 bool operator()(const DGNode *N1, const DGNode *N2) {
33 // TODO: This should be a hierarchical comparator.
34 return N1->getInstruction()->comesBefore(N2->getInstruction());
35 }
36};
37
38/// The list holding nodes that are ready to schedule. Used by the scheduler.
40 PriorityCmp Cmp;
41 /// Control/Other dependencies are not modeled by the DAG to save memory.
42 /// These have to be modeled in the ready list for correctness.
43 /// This means that the list will hold back nodes that need to meet such
44 /// unmodeled dependencies.
45 std::priority_queue<DGNode *, std::vector<DGNode *>, PriorityCmp> List;
46
47public:
49 void insert(DGNode *N) { List.push(N); }
51 auto *Back = List.top();
52 List.pop();
53 return Back;
54 }
55 bool empty() const { return List.empty(); }
56 void clear() { List = {}; }
57#ifndef NDEBUG
58 void dump(raw_ostream &OS) const;
59 LLVM_DUMP_METHOD void dump() const;
60#endif // NDEBUG
61};
62
63/// The nodes that need to be scheduled back-to-back in a single scheduling
64/// cycle form a SchedBundle.
66public:
68
69private:
70 ContainerTy Nodes;
71
72 /// Called by the DGNode destructor to avoid accessing freed memory.
73 void eraseFromBundle(DGNode *N) { Nodes.erase(find(Nodes, N)); }
74 friend DGNode::~DGNode(); // For eraseFromBundle().
75
76public:
77 SchedBundle() = default;
78 SchedBundle(ContainerTy &&Nodes) : Nodes(std::move(Nodes)) {
79 for (auto *N : this->Nodes)
80 N->setSchedBundle(*this);
81 }
82 /// Copy CTOR (unimplemented).
83 SchedBundle(const SchedBundle &Other) = delete;
84 /// Copy Assignment (unimplemented).
87 for (auto *N : this->Nodes)
88 N->clearSchedBundle();
89 }
90 bool empty() const { return Nodes.empty(); }
91 DGNode *back() const { return Nodes.back(); }
94 iterator begin() { return Nodes.begin(); }
95 iterator end() { return Nodes.end(); }
96 const_iterator begin() const { return Nodes.begin(); }
97 const_iterator end() const { return Nodes.end(); }
98 /// \Returns the bundle node that comes before the others in program order.
99 DGNode *getTop() const;
100 /// \Returns the bundle node that comes after the others in program order.
101 DGNode *getBot() const;
102 /// Move all bundle instructions to \p Where back-to-back.
103 void cluster(BasicBlock::iterator Where);
104#ifndef NDEBUG
105 void dump(raw_ostream &OS) const;
106 LLVM_DUMP_METHOD void dump() const;
107#endif
108};
109
110/// The list scheduler.
112 ReadyListContainer ReadyList;
113 DependencyGraph DAG;
114 std::optional<BasicBlock::iterator> ScheduleTopItOpt;
115 // TODO: This is wasting memory in exchange for fast removal using a raw ptr.
117
118 /// \Returns a scheduling bundle containing \p Instrs.
119 SchedBundle *createBundle(ArrayRef<Instruction *> Instrs);
120 void eraseBundle(SchedBundle *SB);
121 /// Schedule nodes until we can schedule \p Instrs back-to-back.
122 bool tryScheduleUntil(ArrayRef<Instruction *> Instrs);
123 /// Schedules all nodes in \p Bndl, marks them as scheduled, updates the
124 /// UnscheduledSuccs counter of all dependency predecessors, and adds any of
125 /// them that become ready to the ready list.
126 void scheduleAndUpdateReadyList(SchedBundle &Bndl);
127 /// The scheduling state of the instructions in the bundle.
128 enum class BndlSchedState {
129 NoneScheduled, ///> No instruction in the bundle was previously scheduled.
130 PartiallyOrDifferentlyScheduled, ///> Only some of the instrs in the bundle
131 /// were previously scheduled, or all of
132 /// them were but not in the same
133 /// SchedBundle.
134 FullyScheduled, ///> All instrs in the bundle were previously scheduled and
135 /// were in the same SchedBundle.
136 };
137 /// \Returns whether none/some/all of \p Instrs have been scheduled.
138 BndlSchedState getBndlSchedState(ArrayRef<Instruction *> Instrs) const;
139 /// Destroy the top-most part of the schedule that includes \p Instrs.
140 void trimSchedule(ArrayRef<Instruction *> Instrs);
141 /// Disable copies.
142 Scheduler(const Scheduler &) = delete;
143 Scheduler &operator=(const Scheduler &) = delete;
144
145public:
146 Scheduler(AAResults &AA, Context &Ctx) : DAG(AA, Ctx) {}
148
150
151#ifndef NDEBUG
152 void dump(raw_ostream &OS) const;
153 LLVM_DUMP_METHOD void dump() const;
154#endif
155};
156
157} // namespace llvm::sandboxir
158
159#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SCHEDULER_H
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:622
const NodeList & List
Definition: RDFGraph.cpp:200
raw_pwrite_stream & OS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
bool empty() const
Definition: SmallVector.h:81
iterator erase(const_iterator CI)
Definition: SmallVector.h:737
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
Iterator for Instructions in a `BasicBlock.
Definition: BasicBlock.h:23
A DependencyGraph Node that points to an Instruction and contains memory dependency edges.
Instruction * getInstruction() const
bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
Definition: Instruction.h:214
bool operator()(const DGNode *N1, const DGNode *N2)
Definition: Scheduler.h:32
The list holding nodes that are ready to schedule. Used by the scheduler.
Definition: Scheduler.h:39
LLVM_DUMP_METHOD void dump() const
Definition: Scheduler.cpp:63
The nodes that need to be scheduled back-to-back in a single scheduling cycle form a SchedBundle.
Definition: Scheduler.h:65
DGNode * getBot() const
\Returns the bundle node that comes after the others in program order.
Definition: Scheduler.cpp:24
SchedBundle(ContainerTy &&Nodes)
Definition: Scheduler.h:78
SchedBundle & operator=(const SchedBundle &Other)=delete
Copy Assignment (unimplemented).
DGNode * getTop() const
\Returns the bundle node that comes before the others in program order.
Definition: Scheduler.cpp:15
const_iterator begin() const
Definition: Scheduler.h:96
LLVM_DUMP_METHOD void dump() const
Definition: Scheduler.cpp:48
SchedBundle(const SchedBundle &Other)=delete
Copy CTOR (unimplemented).
DGNode * back() const
Definition: Scheduler.h:91
const_iterator end() const
Definition: Scheduler.h:97
void cluster(BasicBlock::iterator Where)
Move all bundle instructions to Where back-to-back.
Definition: Scheduler.cpp:33
The list scheduler.
Definition: Scheduler.h:111
LLVM_DUMP_METHOD void dump() const
Definition: Scheduler.cpp:229
bool trySchedule(ArrayRef< Instruction * > Instrs)
Definition: Scheduler.cpp:187
Scheduler(AAResults &AA, Context &Ctx)
Definition: Scheduler.h:146
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1759
@ Other
Any other memory.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1873
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
#define N