LLVM 22.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/// \file
9///
10/// A scheduler for Processor Resource Units and Processor Resource Groups.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_MCA_HARDWAREUNITS_SCHEDULER_H
15#define LLVM_MCA_HARDWAREUNITS_SCHEDULER_H
16
18#include "llvm/MC/MCSchedule.h"
22#include "llvm/MCA/Support.h"
24
25namespace llvm {
26namespace mca {
27
29public:
30 SchedulerStrategy() = default;
32
33 /// Returns true if Lhs should take priority over Rhs.
34 ///
35 /// This method is used by class Scheduler to select the "best" ready
36 /// instruction to issue to the underlying pipelines.
37 virtual bool compare(const InstRef &Lhs, const InstRef &Rhs) const = 0;
38};
39
40/// Default instruction selection strategy used by class Scheduler.
42 /// This method ranks instructions based on their age, and the number of known
43 /// users. The lower the rank value, the better.
44 int computeRank(const InstRef &Lhs) const {
45 return Lhs.getSourceIndex() - Lhs.getInstruction()->getNumUsers();
46 }
47
48public:
51
52 bool compare(const InstRef &Lhs, const InstRef &Rhs) const override {
53 int LhsRank = computeRank(Lhs);
54 int RhsRank = computeRank(Rhs);
55
56 /// Prioritize older instructions over younger instructions to minimize the
57 /// pressure on the reorder buffer.
58 if (LhsRank == RhsRank)
59 return Lhs.getSourceIndex() < Rhs.getSourceIndex();
60 return LhsRank < RhsRank;
61 }
62};
63
64/// Class Scheduler is responsible for issuing instructions to pipeline
65/// resources.
66///
67/// Internally, it delegates to a ResourceManager the management of processor
68/// resources. This class is also responsible for tracking the progress of
69/// instructions from the dispatch stage, until the write-back stage.
70///
71class Scheduler : public HardwareUnit {
72 LSUnitBase &LSU;
73
74 // Instruction selection strategy for this Scheduler.
75 std::unique_ptr<SchedulerStrategy> Strategy;
76
77 // Hardware resources that are managed by this scheduler.
78 std::unique_ptr<ResourceManager> Resources;
79
80 // Instructions dispatched to the Scheduler are internally classified based on
81 // the instruction stage (see Instruction::InstrStage).
82 //
83 // An Instruction dispatched to the Scheduler is added to the WaitSet if not
84 // all its register operands are available, and at least one latency is
85 // unknown. By construction, the WaitSet only contains instructions that are
86 // in the IS_DISPATCHED stage.
87 //
88 // An Instruction transitions from the WaitSet to the PendingSet if the
89 // instruction is not ready yet, but the latency of every register read is
90 // known. Instructions in the PendingSet can only be in the IS_PENDING or
91 // IS_READY stage. Only IS_READY instructions that are waiting on memory
92 // dependencies can be added to the PendingSet.
93 //
94 // Instructions in the PendingSet are immediately dominated only by
95 // instructions that have already been issued to the underlying pipelines. In
96 // the presence of bottlenecks caused by data dependencies, the PendingSet can
97 // be inspected to identify problematic data dependencies between
98 // instructions.
99 //
100 // An instruction is moved to the ReadySet when all register operands become
101 // available, and all memory dependencies are met. Instructions that are
102 // moved from the PendingSet to the ReadySet must transition to the 'IS_READY'
103 // stage.
104 //
105 // On every cycle, the Scheduler checks if it can promote instructions from the
106 // PendingSet to the ReadySet.
107 //
108 // An Instruction is moved from the ReadySet to the `IssuedSet` when it starts
109 // exection. This event also causes an instruction state transition (i.e. from
110 // state IS_READY, to state IS_EXECUTING). An Instruction leaves the IssuedSet
111 // only when it reaches the write-back stage.
112 std::vector<InstRef> WaitSet;
113 std::vector<InstRef> PendingSet;
114 std::vector<InstRef> ReadySet;
115 std::vector<InstRef> IssuedSet;
116
117 // A mask of busy resource units. It defaults to the empty set (i.e. a zero
118 // mask), and it is cleared at the beginning of every cycle.
119 // It is updated every time the scheduler fails to issue an instruction from
120 // the ready set due to unavailable pipeline resources.
121 // Each bit of the mask represents an unavailable resource.
122 uint64_t BusyResourceUnits;
123
124 // Counts the number of instructions in the pending set that were dispatched
125 // during this cycle.
126 unsigned NumDispatchedToThePendingSet;
127
128 // True if the previous pipeline Stage was unable to dispatch a full group of
129 // opcodes because scheduler buffers (or LS queues) were unavailable.
130 bool HadTokenStall;
131
132 /// Verify the given selection strategy and set the Strategy member
133 /// accordingly. If no strategy is provided, the DefaultSchedulerStrategy is
134 /// used.
135 LLVM_ABI void initializeStrategy(std::unique_ptr<SchedulerStrategy> S);
136
137 /// Issue an instruction without updating the ready queue.
138 void issueInstructionImpl(
139 InstRef &IR,
140 SmallVectorImpl<std::pair<ResourceRef, ReleaseAtCycles>> &Pipes);
141
142 // Identify instructions that have finished executing, and remove them from
143 // the IssuedSet. References to executed instructions are added to input
144 // vector 'Executed'.
145 void updateIssuedSet(SmallVectorImpl<InstRef> &Executed);
146
147 // Try to promote instructions from the PendingSet to the ReadySet.
148 // Add promoted instructions to the 'Ready' vector in input.
149 // Returns true if at least one instruction was promoted.
150 bool promoteToReadySet(SmallVectorImpl<InstRef> &Ready);
151
152 // Try to promote instructions from the WaitSet to the PendingSet.
153 // Add promoted instructions to the 'Pending' vector in input.
154 // Returns true if at least one instruction was promoted.
155 bool promoteToPendingSet(SmallVectorImpl<InstRef> &Pending);
156
157public:
159 : Scheduler(Model, Lsu, nullptr) {}
160
162 std::unique_ptr<SchedulerStrategy> SelectStrategy)
163 : Scheduler(std::make_unique<ResourceManager>(Model), Lsu,
164 std::move(SelectStrategy)) {}
165
166 Scheduler(std::unique_ptr<ResourceManager> RM, LSUnitBase &Lsu,
167 std::unique_ptr<SchedulerStrategy> SelectStrategy)
168 : LSU(Lsu), Resources(std::move(RM)), BusyResourceUnits(0),
169 NumDispatchedToThePendingSet(0), HadTokenStall(false) {
170 initializeStrategy(std::move(SelectStrategy));
171 }
172
173 // Stalls generated by the scheduler.
174 enum Status {
180 };
181
182 /// Check if the instruction in 'IR' can be dispatched during this cycle.
183 /// Return SC_AVAILABLE if both scheduler and LS resources are available.
184 ///
185 /// This method is also responsible for setting field HadTokenStall if
186 /// IR cannot be dispatched to the Scheduler due to unavailable resources.
188
189 /// Reserves buffer and LSUnit queue resources that are necessary to issue
190 /// this instruction.
191 ///
192 /// Returns true if instruction IR is ready to be issued to the underlying
193 /// pipelines. Note that this operation cannot fail; it assumes that a
194 /// previous call to method `isAvailable(IR)` returned `SC_AVAILABLE`.
195 ///
196 /// If IR is a memory operation, then the Scheduler queries the LS unit to
197 /// obtain a LS token. An LS token is used internally to track memory
198 /// dependencies.
200
201 /// Issue an instruction and populates a vector of used pipeline resources,
202 /// and a vector of instructions that transitioned to the ready state as a
203 /// result of this event.
205 InstRef &IR,
206 SmallVectorImpl<std::pair<ResourceRef, ReleaseAtCycles>> &Used,
208
209 /// Returns true if IR has to be issued immediately, or if IR is a zero
210 /// latency instruction.
211 LLVM_ABI bool mustIssueImmediately(const InstRef &IR) const;
212
213 /// This routine notifies the Scheduler that a new cycle just started.
214 ///
215 /// It notifies the underlying ResourceManager that a new cycle just started.
216 /// Vector `Freed` is populated with resourceRef related to resources that
217 /// have changed in state, and that are now available to new instructions.
218 /// Instructions executed are added to vector Executed, while vector Ready is
219 /// populated with instructions that have become ready in this new cycle.
220 /// Vector Pending is popluated by instructions that have transitioned through
221 /// the pending stat during this cycle. The Pending and Ready sets may not be
222 /// disjoint. An instruction is allowed to transition from the WAIT state to
223 /// the READY state (going through the PENDING state) within a single cycle.
224 /// That means, instructions may appear in both the Pending and Ready set.
226 SmallVectorImpl<InstRef> &Executed,
229
230 /// Convert a resource mask into a valid llvm processor resource identifier.
231 ///
232 /// Only the most significant bit of the Mask is used by this method to
233 /// identify the processor resource.
234 unsigned getResourceID(uint64_t Mask) const {
235 return Resources->resolveResourceMask(Mask);
236 }
237
238 /// Select the next instruction to issue from the ReadySet. Returns an invalid
239 /// instruction reference if there are no ready instructions, or if processor
240 /// resources are not available.
242
243 bool isReadySetEmpty() const { return ReadySet.empty(); }
244 bool isWaitSetEmpty() const { return WaitSet.empty(); }
245
246 /// This method is called by the ExecuteStage at the end of each cycle to
247 /// identify bottlenecks caused by data dependencies. Vector RegDeps is
248 /// populated by instructions that were not issued because of unsolved
249 /// register dependencies. Vector MemDeps is populated by instructions that
250 /// were not issued because of unsolved memory dependencies.
252 SmallVectorImpl<InstRef> &MemDeps);
253
254 /// Returns a mask of busy resources, and populates vector Insts with
255 /// instructions that could not be issued to the underlying pipelines because
256 /// not all pipeline resources were available.
258
259 // Returns true if the dispatch logic couldn't dispatch a full group due to
260 // unavailable scheduler and/or LS resources.
261 bool hadTokenStall() const { return HadTokenStall; }
262
263#ifndef NDEBUG
264 // Update the ready queues.
265 void dump() const;
266
267 // This routine performs a basic correctness check. This routine should only
268 // be called when we know that 'IR' is not in the scheduler's instruction
269 // queues.
270 void instructionCheck(const InstRef &IR) const {
271 assert(!is_contained(WaitSet, IR) && "Already in the wait set!");
272 assert(!is_contained(ReadySet, IR) && "Already in the ready set!");
273 assert(!is_contained(IssuedSet, IR) && "Already executing!");
274 }
275#endif // !NDEBUG
276};
277} // namespace mca
278} // namespace llvm
279
280#endif // LLVM_MCA_HARDWAREUNITS_SCHEDULER_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_ABI
Definition: Compiler.h:213
This file defines a base class for describing a simulated hardware unit.
A Load/Store unit class that models load/store queues and that implements a simple weak memory consis...
Legalize the Machine IR a function s Machine IR
Definition: Legalizer.cpp:80
The classes here represent processor resource units and their management strategy.
This file defines the SmallVector class.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
Default instruction selection strategy used by class Scheduler.
Definition: Scheduler.h:41
bool compare(const InstRef &Lhs, const InstRef &Rhs) const override
Returns true if Lhs should take priority over Rhs.
Definition: Scheduler.h:52
An InstRef contains both a SourceMgr index and Instruction pair.
Definition: Instruction.h:725
Instruction * getInstruction()
Definition: Instruction.h:739
unsigned getSourceIndex() const
Definition: Instruction.h:738
unsigned getNumUsers() const
Definition: Instruction.h:572
Abstract base interface for LS (load/store) units in llvm-mca.
Definition: LSUnit.h:29
A resource manager for processor resource units and groups.
virtual bool compare(const InstRef &Lhs, const InstRef &Rhs) const =0
Returns true if Lhs should take priority over Rhs.
Class Scheduler is responsible for issuing instructions to pipeline resources.
Definition: Scheduler.h:71
LLVM_ABI InstRef select()
Select the next instruction to issue from the ReadySet.
Definition: Scheduler.cpp:193
unsigned getResourceID(uint64_t Mask) const
Convert a resource mask into a valid llvm processor resource identifier.
Definition: Scheduler.h:234
LLVM_ABI void issueInstruction(InstRef &IR, SmallVectorImpl< std::pair< ResourceRef, ReleaseAtCycles > > &Used, SmallVectorImpl< InstRef > &Pending, SmallVectorImpl< InstRef > &Ready)
Issue an instruction and populates a vector of used pipeline resources, and a vector of instructions ...
Definition: Scheduler.cpp:100
Scheduler(std::unique_ptr< ResourceManager > RM, LSUnitBase &Lsu, std::unique_ptr< SchedulerStrategy > SelectStrategy)
Definition: Scheduler.h:166
LLVM_ABI Status isAvailable(const InstRef &IR)
Check if the instruction in 'IR' can be dispatched during this cycle.
Definition: Scheduler.cpp:40
LLVM_ABI void analyzeDataDependencies(SmallVectorImpl< InstRef > &RegDeps, SmallVectorImpl< InstRef > &MemDeps)
This method is called by the ExecuteStage at the end of each cycle to identify bottlenecks caused by ...
Definition: Scheduler.cpp:249
Scheduler(const MCSchedModel &Model, LSUnitBase &Lsu, std::unique_ptr< SchedulerStrategy > SelectStrategy)
Definition: Scheduler.h:161
LLVM_ABI bool dispatch(InstRef &IR)
Reserves buffer and LSUnit queue resources that are necessary to issue this instruction.
Definition: Scheduler.cpp:301
LLVM_ABI void cycleEvent(SmallVectorImpl< ResourceRef > &Freed, SmallVectorImpl< InstRef > &Executed, SmallVectorImpl< InstRef > &Pending, SmallVectorImpl< InstRef > &Ready)
This routine notifies the Scheduler that a new cycle just started.
Definition: Scheduler.cpp:265
LLVM_ABI bool mustIssueImmediately(const InstRef &IR) const
Returns true if IR has to be issued immediately, or if IR is a zero latency instruction.
Definition: Scheduler.cpp:291
LLVM_ABI uint64_t analyzeResourcePressure(SmallVectorImpl< InstRef > &Insts)
Returns a mask of busy resources, and populates vector Insts with instructions that could not be issu...
Definition: Scheduler.cpp:244
bool isReadySetEmpty() const
Definition: Scheduler.h:243
void dump() const
Definition: Scheduler.cpp:32
void instructionCheck(const InstRef &IR) const
Definition: Scheduler.h:270
Scheduler(const MCSchedModel &Model, LSUnitBase &Lsu)
Definition: Scheduler.h:158
bool hadTokenStall() const
Definition: Scheduler.h:261
bool isWaitSetEmpty() const
Definition: Scheduler.h:244
Helper functions used by various pipeline components.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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:1886
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1916
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:851
Machine model for scheduling, bundling, and heuristics.
Definition: MCSchedule.h:258