[llvm] r329835 - [llvm-mca] Let the Scheduler notify dispatch stall events caused by the lack of scheduling resources.

Andrea Di Biagio via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 11 11:05:24 PDT 2018


Author: adibiagio
Date: Wed Apr 11 11:05:23 2018
New Revision: 329835

URL: http://llvm.org/viewvc/llvm-project?rev=329835&view=rev
Log:
[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.

Modified:
    llvm/trunk/tools/llvm-mca/Dispatch.cpp
    llvm/trunk/tools/llvm-mca/HWEventListener.h
    llvm/trunk/tools/llvm-mca/Scheduler.cpp
    llvm/trunk/tools/llvm-mca/Scheduler.h

Modified: llvm/trunk/tools/llvm-mca/Dispatch.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Dispatch.cpp?rev=329835&r1=329834&r2=329835&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/Dispatch.cpp (original)
+++ llvm/trunk/tools/llvm-mca/Dispatch.cpp Wed Apr 11 11:05:23 2018
@@ -362,27 +362,7 @@ bool DispatchUnit::checkRCU(unsigned Ind
 }
 
 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,

Modified: llvm/trunk/tools/llvm-mca/HWEventListener.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/HWEventListener.h?rev=329835&r1=329834&r2=329835&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/HWEventListener.h (original)
+++ llvm/trunk/tools/llvm-mca/HWEventListener.h Wed Apr 11 11:05:23 2018
@@ -97,6 +97,7 @@ public:
     // Generic stall events generated by the DispatchUnit.
     RegisterFileStall,
     RetireControlUnitStall,
+    // Generic stall events generated by the Scheduler.
     DispatchGroupStall,
     SchedulerQueueFull,
     LoadQueueFull,

Modified: llvm/trunk/tools/llvm-mca/Scheduler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Scheduler.cpp?rev=329835&r1=329834&r2=329835&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/Scheduler.cpp (original)
+++ llvm/trunk/tools/llvm-mca/Scheduler.cpp Wed Apr 11 11:05:23 2018
@@ -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) {

Modified: llvm/trunk/tools/llvm-mca/Scheduler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Scheduler.h?rev=329835&r1=329834&r2=329835&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/Scheduler.h (original)
+++ llvm/trunk/tools/llvm-mca/Scheduler.h Wed Apr 11 11:05:23 2018
@@ -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);




More information about the llvm-commits mailing list