LLVM 24.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 float ReservationStationScaleFactor)
160 : Scheduler(Model, Lsu, ReservationStationScaleFactor, nullptr) {}
161
163 float ReservationStationScaleFactor,
164 std::unique_ptr<SchedulerStrategy> SelectStrategy)
165 : Scheduler(std::make_unique<ResourceManager>(
166 Model, ReservationStationScaleFactor),
167 Lsu, std::move(SelectStrategy)) {}
168
169 Scheduler(std::unique_ptr<ResourceManager> RM, LSUnitBase &Lsu,
170 std::unique_ptr<SchedulerStrategy> SelectStrategy)
171 : LSU(Lsu), Resources(std::move(RM)), BusyResourceUnits(0),
172 NumDispatchedToThePendingSet(0), HadTokenStall(false) {
173 initializeStrategy(std::move(SelectStrategy));
174 }
175
176 // Stalls generated by the scheduler.
184
185 /// Check if the instruction in 'IR' can be dispatched during this cycle.
186 /// Return SC_AVAILABLE if both scheduler and LS resources are available.
187 ///
188 /// This method is also responsible for setting field HadTokenStall if
189 /// IR cannot be dispatched to the Scheduler due to unavailable resources.
191
192 /// Reserves buffer and LSUnit queue resources that are necessary to issue
193 /// this instruction.
194 ///
195 /// Returns true if instruction IR is ready to be issued to the underlying
196 /// pipelines. Note that this operation cannot fail; it assumes that a
197 /// previous call to method `isAvailable(IR)` returned `SC_AVAILABLE`.
198 ///
199 /// If IR is a memory operation, then the Scheduler queries the LS unit to
200 /// obtain a LS token. An LS token is used internally to track memory
201 /// dependencies.
203
204 /// Issue an instruction and populates a vector of used pipeline resources,
205 /// and a vector of instructions that transitioned to the ready state as a
206 /// result of this event.
208 InstRef &IR,
209 SmallVectorImpl<std::pair<ResourceRef, ReleaseAtCycles>> &Used,
211
212 /// Returns true if IR has to be issued immediately, or if IR is a zero
213 /// latency instruction.
214 LLVM_ABI bool mustIssueImmediately(const InstRef &IR) const;
215
216 /// This routine notifies the Scheduler that a new cycle just started.
217 ///
218 /// It notifies the underlying ResourceManager that a new cycle just started.
219 /// Vector `Freed` is populated with resourceRef related to resources that
220 /// have changed in state, and that are now available to new instructions.
221 /// Instructions executed are added to vector Executed, while vector Ready is
222 /// populated with instructions that have become ready in this new cycle.
223 /// Vector Pending is popluated by instructions that have transitioned through
224 /// the pending stat during this cycle. The Pending and Ready sets may not be
225 /// disjoint. An instruction is allowed to transition from the WAIT state to
226 /// the READY state (going through the PENDING state) within a single cycle.
227 /// That means, instructions may appear in both the Pending and Ready set.
229 SmallVectorImpl<InstRef> &Executed,
232
233 /// Convert a resource mask into a valid llvm processor resource identifier.
234 ///
235 /// Only the most significant bit of the Mask is used by this method to
236 /// identify the processor resource.
237 unsigned getResourceID(uint64_t Mask) const {
238 return Resources->resolveResourceMask(Mask);
239 }
240
241 /// Select the next instruction to issue from the ReadySet. Returns an invalid
242 /// instruction reference if there are no ready instructions, or if processor
243 /// resources are not available.
245
246 bool isReadySetEmpty() const { return ReadySet.empty(); }
247 bool isWaitSetEmpty() const { return WaitSet.empty(); }
248
249 /// This method is called by the ExecuteStage at the end of each cycle to
250 /// identify bottlenecks caused by data dependencies. Vector RegDeps is
251 /// populated by instructions that were not issued because of unsolved
252 /// register dependencies. Vector MemDeps is populated by instructions that
253 /// were not issued because of unsolved memory dependencies.
255 SmallVectorImpl<InstRef> &MemDeps);
256
257 /// Returns a mask of busy resources, and populates vector Insts with
258 /// instructions that could not be issued to the underlying pipelines because
259 /// not all pipeline resources were available.
261
262 // Returns true if the dispatch logic couldn't dispatch a full group due to
263 // unavailable scheduler and/or LS resources.
264 bool hadTokenStall() const { return HadTokenStall; }
265
266#ifndef NDEBUG
267 // Update the ready queues.
268 void dump() const;
269
270 // This routine performs a basic correctness check. This routine should only
271 // be called when we know that 'IR' is not in the scheduler's instruction
272 // queues.
273 void instructionCheck(const InstRef &IR) const {
274 assert(!is_contained(WaitSet, IR) && "Already in the wait set!");
275 assert(!is_contained(ReadySet, IR) && "Already in the ready set!");
276 assert(!is_contained(IssuedSet, IR) && "Already executing!");
277 }
278#endif // !NDEBUG
279};
280} // namespace mca
281} // namespace llvm
282
283#endif // LLVM_MCA_HARDWAREUNITS_SCHEDULER_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
#define LLVM_ABI
Definition Compiler.h:215
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:85
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...
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.
Instruction * getInstruction()
unsigned getSourceIndex() const
unsigned getNumUsers() const
Abstract base interface for LS (load/store) units in llvm-mca.
Definition LSUnit.h:29
virtual bool compare(const InstRef &Lhs, const InstRef &Rhs) const =0
Returns true if Lhs should take priority over Rhs.
LLVM_ABI InstRef select()
Select the next instruction to issue from the ReadySet.
unsigned getResourceID(uint64_t Mask) const
Convert a resource mask into a valid llvm processor resource identifier.
Definition Scheduler.h:237
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 ...
Scheduler(std::unique_ptr< ResourceManager > RM, LSUnitBase &Lsu, std::unique_ptr< SchedulerStrategy > SelectStrategy)
Definition Scheduler.h:169
LLVM_ABI Status isAvailable(const InstRef &IR)
Check if the instruction in 'IR' can be dispatched during this cycle.
Definition Scheduler.cpp:40
Scheduler(const MCSchedModel &Model, LSUnitBase &Lsu, float ReservationStationScaleFactor, std::unique_ptr< SchedulerStrategy > SelectStrategy)
Definition Scheduler.h:162
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 ...
LLVM_ABI bool dispatch(InstRef &IR)
Reserves buffer and LSUnit queue resources that are necessary to issue this instruction.
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.
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.
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...
Scheduler(const MCSchedModel &Model, LSUnitBase &Lsu, float ReservationStationScaleFactor)
Definition Scheduler.h:158
bool isReadySetEmpty() const
Definition Scheduler.h:246
void dump() const
Definition Scheduler.cpp:32
void instructionCheck(const InstRef &IR) const
Definition Scheduler.h:273
bool hadTokenStall() const
Definition Scheduler.h:264
bool isWaitSetEmpty() const
Definition Scheduler.h:247
Helper functions used by various pipeline components.
This is an optimization pass for GlobalISel generic memory operations.
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:1933
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
Machine model for scheduling, bundling, and heuristics.
Definition MCSchedule.h:274