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);
94 IssuedSet.emplace_back(
IR);
102 SmallVectorImpl<std::pair<ResourceRef, ReleaseAtCycles>> &UsedResources,
110 issueInstructionImpl(
IR, UsedResources);
115 if (HasDependentUsers)
116 if (promoteToPendingSet(PendingInstructions))
117 promoteToReadySet(ReadyInstructions);
123 unsigned PromotedElements = 0;
124 for (
auto I = PendingSet.begin(),
E = PendingSet.end();
I !=
E;) {
142 <<
" promoted to the READY set.\n");
144 Ready.emplace_back(
IR);
145 ReadySet.emplace_back(
IR);
149 std::iter_swap(
I,
E - PromotedElements);
152 PendingSet.resize(PendingSet.size() - PromotedElements);
153 return PromotedElements;
156bool Scheduler::promoteToPendingSet(SmallVectorImpl<InstRef> &Pending) {
159 unsigned RemovedElements = 0;
160 for (
auto I = WaitSet.begin(),
E = WaitSet.end();
I !=
E;) {
167 Instruction &IS = *
IR.getInstruction();
168 if (IS.isDispatched() && !IS.updateDispatched()) {
179 <<
" promoted to the PENDING set.\n");
181 Pending.emplace_back(
IR);
182 PendingSet.emplace_back(
IR);
186 std::iter_swap(
I,
E - RemovedElements);
189 WaitSet.resize(WaitSet.size() - RemovedElements);
190 return RemovedElements;
194 unsigned QueueIndex = ReadySet.size();
195 for (
unsigned I = 0,
E = ReadySet.size();
I !=
E; ++
I) {
197 if (QueueIndex == ReadySet.size() ||
198 Strategy->compare(
IR, ReadySet[QueueIndex])) {
200 uint64_t BusyResourceMask = Resources->checkAvailability(IS.
getDesc());
201 if (BusyResourceMask)
203 BusyResourceUnits |= BusyResourceMask;
204 if (!BusyResourceMask)
209 if (QueueIndex == ReadySet.size())
214 std::swap(ReadySet[QueueIndex], ReadySet[ReadySet.size() - 1]);
220 unsigned RemovedElements = 0;
221 for (
auto I = IssuedSet.begin(),
E = IssuedSet.end();
I !=
E;) {
228 <<
" is still executing.\n");
238 std::iter_swap(
I,
E - RemovedElements);
241 IssuedSet.resize(IssuedSet.size() - RemovedElements);
246 return BusyResourceUnits;
251 const auto EndIt = PendingSet.end() - NumDispatchedToThePendingSet;
254 if (Resources->checkAvailability(IS.
getDesc()))
272 Resources->cycleEvent(Freed);
275 IR.getInstruction()->cycleEvent();
276 updateIssuedSet(Executed);
279 IR.getInstruction()->cycleEvent();
282 IR.getInstruction()->cycleEvent();
284 promoteToPendingSet(Pending);
285 promoteToReadySet(Ready);
287 NumDispatchedToThePendingSet = 0;
288 BusyResourceUnits = 0;
293 if (
Desc.isZeroLatency())
298 return Desc.MustIssueImmediately;
311 WaitSet.push_back(
IR);
317 <<
" to the PendingSet\n");
318 PendingSet.push_back(
IR);
319 ++NumDispatchedToThePendingSet;
324 "Unexpected internal state found!");
335 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
A scheduler for Processor Resource Units and Processor Resource Groups.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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 bool isReady(const InstRef &IR) const =0
Check if a peviously dispatched instruction IR is now ready for execution.
virtual Status isAvailable(const InstRef &IR) const =0
This method checks the availability of the load/store buffers.
virtual void onInstructionExecuted(const InstRef &IR)=0
virtual void cycleEvent()=0
virtual bool isWaiting(const InstRef &IR) const =0
Check if instruction IR is still waiting on memory operations, and the wait time is still unknown.
virtual const CriticalDependency getCriticalPredecessor(unsigned GroupId)=0
virtual bool isPending(const InstRef &IR) const =0
Check if instruction IR only depends on memory instructions that are currently executing.
virtual bool hasDependentUsers(const InstRef &IR) const =0
virtual void onInstructionIssued(const InstRef &IR)=0
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.
A critical data dependency descriptor.
An instruction descriptor.