blob: 8d44f61e32b1007cb0df767a4a49fc8e6822a56b [file] [log] [blame]
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +00001//===--------------------- Scheduler.h ------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10///
11/// A scheduler for Processor Resource Units and Processor Resource Groups.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_TOOLS_LLVM_MCA_SCHEDULER_H
16#define LLVM_TOOLS_LLVM_MCA_SCHEDULER_H
17
Matt Davis488ac4c2018-06-14 01:20:18 +000018#include "HWEventListener.h"
Matt Davis362ea5f2018-07-06 18:03:14 +000019#include "HardwareUnit.h"
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000020#include "Instruction.h"
21#include "LSUnit.h"
Matt Davis5b79ffc5b2018-05-25 18:00:25 +000022#include "RetireControlUnit.h"
Matt Davis488ac4c2018-06-14 01:20:18 +000023#include "llvm/ADT/ArrayRef.h"
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000024#include "llvm/ADT/DenseMap.h"
Matt Davis488ac4c2018-06-14 01:20:18 +000025#include "llvm/ADT/SmallVector.h"
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000026#include "llvm/MC/MCSubtargetInfo.h"
27#include <map>
28
29namespace mca {
30
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000031/// Used to notify the internal state of a processor resource.
32///
33/// A processor resource is available if it is not reserved, and there are
34/// available slots in the buffer. A processor resource is unavailable if it
35/// is either reserved, or the associated buffer is full. A processor resource
36/// with a buffer size of -1 is always available if it is not reserved.
37///
38/// Values of type ResourceStateEvent are returned by method
39/// ResourceState::isBufferAvailable(), which is used to query the internal
40/// state of a resource.
41///
42/// The naming convention for resource state events is:
43/// * Event names start with prefix RS_
44/// * Prefix RS_ is followed by a string describing the actual resource state.
45enum ResourceStateEvent {
46 RS_BUFFER_AVAILABLE,
47 RS_BUFFER_UNAVAILABLE,
48 RS_RESERVED
49};
50
Adrian Prantl5f8f34e42018-05-01 15:54:18 +000051/// A descriptor for processor resources.
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000052///
53/// Each object of class ResourceState is associated to a specific processor
54/// resource. There is an instance of this class for every processor resource
55/// defined by the scheduling model.
56/// A ResourceState dynamically tracks the availability of units of a processor
57/// resource. For example, the ResourceState of a ProcResGroup tracks the
58/// availability of resource units which are part of the group.
59///
60/// Internally, ResourceState uses a round-robin selector to identify
61/// which unit of the group shall be used next.
62class ResourceState {
Andrea Di Biagio0c541292018-03-10 16:55:07 +000063 // Index to the MCProcResourceDesc in the processor Model.
64 unsigned ProcResourceDescIndex;
Andrea Di Biagio4704f032018-03-20 12:25:54 +000065 // A resource mask. This is generated by the tool with the help of
66 // function `mca::createProcResourceMasks' (see Support.h).
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000067 uint64_t ResourceMask;
68
69 // A ProcResource can specify a number of units. For the purpose of dynamic
70 // scheduling, a processor resource with more than one unit behaves like a
71 // group. This field has one bit set for every unit/resource that is part of
72 // the group.
73 // For groups, this field defaults to 'ResourceMask'. For non-group
74 // resources, the number of bits set in this mask is equivalent to the
75 // number of units (i.e. field 'NumUnits' in 'ProcResourceUnits').
76 uint64_t ResourceSizeMask;
77
78 // A simple round-robin selector for processor resources.
79 // Each bit of the mask identifies a sub resource within this group.
80 //
81 // As an example, lets assume that this ResourceState describes a
82 // processor resource group composed of the following three units:
83 // ResourceA -- 0b001
84 // ResourceB -- 0b010
85 // ResourceC -- 0b100
86 //
87 // Each unit is identified by a ResourceMask which always contains a
88 // single bit set. Field NextInSequenceMask is initially set to value
89 // 0xb111. That value is obtained by OR'ing the resource masks of
90 // processor resource that are part of the group.
91 //
92 // NextInSequenceMask -- 0b111
93 //
94 // Field NextInSequenceMask is used by the resource manager (i.e.
95 // an object of class ResourceManager) to select the "next available resource"
96 // from the set. The algorithm would prioritize resources with a bigger
97 // ResourceMask value.
98 //
99 // In this example, there are three resources in the set, and 'ResourceC'
100 // has the highest mask value. The round-robin selector would firstly select
101 // 'ResourceC', then 'ResourceB', and eventually 'ResourceA'.
102 //
103 // When a resource R is used, its corresponding bit is cleared from the set.
104 //
105 // Back to the example:
106 // If 'ResourceC' is selected, then the new value of NextInSequenceMask
107 // becomes 0xb011.
108 //
109 // When NextInSequenceMask becomes zero, it is reset to its original value
110 // (in this example, that value would be 0b111).
111 uint64_t NextInSequenceMask;
112
113 // Some instructions can only be issued on very specific pipeline resources.
114 // For those instructions, we know exactly which resource would be consumed
115 // without having to dynamically select it using field 'NextInSequenceMask'.
116 //
117 // The resource mask bit associated to the (statically) selected
118 // processor resource is still cleared from the 'NextInSequenceMask'.
119 // If that bit was already zero in NextInSequenceMask, then we update
120 // mask 'RemovedFromNextInSequence'.
121 //
122 // When NextInSequenceMask is reset back to its initial value, the algorithm
123 // removes any bits which are set in RemoveFromNextInSequence.
124 uint64_t RemovedFromNextInSequence;
125
126 // A mask of ready units.
127 uint64_t ReadyMask;
128
129 // Buffered resources will have this field set to a positive number bigger
130 // than 0. A buffered resource behaves like a separate reservation station
131 // implementing its own buffer for out-of-order execution.
132 // A buffer of 1 is for units that force in-order execution.
133 // A value of 0 is treated specially. In particular, a resource with
134 // A BufferSize = 0 is for an in-order issue/dispatch resource.
135 // That means, this resource is reserved starting from the dispatch event,
136 // until all the "resource cycles" are consumed after the issue event.
137 // While this resource is reserved, no other instruction may be dispatched.
138 int BufferSize;
139
140 // Available slots in the buffer (zero, if this is not a buffered resource).
141 unsigned AvailableSlots;
142
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000143 // True if this is resource is currently unavailable.
144 // An instruction may "reserve" a resource for a number of cycles.
145 // During those cycles, the reserved resource cannot be used for other
146 // instructions, even if the ReadyMask is set.
147 bool Unavailable;
148
149 bool isSubResourceReady(uint64_t ID) const { return ReadyMask & ID; }
150
151 /// Returns the mask identifier of the next available resource in the set.
152 uint64_t getNextInSequence() const {
153 assert(NextInSequenceMask);
154 return llvm::PowerOf2Floor(NextInSequenceMask);
155 }
156
157 /// Returns the mask of the next available resource within the set,
158 /// and updates the resource selector.
159 void updateNextInSequence() {
160 NextInSequenceMask ^= getNextInSequence();
161 if (!NextInSequenceMask)
162 NextInSequenceMask = ResourceSizeMask;
163 }
164
165 uint64_t computeResourceSizeMaskForGroup(uint64_t ResourceMask) {
166 assert(llvm::countPopulation(ResourceMask) > 1);
167 return ResourceMask ^ llvm::PowerOf2Floor(ResourceMask);
168 }
169
170public:
Andrea Di Biagio0c541292018-03-10 16:55:07 +0000171 ResourceState(const llvm::MCProcResourceDesc &Desc, unsigned Index,
172 uint64_t Mask)
173 : ProcResourceDescIndex(Index), ResourceMask(Mask) {
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000174 bool IsAGroup = llvm::countPopulation(ResourceMask) > 1;
175 ResourceSizeMask = IsAGroup ? computeResourceSizeMaskForGroup(ResourceMask)
176 : ((1ULL << Desc.NumUnits) - 1);
177 NextInSequenceMask = ResourceSizeMask;
178 RemovedFromNextInSequence = 0;
179 ReadyMask = ResourceSizeMask;
180 BufferSize = Desc.BufferSize;
181 AvailableSlots = BufferSize == -1 ? 0U : static_cast<unsigned>(BufferSize);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000182 Unavailable = false;
183 }
184
Andrea Di Biagio0c541292018-03-10 16:55:07 +0000185 unsigned getProcResourceID() const { return ProcResourceDescIndex; }
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000186 uint64_t getResourceMask() const { return ResourceMask; }
187 int getBufferSize() const { return BufferSize; }
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000188
189 bool isBuffered() const { return BufferSize > 0; }
190 bool isInOrder() const { return BufferSize == 1; }
191 bool isADispatchHazard() const { return BufferSize == 0; }
192 bool isReserved() const { return Unavailable; }
193
194 void setReserved() { Unavailable = true; }
195 void clearReserved() { Unavailable = false; }
196
197 // A resource is ready if it is not reserved, and if there are enough
198 // available units.
199 // If a resource is also a dispatch hazard, then we don't check if
200 // it is reserved because that check would always return true.
201 // A resource marked as "dispatch hazard" is always reserved at
202 // dispatch time. When this method is called, the assumption is that
203 // the user of this resource has been already dispatched.
204 bool isReady(unsigned NumUnits = 1) const {
205 return (!isReserved() || isADispatchHazard()) &&
206 llvm::countPopulation(ReadyMask) >= NumUnits;
207 }
208 bool isAResourceGroup() const {
209 return llvm::countPopulation(ResourceMask) > 1;
210 }
211
212 bool containsResource(uint64_t ID) const { return ResourceMask & ID; }
213
214 void markSubResourceAsUsed(uint64_t ID) {
215 assert(isSubResourceReady(ID));
216 ReadyMask ^= ID;
217 }
218
219 void releaseSubResource(uint64_t ID) {
220 assert(!isSubResourceReady(ID));
221 ReadyMask ^= ID;
222 }
223
224 unsigned getNumUnits() const {
225 return isAResourceGroup() ? 1U : llvm::countPopulation(ResourceSizeMask);
226 }
227
228 uint64_t selectNextInSequence();
229 void removeFromNextInSequence(uint64_t ID);
230
231 ResourceStateEvent isBufferAvailable() const {
232 if (isADispatchHazard() && isReserved())
233 return RS_RESERVED;
234 if (!isBuffered() || AvailableSlots)
235 return RS_BUFFER_AVAILABLE;
236 return RS_BUFFER_UNAVAILABLE;
237 }
238
239 void reserveBuffer() {
240 if (AvailableSlots)
241 AvailableSlots--;
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000242 }
243
244 void releaseBuffer() {
245 if (BufferSize > 0)
246 AvailableSlots++;
247 assert(AvailableSlots <= static_cast<unsigned>(BufferSize));
248 }
249
250#ifndef NDEBUG
251 void dump() const;
252#endif
253};
254
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000255/// A resource unit identifier.
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000256///
257/// This is used to identify a specific processor resource unit using a pair
258/// of indices where the 'first' index is a processor resource mask, and the
259/// 'second' index is an index for a "sub-resource" (i.e. unit).
260typedef std::pair<uint64_t, uint64_t> ResourceRef;
261
Andrea Di Biagio0c541292018-03-10 16:55:07 +0000262// First: a MCProcResourceDesc index identifying a buffered resource.
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000263// Second: max number of buffer entries used in this resource.
Andrea Di Biagio0c541292018-03-10 16:55:07 +0000264typedef std::pair<unsigned, unsigned> BufferUsageEntry;
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000265
266/// A resource manager for processor resource units and groups.
267///
268/// This class owns all the ResourceState objects, and it is responsible for
269/// acting on requests from a Scheduler by updating the internal state of
270/// ResourceState objects.
271/// This class doesn't know about instruction itineraries and functional units.
272/// In future, it can be extended to support itineraries too through the same
273/// public interface.
274class ResourceManager {
275 // The resource manager owns all the ResourceState.
276 using UniqueResourceState = std::unique_ptr<ResourceState>;
Andrea Di Biagioc2619a22018-08-02 11:12:35 +0000277 std::vector<UniqueResourceState> Resources;
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000278
279 // Keeps track of which resources are busy, and how many cycles are left
280 // before those become usable again.
281 llvm::SmallDenseMap<ResourceRef, unsigned> BusyResources;
282
283 // A table to map processor resource IDs to processor resource masks.
284 llvm::SmallVector<uint64_t, 8> ProcResID2Mask;
285
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000286 // Populate resource descriptors.
Andrea Di Biagio4704f032018-03-20 12:25:54 +0000287 void initialize(const llvm::MCSchedModel &SM);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000288
289 // Returns the actual resource unit that will be used.
290 ResourceRef selectPipe(uint64_t ResourceID);
291
Andrea Di Biagioc2619a22018-08-02 11:12:35 +0000292 void use(const ResourceRef &RR);
293 void release(const ResourceRef &RR);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000294
Andrea Di Biagioc2619a22018-08-02 11:12:35 +0000295 unsigned getNumUnits(uint64_t ResourceID) const;
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000296
297public:
Andrea Di Biagio4704f032018-03-20 12:25:54 +0000298 ResourceManager(const llvm::MCSchedModel &SM)
299 : ProcResID2Mask(SM.getNumProcResourceKinds()) {
300 initialize(SM);
301 }
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000302
Andrea Di Biagio44bfcd22018-03-19 19:09:38 +0000303 // Returns RS_BUFFER_AVAILABLE if buffered resources are not reserved, and if
304 // there are enough available slots in the buffers.
Andrea Di Biagioa3f2e482018-03-20 18:20:39 +0000305 ResourceStateEvent canBeDispatched(llvm::ArrayRef<uint64_t> Buffers) const;
306
307 // Return the processor resource identifier associated to this Mask.
Andrea Di Biagioc2619a22018-08-02 11:12:35 +0000308 unsigned resolveResourceMask(uint64_t Mask) const;
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000309
Andrea Di Biagio44bfcd22018-03-19 19:09:38 +0000310 // Consume a slot in every buffered resource from array 'Buffers'. Resource
311 // units that are dispatch hazards (i.e. BufferSize=0) are marked as reserved.
Andrea Di Biagio847accd2018-03-20 19:06:34 +0000312 void reserveBuffers(llvm::ArrayRef<uint64_t> Buffers);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000313
Andrea Di Biagio44bfcd22018-03-19 19:09:38 +0000314 // Release buffer entries previously allocated by method reserveBuffers.
Andrea Di Biagio847accd2018-03-20 19:06:34 +0000315 void releaseBuffers(llvm::ArrayRef<uint64_t> Buffers);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000316
Andrea Di Biagioc2619a22018-08-02 11:12:35 +0000317 // Reserve a processor resource. A reserved resource is not available for
318 // instruction issue until it is released.
319 void reserveResource(uint64_t ResourceID);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000320
Andrea Di Biagioc2619a22018-08-02 11:12:35 +0000321 // Release a previously reserved processor resource.
322 void releaseResource(uint64_t ResourceID);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000323
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000324 // Returns true if all resources are in-order, and there is at least one
325 // resource which is a dispatch hazard (BufferSize = 0).
326 bool mustIssueImmediately(const InstrDesc &Desc);
327
328 bool canBeIssued(const InstrDesc &Desc) const;
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000329
330 void issueInstruction(
Matt Davisad78e662018-04-26 22:30:40 +0000331 const InstrDesc &Desc,
Andrea Di Biagio51dba7d2018-03-23 17:36:07 +0000332 llvm::SmallVectorImpl<std::pair<ResourceRef, double>> &Pipes);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000333
334 void cycleEvent(llvm::SmallVectorImpl<ResourceRef> &ResourcesFreed);
335
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000336#ifndef NDEBUG
337 void dump() const {
Andrea Di Biagioc2619a22018-08-02 11:12:35 +0000338 for (const UniqueResourceState &Resource : Resources)
339 Resource->dump();
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000340 }
341#endif
342}; // namespace mca
343
344/// Class Scheduler is responsible for issuing instructions to pipeline
Andrea Di Biagio1c3bcc62018-08-03 12:55:28 +0000345/// resources.
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000346///
Andrea Di Biagio1c3bcc62018-08-03 12:55:28 +0000347/// Internally, it delegates to a ResourceManager the management of processor
348/// resources. This class is also responsible for tracking the progress of
349/// instructions from the dispatch stage, until the write-back stage.
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000350///
Andrea Di Biagio1c3bcc62018-08-03 12:55:28 +0000351/// An instruction dispatched to the Scheduler is initially placed into either
352/// the 'WaitSet' or the 'ReadySet' depending on the availability of the input
353/// operands.
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000354///
Andrea Di Biagio1c3bcc62018-08-03 12:55:28 +0000355/// An instruction is moved from the WaitSet to the ReadySet when register
356/// operands become available, and all memory dependencies are met.
357/// Instructions that are moved from the WaitSet to the ReadySet transition
358/// in state from 'IS_AVAILABLE' to 'IS_READY'.
359///
360/// On every cycle, the Scheduler checks if it can promote instructions from the
361/// WaitSet to the ReadySet.
362///
363/// An Instruction is moved from the ReadySet the `IssuedSet` when it is issued
364/// to a (one or more) pipeline(s). This event also causes an instruction state
365/// transition (i.e. from state IS_READY, to state IS_EXECUTING). An Instruction
366/// leaves the IssuedSet when it reaches the write-back stage.
Matt Davis362ea5f2018-07-06 18:03:14 +0000367class Scheduler : public HardwareUnit {
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000368 const llvm::MCSchedModel &SM;
369
370 // Hardware resources that are managed by this scheduler.
371 std::unique_ptr<ResourceManager> Resources;
372 std::unique_ptr<LSUnit> LSU;
373
Andrea Di Biagio1c3bcc62018-08-03 12:55:28 +0000374 std::vector<InstRef> WaitSet;
375 std::vector<InstRef> ReadySet;
376 std::vector<InstRef> IssuedSet;
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000377
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000378 /// Issue an instruction without updating the ready queue.
Andrea Di Biagio27c4b092018-04-24 14:53:16 +0000379 void issueInstructionImpl(
Matt Davis21a8d322018-05-07 18:29:15 +0000380 InstRef &IR,
Andrea Di Biagio27c4b092018-04-24 14:53:16 +0000381 llvm::SmallVectorImpl<std::pair<ResourceRef, double>> &Pipes);
382
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000383public:
Matt Davis488ac4c2018-06-14 01:20:18 +0000384 Scheduler(const llvm::MCSchedModel &Model, unsigned LoadQueueSize,
385 unsigned StoreQueueSize, bool AssumeNoAlias)
386 : SM(Model), Resources(llvm::make_unique<ResourceManager>(SM)),
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000387 LSU(llvm::make_unique<LSUnit>(LoadQueueSize, StoreQueueSize,
Matt Davis488ac4c2018-06-14 01:20:18 +0000388 AssumeNoAlias)) {}
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000389
Matt Davis21a8d322018-05-07 18:29:15 +0000390 /// Check if the instruction in 'IR' can be dispatched.
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000391 ///
Matt Davis679083e2018-05-17 19:22:29 +0000392 /// The DispatchStage is responsible for querying the Scheduler before
Matt Davis488ac4c2018-06-14 01:20:18 +0000393 /// dispatching new instructions. This routine is used for performing such
394 /// a query. If the instruction 'IR' can be dispatched, then true is
395 /// returned, otherwise false is returned with Event set to the stall type.
396 bool canBeDispatched(const InstRef &IR,
397 HWStallEvent::GenericEventType &Event) const;
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000398
Matt Davis488ac4c2018-06-14 01:20:18 +0000399 /// Returns true if there is availibility for IR in the LSU.
400 bool isReady(const InstRef &IR) const { return LSU->isReady(IR); }
401
402 /// Issue an instruction. The Used container is populated with
403 /// the resource objects consumed on behalf of issuing this instruction.
404 void
405 issueInstruction(InstRef &IR,
406 llvm::SmallVectorImpl<std::pair<ResourceRef, double>> &Used);
407
408 /// This routine will attempt to issue an instruction immediately (for
409 /// zero-latency instructions).
410 ///
411 /// Returns true if the instruction is issued immediately. If this does not
Andrea Di Biagio1c3bcc62018-08-03 12:55:28 +0000412 /// occur, then the instruction will be added to the Scheduler's ReadySet.
Matt Davis488ac4c2018-06-14 01:20:18 +0000413 bool issueImmediately(InstRef &IR);
Andrea Di Biagio27c4b092018-04-24 14:53:16 +0000414
415 /// Reserve one entry in each buffered resource.
416 void reserveBuffers(llvm::ArrayRef<uint64_t> Buffers) {
417 Resources->reserveBuffers(Buffers);
418 }
419
420 /// Release buffer entries previously allocated by method reserveBuffers.
421 void releaseBuffers(llvm::ArrayRef<uint64_t> Buffers) {
422 Resources->releaseBuffers(Buffers);
423 }
424
Matt Davis488ac4c2018-06-14 01:20:18 +0000425 /// Update the resources managed by the scheduler.
426 /// This routine is to be called at the start of a new cycle, and is
427 /// responsible for updating scheduler resources. Resources are released
428 /// once they have been fully consumed.
429 void reclaimSimulatedResources(llvm::SmallVectorImpl<ResourceRef> &Freed);
430
Andrea Di Biagio1c3bcc62018-08-03 12:55:28 +0000431 /// Move instructions from the WaitSet to the ReadySet if input operands
Matt Davis488ac4c2018-06-14 01:20:18 +0000432 /// are all available.
Andrea Di Biagio1c3bcc62018-08-03 12:55:28 +0000433 void promoteToReadySet(llvm::SmallVectorImpl<InstRef> &Ready);
Matt Davis488ac4c2018-06-14 01:20:18 +0000434
435 /// Update the ready queue.
436 void updatePendingQueue(llvm::SmallVectorImpl<InstRef> &Ready);
437
438 /// Update the issued queue.
Andrea Di Biagio1c3bcc62018-08-03 12:55:28 +0000439 void updateIssuedSet(llvm::SmallVectorImpl<InstRef> &Executed);
Matt Davis488ac4c2018-06-14 01:20:18 +0000440
441 /// Updates the Scheduler's resources to reflect that an instruction has just
442 /// been executed.
443 void onInstructionExecuted(const InstRef &IR);
444
445 /// Obtain the processor's resource identifier for the given
446 /// resource mask.
447 unsigned getResourceID(uint64_t Mask) {
448 return Resources->resolveResourceMask(Mask);
449 }
450
451 /// Reserve resources necessary to issue the instruction.
452 /// Returns true if the resources are ready and the (LSU) can
453 /// execute the given instruction immediately.
454 bool reserveResources(InstRef &IR);
455
Andrea Di Biagio1c3bcc62018-08-03 12:55:28 +0000456 /// Select the next instruction to issue from the ReadySet.
Matt Davis488ac4c2018-06-14 01:20:18 +0000457 /// This method gives priority to older instructions.
458 InstRef select();
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000459
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000460#ifndef NDEBUG
Matt Davis488ac4c2018-06-14 01:20:18 +0000461 // Update the ready queues.
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000462 void dump() const;
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000463
Matt Davis488ac4c2018-06-14 01:20:18 +0000464 // This routine performs a sanity check. This routine should only be called
465 // when we know that 'IR' is not in the scheduler's instruction queues.
466 void sanityCheck(const InstRef &IR) const {
Andrea Di Biagio1c3bcc62018-08-03 12:55:28 +0000467 assert(llvm::find(WaitSet, IR) == WaitSet.end());
468 assert(llvm::find(ReadySet, IR) == ReadySet.end());
469 assert(llvm::find(IssuedSet, IR) == IssuedSet.end());
Matt Davis488ac4c2018-06-14 01:20:18 +0000470 }
471#endif // !NDEBUG
472};
473} // namespace mca
474
475#endif // LLVM_TOOLS_LLVM_MCA_SCHEDULER_H