Go to the documentation of this file.
20 #define DEBUG_TYPE "llvm-mca"
22 void 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());
70 void Scheduler::issueInstructionImpl(
72 SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &UsedResources) {
78 Resources->issueInstruction(
D, UsedResources);
93 IssuedSet.emplace_back(
IR);
101 SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &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;
155 bool 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;
291 const InstrDesc &Desc =
IR.getInstruction()->getDesc();
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);
bool isPending(const InstRef &IR) const
Check if instruction IR only depends on memory instructions that are currently executing.
bool isZeroLatency() const
bool dispatch(InstRef &IR)
Reserves buffer and LSUnit queue resources that are necessary to issue this instruction.
unsigned MustIssueImmediately
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 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 hasDependentUsers(const InstRef &IR) const
bool isWaiting(const InstRef &IR) const
Check if instruction IR is still waiting on memory operations, and the wait time is still unknown.
void setCriticalResourceMask(uint64_t ResourceMask)
unsigned getLSUTokenID() const
virtual Status isAvailable(const InstRef &IR) const =0
This method checks the availability of the load/store buffers.
An instruction propagated through the simulated instruction pipeline.
const MemoryGroup & getGroup(unsigned Index) const
const CriticalDependency & getCriticalPredecessor() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool hasDependentUsers() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void execute(unsigned IID)
virtual void onInstructionExecuted(const InstRef &IR)
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...
Statically lint checks LLVM IR
A node of a memory dependency graph.
const InstrDesc & getDesc() const
An instruction descriptor.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
An InstRef contains both a SourceMgr index and Instruction pair.
void issueInstruction(InstRef &IR, SmallVectorImpl< std::pair< ResourceRef, ResourceCycles >> &Used, SmallVectorImpl< InstRef > &Pending, SmallVectorImpl< InstRef > &Ready)
Issue an instruction and populates a vector of used pipeline resources, and a vector of instructions ...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
virtual unsigned dispatch(const InstRef &IR)=0
Allocates LS resources for instruction IR.
virtual void onInstructionIssued(const InstRef &IR)
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
@ SC_DISPATCH_GROUP_STALL
Status isAvailable(const InstRef &IR)
Check if the instruction in 'IR' can be dispatched during this cycle.
InstRef select()
Select the next instruction to issue from the ReadySet.
bool isReady(const InstRef &IR) const
Check if a peviously dispatched instruction IR is now ready for execution.
void setCriticalMemDep(const CriticalDependency &MemDep)
uint64_t getUsedBuffers() const
virtual ~DefaultSchedulerStrategy()
bool isDispatched() const
virtual ~SchedulerStrategy()
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
virtual void cycleEvent()
const CriticalDependency & computeCriticalRegDep()
ResourceStateEvent
Used to notify the internal state of a processor resource.
void setLSUTokenID(unsigned LSUTok)
reference emplace_back(ArgTypes &&... Args)
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.