mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
[llvm-mca] Let the Scheduler notify dispatch stall events caused by the lack of scheduling resources.
This patch moves part of the logic that notifies dispatch stall events from the DispatchUnit to the Scheduler. The main goal of this patch is to remove (yet another) dependency between the DispatchUnit and the Scheduler. Before this patch, the DispatchUnit had to know about `Scheduler::Event` and how to classify stalls due to the lack of scheduling resources. This patch removes that knowledge and simplifies the logic in DispatchUnit::checkScheduler. This is another change done in preparation for the work to fix PR36663. No functional change intended. llvm-svn: 329835
This commit is contained in:
parent
ac46827cba
commit
aa4e3e3fd7
@ -362,27 +362,7 @@ bool DispatchUnit::checkRCU(unsigned Index, const InstrDesc &Desc) {
|
||||
}
|
||||
|
||||
bool DispatchUnit::checkScheduler(unsigned Index, const InstrDesc &Desc) {
|
||||
// If this is a zero-latency instruction, then it bypasses
|
||||
// the scheduler.
|
||||
HWStallEvent::GenericEventType Type = HWStallEvent::Invalid;
|
||||
switch (SC->canBeDispatched(Desc)) {
|
||||
case Scheduler::HWS_AVAILABLE:
|
||||
return true;
|
||||
case Scheduler::HWS_QUEUE_UNAVAILABLE:
|
||||
Type = HWStallEvent::SchedulerQueueFull;
|
||||
break;
|
||||
case Scheduler::HWS_LD_QUEUE_UNAVAILABLE:
|
||||
Type = HWStallEvent::LoadQueueFull;
|
||||
break;
|
||||
case Scheduler::HWS_ST_QUEUE_UNAVAILABLE:
|
||||
Type = HWStallEvent::StoreQueueFull;
|
||||
break;
|
||||
case Scheduler::HWS_DISPATCH_GROUP_RESTRICTION:
|
||||
Type = HWStallEvent::DispatchGroupStall;
|
||||
}
|
||||
|
||||
Owner->notifyStallEvent(HWStallEvent(Type, Index));
|
||||
return false;
|
||||
return SC->canBeDispatched(Index, Desc);
|
||||
}
|
||||
|
||||
void DispatchUnit::updateRAWDependencies(ReadState &RS,
|
||||
|
@ -97,6 +97,7 @@ public:
|
||||
// Generic stall events generated by the DispatchUnit.
|
||||
RegisterFileStall,
|
||||
RetireControlUnitStall,
|
||||
// Generic stall events generated by the Scheduler.
|
||||
DispatchGroupStall,
|
||||
SchedulerQueueFull,
|
||||
LoadQueueFull,
|
||||
|
@ -308,24 +308,26 @@ void Scheduler::dump() const {
|
||||
}
|
||||
#endif
|
||||
|
||||
Scheduler::Event Scheduler::canBeDispatched(const InstrDesc &Desc) const {
|
||||
if (Desc.MayLoad && LSU->isLQFull())
|
||||
return HWS_LD_QUEUE_UNAVAILABLE;
|
||||
if (Desc.MayStore && LSU->isSQFull())
|
||||
return HWS_ST_QUEUE_UNAVAILABLE;
|
||||
bool Scheduler::canBeDispatched(unsigned Index, const InstrDesc &Desc) const {
|
||||
HWStallEvent::GenericEventType Type = HWStallEvent::Invalid;
|
||||
|
||||
Scheduler::Event Event;
|
||||
switch (Resources->canBeDispatched(Desc.Buffers)) {
|
||||
case ResourceStateEvent::RS_BUFFER_AVAILABLE:
|
||||
Event = HWS_AVAILABLE;
|
||||
break;
|
||||
case ResourceStateEvent::RS_BUFFER_UNAVAILABLE:
|
||||
Event = HWS_QUEUE_UNAVAILABLE;
|
||||
break;
|
||||
case ResourceStateEvent::RS_RESERVED:
|
||||
Event = HWS_DISPATCH_GROUP_RESTRICTION;
|
||||
if (Desc.MayLoad && LSU->isLQFull())
|
||||
Type = HWStallEvent::LoadQueueFull;
|
||||
else if (Desc.MayStore && LSU->isSQFull())
|
||||
Type = HWStallEvent::StoreQueueFull;
|
||||
else {
|
||||
switch (Resources->canBeDispatched(Desc.Buffers)) {
|
||||
default: return true;
|
||||
case ResourceStateEvent::RS_BUFFER_UNAVAILABLE:
|
||||
Type = HWStallEvent::SchedulerQueueFull;
|
||||
break;
|
||||
case ResourceStateEvent::RS_RESERVED:
|
||||
Type = HWStallEvent::DispatchGroupStall;
|
||||
}
|
||||
}
|
||||
return Event;
|
||||
|
||||
Owner->notifyStallEvent(HWStallEvent(Type, Index));
|
||||
return false;
|
||||
}
|
||||
|
||||
void Scheduler::issueInstruction(Instruction &IS, unsigned InstrIndex) {
|
||||
|
@ -454,42 +454,14 @@ public:
|
||||
|
||||
void setDispatchUnit(DispatchUnit *DispUnit) { DU = DispUnit; }
|
||||
|
||||
/// Scheduling events.
|
||||
/// Check if instruction at index Idx can be dispatched.
|
||||
///
|
||||
/// The DispatchUnit is responsible for querying the Scheduler before
|
||||
/// dispatching new instructions. Queries are performed through method
|
||||
/// `Scheduler::CanBeDispatched`, which returns an instance of this enum to
|
||||
/// tell if the dispatch would fail or not. If scheduling resources are
|
||||
/// available, and the instruction can be dispatched, then the query returns
|
||||
/// HWS_AVAILABLE. A values different than HWS_AVAILABLE means that the
|
||||
/// instruction cannot be dispatched during this cycle.
|
||||
///
|
||||
/// Each event name starts with prefix "HWS_", and it is followed by
|
||||
/// a substring which describes the reason why the Scheduler was unavailable
|
||||
/// (or "AVAILABLE" if the instruction is allowed to be dispatched).
|
||||
///
|
||||
/// HWS_QUEUE_UNAVAILABLE is returned if there are not enough available slots
|
||||
/// in the scheduler's queue. That means, one (or more) buffered resources
|
||||
/// consumed by the instruction were full.
|
||||
///
|
||||
/// HWS_LD_QUEUE_UNAVAILABLE is returned when an instruction 'mayLoad', and
|
||||
/// the load queue in the load/store unit (implemented by class LSUnit) is
|
||||
/// full. Similarly, HWS_ST_QUEUE_UNAVAILABLE is returned when the store
|
||||
/// queue is full, and the instruction to be dispatched 'mayStore'.
|
||||
///
|
||||
/// HWS_DISPATCH_GROUP_RESTRICTION is only returned in special cases where the
|
||||
/// instruction consumes an in-order issue/dispatch resource (i.e. a resource
|
||||
/// with `BufferSize=0`), and the pipeline resource is not immediately
|
||||
/// available.
|
||||
enum Event {
|
||||
HWS_AVAILABLE,
|
||||
HWS_QUEUE_UNAVAILABLE,
|
||||
HWS_DISPATCH_GROUP_RESTRICTION,
|
||||
HWS_LD_QUEUE_UNAVAILABLE,
|
||||
HWS_ST_QUEUE_UNAVAILABLE
|
||||
};
|
||||
|
||||
Event canBeDispatched(const InstrDesc &Desc) const;
|
||||
/// `Scheduler::CanBeDispatched`. If scheduling resources are available,
|
||||
/// and the instruction can be dispatched, then this method returns true.
|
||||
/// Otherwise, a generic HWStallEvent is notified to the listeners.
|
||||
bool canBeDispatched(unsigned Idx, const InstrDesc &Desc) const;
|
||||
void scheduleInstruction(unsigned Idx, Instruction &MCIS);
|
||||
|
||||
void cycleEvent(unsigned Cycle);
|
||||
|
Loading…
Reference in New Issue
Block a user