[MCA] Moved the logic that updates register dependencies from DispatchStage to Regist...
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Tue, 5 Feb 2019 14:11:41 +0000 (14:11 +0000)
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Tue, 5 Feb 2019 14:11:41 +0000 (14:11 +0000)
DispatchStage should always delegate to an object of class RegisterFile the task
of updating data dependencies.  ReadState and WriteState objects should not be
modified directly by DispatchStage.
This patch also renames stage IS_AVAILABLE to IS_DISPATCHED.

llvm-svn: 353170

llvm/include/llvm/MCA/HardwareUnits/RegisterFile.h
llvm/include/llvm/MCA/HardwareUnits/Scheduler.h
llvm/include/llvm/MCA/Instruction.h
llvm/include/llvm/MCA/Stages/DispatchStage.h
llvm/lib/MCA/HardwareUnits/RegisterFile.cpp
llvm/lib/MCA/Instruction.cpp
llvm/lib/MCA/Stages/DispatchStage.cpp

index e354f4a..3650632 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCSchedule.h"
+#include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/MCA/HardwareUnits/HardwareUnit.h"
 #include "llvm/Support/Error.h"
 
@@ -195,7 +196,7 @@ public:
 
   // Collect writes that are in a data dependency with RS, and update RS
   // internal state.
-  void addRegisterRead(ReadState &RS, SmallVectorImpl<WriteRef> &Writes) const;
+  void addRegisterRead(ReadState &RS, const MCSubtargetInfo &STI) const;
 
   // Removes write \param WS from the register mappings.
   // Physical registers may be released to reflect this update.
index 5f05141..ae09aef 100644 (file)
@@ -74,7 +74,7 @@ public:
 /// An instruction is moved from the WaitSet to the ReadySet when register
 /// operands become available, and all memory dependencies are met.
 /// Instructions that are moved from the WaitSet to the ReadySet transition
-/// in state from 'IS_AVAILABLE' to 'IS_READY'.
+/// in state from 'IS_DISPATCHED' to 'IS_READY'.
 ///
 /// On every cycle, the Scheduler checks if it can promote instructions from the
 /// WaitSet to the ReadySet.
index 3effa2b..133cce5 100644 (file)
@@ -409,12 +409,12 @@ public:
 /// that are sent to the various components of the simulated hardware pipeline.
 class Instruction : public InstructionBase {
   enum InstrStage {
-    IS_INVALID,   // Instruction in an invalid state.
-    IS_AVAILABLE, // Instruction dispatched but operands are not ready.
-    IS_READY,     // Instruction dispatched and operands ready.
-    IS_EXECUTING, // Instruction issued.
-    IS_EXECUTED,  // Instruction executed. Values are written back.
-    IS_RETIRED    // Instruction retired.
+    IS_INVALID,    // Instruction in an invalid state.
+    IS_DISPATCHED, // Instruction dispatched but operands are not ready.
+    IS_READY,      // Instruction dispatched and operands ready.
+    IS_EXECUTING,  // Instruction issued.
+    IS_EXECUTED,   // Instruction executed. Values are written back.
+    IS_RETIRED     // Instruction retired.
   };
 
   // The current instruction stage.
@@ -444,7 +444,7 @@ public:
   // all the definitions.
   void execute();
 
-  // Force a transition from the IS_AVAILABLE state to the IS_READY state if
+  // Force a transition from the IS_DISPATCHED state to the IS_READY state if
   // input operands are all ready. State transitions normally occur at the
   // beginning of a new cycle (see method cycleEvent()). However, the scheduler
   // may decide to promote instructions from the wait queue to the ready queue
@@ -452,7 +452,7 @@ public:
   // instruction might have changed in state.
   void update();
 
-  bool isDispatched() const { return Stage == IS_AVAILABLE; }
+  bool isDispatched() const { return Stage == IS_DISPATCHED; }
   bool isReady() const { return Stage == IS_READY; }
   bool isExecuting() const { return Stage == IS_EXECUTING; }
   bool isExecuted() const { return Stage == IS_EXECUTED; }
@@ -464,7 +464,7 @@ public:
                   [](const WriteState &W) { return W.isEliminated(); });
   }
 
-  // Forces a transition from state IS_AVAILABLE to state IS_EXECUTED.
+  // Forces a transition from state IS_DISPATCHED to state IS_EXECUTED.
   void forceExecuted();
 
   void retire() {
index dde20d5..e39f03e 100644 (file)
@@ -61,8 +61,6 @@ class DispatchStage final : public Stage {
   bool canDispatch(const InstRef &IR) const;
   Error dispatch(InstRef IR);
 
-  void updateRAWDependencies(ReadState &RS, const MCSubtargetInfo &STI);
-
   void notifyInstructionDispatched(const InstRef &IR,
                                    ArrayRef<unsigned> UsedPhysRegs,
                                    unsigned uOps) const;
index 78dddba..3621d18 100644 (file)
@@ -401,7 +401,7 @@ void RegisterFile::collectWrites(const ReadState &RS,
 }
 
 void RegisterFile::addRegisterRead(ReadState &RS,
-                                   SmallVectorImpl<WriteRef> &Defs) const {
+                                   const MCSubtargetInfo &STI) const {
   unsigned RegID = RS.getRegisterID();
   const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
   RS.setPRF(RRI.IndexPlusCost.first);
@@ -410,8 +410,23 @@ void RegisterFile::addRegisterRead(ReadState &RS,
 
   if (ZeroRegisters[RS.getRegisterID()])
     RS.setReadZero();
-  collectWrites(RS, Defs);
-  RS.setDependentWrites(Defs.size());
+
+  SmallVector<WriteRef, 4> DependentWrites;
+  collectWrites(RS, DependentWrites);
+  RS.setDependentWrites(DependentWrites.size());
+
+  // We know that this read depends on all the writes in DependentWrites.
+  // For each write, check if we have ReadAdvance information, and use it
+  // to figure out in how many cycles this read becomes available.
+  const ReadDescriptor &RD = RS.getDescriptor();
+  const MCSchedModel &SM = STI.getSchedModel();
+  const MCSchedClassDesc *SC = SM.getSchedClassDesc(RD.SchedClassID);
+  for (WriteRef &WR : DependentWrites) {
+    WriteState &WS = *WR.getWriteState();
+    unsigned WriteResID = WS.getWriteResourceID();
+    int ReadAdvance = STI.getReadAdvanceCycles(SC, RD.UseIndex, WriteResID);
+    WS.addUser(&RS, ReadAdvance);
+  }
 }
 
 unsigned RegisterFile::isAvailable(ArrayRef<unsigned> Regs) const {
index 0e9c709..3c40979 100644 (file)
@@ -123,7 +123,7 @@ void WriteRef::dump() const {
 
 void Instruction::dispatch(unsigned RCUToken) {
   assert(Stage == IS_INVALID);
-  Stage = IS_AVAILABLE;
+  Stage = IS_DISPATCHED;
   RCUTokenID = RCUToken;
 
   // Check if input operands are already available.
index 1c24b87..a67b461 100644 (file)
@@ -62,27 +62,6 @@ bool DispatchStage::canDispatch(const InstRef &IR) const {
   return checkRCU(IR) && checkPRF(IR) && checkNextStage(IR);
 }
 
-void DispatchStage::updateRAWDependencies(ReadState &RS,
-                                          const MCSubtargetInfo &STI) {
-  SmallVector<WriteRef, 4> DependentWrites;
-
-  // Collect all the dependent writes, and update RS internal state.
-  PRF.addRegisterRead(RS, DependentWrites);
-
-  // We know that this read depends on all the writes in DependentWrites.
-  // For each write, check if we have ReadAdvance information, and use it
-  // to figure out in how many cycles this read becomes available.
-  const ReadDescriptor &RD = RS.getDescriptor();
-  const MCSchedModel &SM = STI.getSchedModel();
-  const MCSchedClassDesc *SC = SM.getSchedClassDesc(RD.SchedClassID);
-  for (WriteRef &WR : DependentWrites) {
-    WriteState &WS = *WR.getWriteState();
-    unsigned WriteResID = WS.getWriteResourceID();
-    int ReadAdvance = STI.getReadAdvanceCycles(SC, RD.UseIndex, WriteResID);
-    WS.addUser(&RS, ReadAdvance);
-  }
-}
-
 Error DispatchStage::dispatch(InstRef IR) {
   assert(!CarryOver && "Cannot dispatch another instruction!");
   Instruction &IS = *IR.getInstruction();
@@ -121,7 +100,7 @@ Error DispatchStage::dispatch(InstRef IR) {
   // eliminated at register renaming stage.
   if (!IsEliminated) {
     for (ReadState &RS : IS.getUses())
-      updateRAWDependencies(RS, STI);
+      PRF.addRegisterRead(RS, STI);
   }
 
   // By default, a dependency-breaking zero-idiom is expected to be optimized