20#define DEBUG_TYPE "llvm-mca"
22void Scheduler::initializeStrategy(std::unique_ptr<SchedulerStrategy> S) {
24 Strategy = S ? std::move(S) : std::make_unique<DefaultSchedulerStrategy>();
33 dbgs() <<
"[SCHEDULER]: WaitSet size is: " << WaitSet.size() <<
'\n';
34 dbgs() <<
"[SCHEDULER]: ReadySet size is: " << ReadySet.size() <<
'\n';
35 dbgs() <<
"[SCHEDULER]: IssuedSet size is: " << IssuedSet.size() <<
'\n';
42 Resources->canBeDispatched(
IR.getInstruction()->getUsedBuffers());
70void Scheduler::issueInstructionImpl(
72 SmallVectorImpl<std::pair<ResourceRef, ReleaseAtCycles>> &UsedResources) {
78 Resources->issueInstruction(
D, UsedResources);
93 IssuedSet.emplace_back(
IR);
101 SmallVectorImpl<std::pair<ResourceRef, ReleaseAtCycles>> &UsedResources,
109 issueInstructionImpl(
IR, UsedResources);
114 if (HasDependentUsers)
115 if (promoteToPendingSet(PendingInstructions))
116 promoteToReadySet(ReadyInstructions);
122 unsigned PromotedElements = 0;
123 for (
auto I = PendingSet.begin(),
E = PendingSet.end();
I !=
E;) {
141 <<
" promoted to the READY set.\n");
143 Ready.emplace_back(
IR);
144 ReadySet.emplace_back(
IR);
148 std::iter_swap(
I,
E - PromotedElements);
151 PendingSet.resize(PendingSet.size() - PromotedElements);
152 return PromotedElements;
155bool Scheduler::promoteToPendingSet(SmallVectorImpl<InstRef> &Pending) {
158 unsigned RemovedElements = 0;
159 for (
auto I = WaitSet.begin(),
E = WaitSet.end();
I !=
E;) {
166 Instruction &IS = *
IR.getInstruction();
167 if (IS.isDispatched() && !IS.updateDispatched()) {
178 <<
" promoted to the PENDING set.\n");
180 Pending.emplace_back(
IR);
181 PendingSet.emplace_back(
IR);
185 std::iter_swap(
I,
E - RemovedElements);
188 WaitSet.resize(WaitSet.size() - RemovedElements);
189 return RemovedElements;
193 unsigned QueueIndex = ReadySet.size();
194 for (
unsigned I = 0,
E = ReadySet.size();
I !=
E; ++
I) {
196 if (QueueIndex == ReadySet.size() ||
197 Strategy->compare(
IR, ReadySet[QueueIndex])) {
199 uint64_t BusyResourceMask = Resources->checkAvailability(IS.
getDesc());
200 if (BusyResourceMask)
202 BusyResourceUnits |= BusyResourceMask;
203 if (!BusyResourceMask)
208 if (QueueIndex == ReadySet.size())
213 std::swap(ReadySet[QueueIndex], ReadySet[ReadySet.size() - 1]);
219 unsigned RemovedElements = 0;
220 for (
auto I = IssuedSet.begin(),
E = IssuedSet.end();
I !=
E;) {
227 <<
" is still executing.\n");
237 std::iter_swap(
I,
E - RemovedElements);
240 IssuedSet.resize(IssuedSet.size() - RemovedElements);
245 return BusyResourceUnits;
250 const auto EndIt = PendingSet.end() - NumDispatchedToThePendingSet;
253 if (Resources->checkAvailability(IS.
getDesc()))
271 Resources->cycleEvent(Freed);
274 IR.getInstruction()->cycleEvent();
275 updateIssuedSet(Executed);
278 IR.getInstruction()->cycleEvent();
281 IR.getInstruction()->cycleEvent();
283 promoteToPendingSet(Pending);
284 promoteToReadySet(Ready);
286 NumDispatchedToThePendingSet = 0;
287 BusyResourceUnits = 0;
292 if (
Desc.isZeroLatency())
297 return Desc.MustIssueImmediately;
310 WaitSet.push_back(
IR);
316 <<
" to the PendingSet\n");
317 PendingSet.push_back(
IR);
318 ++NumDispatchedToThePendingSet;
323 "Unexpected internal state found!");
334 ReadySet.push_back(
IR);
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Legalize the Machine IR a function s Machine IR
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A scheduler for Processor Resource Units and Processor Resource Groups.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
virtual ~DefaultSchedulerStrategy()
An InstRef contains both a SourceMgr index and Instruction pair.
const InstrDesc & getDesc() const
bool hasDependentUsers() const
An instruction propagated through the simulated instruction pipeline.
bool isDispatched() const
void setCriticalResourceMask(uint64_t ResourceMask)
const CriticalDependency & computeCriticalRegDep()
void execute(unsigned IID)
void setLSUTokenID(unsigned LSUTok)
void setCriticalMemDep(const CriticalDependency &MemDep)
uint64_t getUsedBuffers() const
unsigned getLSUTokenID() const
virtual unsigned dispatch(const InstRef &IR)=0
Allocates LS resources for instruction IR.
virtual void onInstructionExecuted(const InstRef &IR)
bool isWaiting(const InstRef &IR) const
Check if instruction IR is still waiting on memory operations, and the wait time is still unknown.
virtual void onInstructionIssued(const InstRef &IR)
const MemoryGroup & getGroup(unsigned Index) const
bool isPending(const InstRef &IR) const
Check if instruction IR only depends on memory instructions that are currently executing.
virtual Status isAvailable(const InstRef &IR) const =0
This method checks the availability of the load/store buffers.
virtual void cycleEvent()
bool hasDependentUsers(const InstRef &IR) const
bool isReady(const InstRef &IR) const
Check if a peviously dispatched instruction IR is now ready for execution.
A node of a memory dependency graph.
const CriticalDependency & getCriticalPredecessor() const
virtual ~SchedulerStrategy()
@ SC_DISPATCH_GROUP_STALL
InstRef select()
Select the next instruction to issue from the ReadySet.
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 ...
Status isAvailable(const InstRef &IR)
Check if the instruction in 'IR' can be dispatched during this cycle.
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 ...
bool dispatch(InstRef &IR)
Reserves buffer and LSUnit queue resources that are necessary to issue this instruction.
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.
bool mustIssueImmediately(const InstRef &IR) const
Returns true if IR has to be issued immediately, or if IR is a zero latency instruction.
uint64_t analyzeResourcePressure(SmallVectorImpl< InstRef > &Insts)
Returns a mask of busy resources, and populates vector Insts with instructions that could not be issu...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ResourceStateEvent
Used to notify the internal state of a processor resource.
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Description of the encoding of one expression Op.
An instruction descriptor.