[llvm] r362302 - [MCA][Scheduler] Change how memory instructions are dispatched to the pending set. NFCI

Andrea Di Biagio via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 1 08:22:38 PDT 2019


Author: adibiagio
Date: Sat Jun  1 08:22:37 2019
New Revision: 362302

URL: http://llvm.org/viewvc/llvm-project?rev=362302&view=rev
Log:
[MCA][Scheduler] Change how memory instructions are dispatched to the pending set. NFCI

Modified:
    llvm/trunk/include/llvm/MCA/HardwareUnits/LSUnit.h
    llvm/trunk/lib/MCA/HardwareUnits/Scheduler.cpp

Modified: llvm/trunk/include/llvm/MCA/HardwareUnits/LSUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MCA/HardwareUnits/LSUnit.h?rev=362302&r1=362301&r2=362302&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MCA/HardwareUnits/LSUnit.h (original)
+++ llvm/trunk/include/llvm/MCA/HardwareUnits/LSUnit.h Sat Jun  1 08:22:37 2019
@@ -70,7 +70,7 @@ public:
   unsigned getNumExecuting() const { return NumExecuting; }
   unsigned getNumExecuted() const { return NumExecuted; }
 
-  const InstRef &getCriticalMemoryInstruction() const { 
+  const InstRef &getCriticalMemoryInstruction() const {
     return CriticalMemoryInstruction;
   }
   const CriticalDependency &getCriticalPredecessor() const {
@@ -96,7 +96,7 @@ public:
   }
   bool isReady() const { return NumExecutedPredecessors == NumPredecessors; }
   bool isExecuting() const {
-    return NumExecuting == NumInstructions - NumExecuted;
+    return NumExecuting && (NumExecuting == (NumInstructions - NumExecuted));
   }
   bool isExecuted() const { return NumInstructions == NumExecuted; }
 
@@ -247,22 +247,32 @@ public:
   /// Check if a peviously dispatched instruction IR is now ready for execution.
   bool isReady(const InstRef &IR) const {
     unsigned GroupID = IR.getInstruction()->getLSUTokenID();
-    assert(isValidGroupID(GroupID) &&
-           "Invalid group associated with this instruction!");
-    const MemoryGroup &Group = *Groups.find(GroupID)->second;
+    const MemoryGroup &Group = getGroup(GroupID);
     return Group.isReady();
   }
 
-  /// Check if a previously dispatched instruction IR only depends on
-  /// instructions that are currently executing.
+  /// Check if instruction IR only depends on memory instructions that are
+  /// currently executing.
   bool isPending(const InstRef &IR) const {
     unsigned GroupID = IR.getInstruction()->getLSUTokenID();
-    assert(isValidGroupID(GroupID) &&
-           "Invalid group associated with this instruction!");
-    const MemoryGroup &Group = *Groups.find(GroupID)->second;
+    const MemoryGroup &Group = getGroup(GroupID);
     return Group.isPending();
   }
 
+  /// Check if instruction IR is still waiting on memory operations, and the
+  /// wait time is still unknown.
+  bool isWaiting(const InstRef &IR) const {
+    unsigned GroupID = IR.getInstruction()->getLSUTokenID();
+    const MemoryGroup &Group = getGroup(GroupID);
+    return Group.isWaiting();
+  }
+
+  bool hasDependentUsers(const InstRef &IR) const {
+    unsigned GroupID = IR.getInstruction()->getLSUTokenID();
+    const MemoryGroup &Group = getGroup(GroupID);
+    return !Group.isExecuted() && Group.getNumSuccessors();
+  }
+
   const MemoryGroup &getGroup(unsigned Index) const {
     assert(isValidGroupID(Index) && "Group doesn't exist!");
     return *Groups.find(Index)->second;
@@ -274,7 +284,8 @@ public:
   }
 
   unsigned createMemoryGroup() {
-    Groups.insert(std::make_pair(NextGroupID, llvm::make_unique<MemoryGroup>()));
+    Groups.insert(
+        std::make_pair(NextGroupID, llvm::make_unique<MemoryGroup>()));
     return NextGroupID++;
   }
 

Modified: llvm/trunk/lib/MCA/HardwareUnits/Scheduler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MCA/HardwareUnits/Scheduler.cpp?rev=362302&r1=362301&r2=362302&view=diff
==============================================================================
--- llvm/trunk/lib/MCA/HardwareUnits/Scheduler.cpp (original)
+++ llvm/trunk/lib/MCA/HardwareUnits/Scheduler.cpp Sat Jun  1 08:22:37 2019
@@ -104,6 +104,7 @@ void Scheduler::issueInstruction(
     SmallVectorImpl<InstRef> &ReadyInstructions) {
   const Instruction &Inst = *IR.getInstruction();
   bool HasDependentUsers = Inst.hasDependentUsers();
+  HasDependentUsers |= Inst.isMemOp() && LSU.hasDependentUsers(IR);
 
   Resources->releaseBuffers(Inst.getDesc().Buffers);
   issueInstructionImpl(IR, UsedResources);
@@ -111,14 +112,9 @@ void Scheduler::issueInstruction(
   // other dependent instructions. Dependent instructions may be issued during
   // this same cycle if operands have ReadAdvance entries.  Promote those
   // instructions to the ReadySet and notify the caller that those are ready.
-  // If IR is a memory operation, then always call method `promoteToReadySet()`
-  // to notify any dependent memory operations that IR started execution.
-  bool ShouldPromoteInstructions = Inst.isMemOp();
   if (HasDependentUsers)
-    ShouldPromoteInstructions |= promoteToPendingSet(PendingInstructions);
-
-  if (ShouldPromoteInstructions)
-    promoteToReadySet(ReadyInstructions);
+    if (promoteToPendingSet(PendingInstructions))
+      promoteToReadySet(ReadyInstructions);
 }
 
 bool Scheduler::promoteToReadySet(SmallVectorImpl<InstRef> &Ready) {
@@ -130,18 +126,18 @@ bool Scheduler::promoteToReadySet(SmallV
     if (!IR)
       break;
 
-    // Check if there are unsolved memory dependencies.
+    // Check if there are unsolved register dependencies.
     Instruction &IS = *IR.getInstruction();
-    if (IS.isMemOp() && !LSU.isReady(IR)) {
+    if (!IS.isReady() && !IS.updatePending()) {
       ++I;
       continue;
     }
-
-    // Check if there are unsolved register dependencies.
-    if (!IS.isReady() && !IS.updatePending()) {
+    // Check if there are unsolved memory dependencies.
+    if (IS.isMemOp() && !LSU.isReady(IR)) {
       ++I;
       continue;
     }
+
     LLVM_DEBUG(dbgs() << "[SCHEDULER]: Instruction #" << IR
                       << " promoted to the READY set.\n");
 
@@ -173,6 +169,12 @@ bool Scheduler::promoteToPendingSet(Smal
       ++I;
       continue;
     }
+
+    if (IS.isMemOp() && LSU.isWaiting(IR)) {
+      ++I;
+      continue;
+    }
+
     LLVM_DEBUG(dbgs() << "[SCHEDULER]: Instruction #" << IR
                       << " promoted to the PENDING set.\n");
 
@@ -251,13 +253,8 @@ void Scheduler::analyzeDataDependencies(
     if (Resources->checkAvailability(IS.getDesc()))
       continue;
 
-    if (IS.isMemOp()) {
-      const MemoryGroup &Group = LSU.getGroup(IS.getLSUTokenID());
-      if (Group.isWaiting())
-        continue;
-      if (Group.isPending())
-        MemDeps.emplace_back(IR);
-    }
+    if (IS.isMemOp() && LSU.isPending(IR))
+      MemDeps.emplace_back(IR);
 
     if (IS.isPending())
       RegDeps.emplace_back(IR);
@@ -309,7 +306,13 @@ bool Scheduler::dispatch(InstRef &IR) {
   if (IS.isMemOp())
     IS.setLSUTokenID(LSU.dispatch(IR));
 
-  if (IS.isPending()) {
+  if (IS.isDispatched() || (IS.isMemOp() && LSU.isWaiting(IR))) {
+    LLVM_DEBUG(dbgs() << "[SCHEDULER] Adding #" << IR << " to the WaitSet\n");
+    WaitSet.push_back(IR);
+    return false;
+  }
+
+  if (IS.isPending() || (IS.isMemOp() && LSU.isPending(IR))) {
     LLVM_DEBUG(dbgs() << "[SCHEDULER] Adding #" << IR
                       << " to the PendingSet\n");
     PendingSet.push_back(IR);
@@ -317,14 +320,8 @@ bool Scheduler::dispatch(InstRef &IR) {
     return false;
   }
 
-  // Memory operations that still have unsolved memory dependencies are
-  // initially dispatched to the WaitSet.
-  if (!IS.isReady() || (IS.isMemOp() && !LSU.isReady(IR))) {
-    LLVM_DEBUG(dbgs() << "[SCHEDULER] Adding #" << IR << " to the WaitSet\n");
-    WaitSet.push_back(IR);
-    return false;
-  }
-
+  assert(IS.isReady() && (!IS.isMemOp() || LSU.isReady(IR)) &&
+         "Unexpected internal state found!");
   // Don't add a zero-latency instruction to the Ready queue.
   // A zero-latency instruction doesn't consume any scheduler resources. That is
   // because it doesn't need to be executed, and it is often removed at register




More information about the llvm-commits mailing list