[llvm] r327514 - [llvm-mca] Move the logic that updates the register files from InstrBuilder to DispatchUnit. NFCI

Andrea Di Biagio via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 14 07:57:23 PDT 2018


Author: adibiagio
Date: Wed Mar 14 07:57:23 2018
New Revision: 327514

URL: http://llvm.org/viewvc/llvm-project?rev=327514&view=rev
Log:
[llvm-mca] Move the logic that updates the register files from InstrBuilder to DispatchUnit. NFCI

Before this patch, the register file was always updated at instruction creation
time. That means, new read-after-write dependencies, and new temporary registers
were allocated at instruction creation time.

This patch refactors the code in InstrBuilder, and move all the logic that
updates the register file into the dispatch unit. We only want to update the
register file when instructions are effectively dispatched (not before).

This refactoring also helps removing a bad dependency between the InstrBuilder
and the DispatchUnit.

No functional change intended.

Modified:
    llvm/trunk/tools/llvm-mca/Backend.cpp
    llvm/trunk/tools/llvm-mca/Dispatch.cpp
    llvm/trunk/tools/llvm-mca/Dispatch.h
    llvm/trunk/tools/llvm-mca/InstrBuilder.cpp
    llvm/trunk/tools/llvm-mca/InstrBuilder.h
    llvm/trunk/tools/llvm-mca/Instruction.h

Modified: llvm/trunk/tools/llvm-mca/Backend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Backend.cpp?rev=327514&r1=327513&r2=327514&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/Backend.cpp (original)
+++ llvm/trunk/tools/llvm-mca/Backend.cpp Wed Mar 14 07:57:23 2018
@@ -31,26 +31,18 @@ void Backend::addEventListener(HWEventLi
 void Backend::runCycle(unsigned Cycle) {
   notifyCycleBegin(Cycle);
 
-  if (!SM.hasNext()) {
-    notifyCycleEnd(Cycle);
-    return;
-  }
-
-  InstRef IR = SM.peekNext();
-  const InstrDesc *Desc = &IB->getOrCreateInstrDesc(STI, *IR.second);
-  while (DU->isAvailable(Desc->NumMicroOps) && DU->canDispatch(*Desc)) {
-    Instruction *NewIS = IB->createInstruction(STI, *DU, IR.first, *IR.second);
-    Instructions[IR.first] = std::unique_ptr<Instruction>(NewIS);
-    NewIS->setRCUTokenID(DU->dispatch(IR.first, NewIS));
-
-    // Check if we have dispatched all the instructions.
-    SM.updateNext();
-    if (!SM.hasNext())
+  while (SM.hasNext()) {
+    InstRef IR = SM.peekNext();
+    std::unique_ptr<Instruction> NewIS(
+        IB->createInstruction(STI, IR.first, *IR.second));
+    const InstrDesc &Desc = NewIS->getDesc();
+    if (!DU->isAvailable(Desc.NumMicroOps) || !DU->canDispatch(Desc))
       break;
 
-    // Prepare for the next round.
-    IR = SM.peekNext();
-    Desc = &IB->getOrCreateInstrDesc(STI, *IR.second);
+    Instruction *IS = NewIS.get();
+    Instructions[IR.first] = std::move(NewIS);
+    IS->setRCUTokenID(DU->dispatch(IR.first, IS, STI));
+    SM.updateNext();
   }
 
   notifyCycleEnd(Cycle);

Modified: llvm/trunk/tools/llvm-mca/Dispatch.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Dispatch.cpp?rev=327514&r1=327513&r2=327514&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/Dispatch.cpp (original)
+++ llvm/trunk/tools/llvm-mca/Dispatch.cpp Wed Mar 14 07:57:23 2018
@@ -237,7 +237,36 @@ bool DispatchUnit::checkScheduler(const
   return false;
 }
 
-unsigned DispatchUnit::dispatch(unsigned IID, Instruction *NewInst) {
+void DispatchUnit::updateRAWDependencies(ReadState &RS,
+                                         const MCSubtargetInfo &STI) {
+  SmallVector<WriteState *, 4> DependentWrites;
+
+  collectWrites(DependentWrites, RS.getRegisterID());
+  RS.setDependentWrites(DependentWrites.size());
+  DEBUG(dbgs() << "Found " << DependentWrites.size() << " dependent writes\n");
+  // 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();
+  if (!RD.HasReadAdvanceEntries) {
+    for (WriteState *WS : DependentWrites)
+      WS->addUser(&RS, /* ReadAdvance */ 0);
+    return;
+  }
+
+  const MCSchedModel &SM = STI.getSchedModel();
+  const MCSchedClassDesc *SC = SM.getSchedClassDesc(RD.SchedClassID);
+  for (WriteState *WS : DependentWrites) {
+    unsigned WriteResID = WS->getWriteResourceID();
+    int ReadAdvance = STI.getReadAdvanceCycles(SC, RD.OpIndex, WriteResID);
+    WS->addUser(&RS, ReadAdvance);
+  }
+  // Prepare the set for another round.
+  DependentWrites.clear();
+}
+
+unsigned DispatchUnit::dispatch(unsigned IID, Instruction *NewInst,
+                                const MCSubtargetInfo &STI) {
   assert(!CarryOver && "Cannot dispatch another instruction!");
   unsigned NumMicroOps = NewInst->getDesc().NumMicroOps;
   if (NumMicroOps > DispatchWidth) {
@@ -249,6 +278,18 @@ unsigned DispatchUnit::dispatch(unsigned
     AvailableEntries -= NumMicroOps;
   }
 
+  // Update RAW dependencies.
+  for (std::unique_ptr<ReadState> &RS : NewInst->getUses())
+    updateRAWDependencies(*RS, STI);
+
+  // Allocate temporary registers in the register file.
+  for (std::unique_ptr<WriteState> &WS : NewInst->getDefs())
+    addNewRegisterMapping(*WS);
+
+  // Set the cycles left before the write-back stage.
+  const InstrDesc &D = NewInst->getDesc();
+  NewInst->setCyclesLeft(D.MaxLatency);
+
   // Reserve slots in the RCU.
   unsigned RCUTokenID = RCU->reserveSlot(IID, NumMicroOps);
   NewInst->setRCUTokenID(RCUTokenID);

Modified: llvm/trunk/tools/llvm-mca/Dispatch.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Dispatch.h?rev=327514&r1=327513&r2=327514&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/Dispatch.h (original)
+++ llvm/trunk/tools/llvm-mca/Dispatch.h Wed Mar 14 07:57:23 2018
@@ -18,6 +18,7 @@
 
 #include "Instruction.h"
 #include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
 #include <map>
 
 namespace mca {
@@ -236,6 +237,7 @@ class DispatchUnit {
   bool checkRCU(const InstrDesc &Desc);
   bool checkScheduler(const InstrDesc &Desc);
 
+  void updateRAWDependencies(ReadState &RS, const llvm::MCSubtargetInfo &STI);
   void notifyInstructionDispatched(unsigned IID);
 
 public:
@@ -263,7 +265,8 @@ public:
     return checkRCU(Desc) && checkRAT(Desc) && checkScheduler(Desc);
   }
 
-  unsigned dispatch(unsigned IID, Instruction *NewInst);
+  unsigned dispatch(unsigned IID, Instruction *NewInst,
+                    const llvm::MCSubtargetInfo &STI);
 
   void collectWrites(llvm::SmallVectorImpl<WriteState *> &Vec,
                      unsigned RegID) const {

Modified: llvm/trunk/tools/llvm-mca/InstrBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/InstrBuilder.cpp?rev=327514&r1=327513&r2=327514&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/InstrBuilder.cpp (original)
+++ llvm/trunk/tools/llvm-mca/InstrBuilder.cpp Wed Mar 14 07:57:23 2018
@@ -419,14 +419,12 @@ const InstrDesc &InstrBuilder::getOrCrea
 }
 
 Instruction *InstrBuilder::createInstruction(const MCSubtargetInfo &STI,
-                                             DispatchUnit &DU, unsigned Idx,
-                                             const MCInst &MCI) {
+                                             unsigned Idx, const MCInst &MCI) {
   const InstrDesc &D = getOrCreateInstrDesc(STI, MCI);
   Instruction *NewIS = new Instruction(D);
 
   // Populate Reads first.
   const MCSchedModel &SM = STI.getSchedModel();
-  SmallVector<WriteState *, 4> DependentWrites;
   for (const ReadDescriptor &RD : D.Reads) {
     int RegID = -1;
     if (RD.OpIndex != -1) {
@@ -447,34 +445,9 @@ Instruction *InstrBuilder::createInstruc
 
     // Okay, this is a register operand. Create a ReadState for it.
     assert(RegID > 0 && "Invalid register ID found!");
-    ReadState *NewRDS = new ReadState(RD);
+    ReadState *NewRDS = new ReadState(RD, RegID);
     NewIS->getUses().emplace_back(std::unique_ptr<ReadState>(NewRDS));
-    DU.collectWrites(DependentWrites, RegID);
-    NewRDS->setDependentWrites(DependentWrites.size());
-    DEBUG(dbgs() << "Found " << DependentWrites.size()
-                 << " dependent writes\n");
-
-    // 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 after how many cycles this read becomes available.
-    if (!RD.HasReadAdvanceEntries) {
-      for (WriteState *WS : DependentWrites)
-        WS->addUser(NewRDS, /* ReadAdvance */ 0);
-      // Prepare the set for another round.
-      DependentWrites.clear();
-      continue;
-    }
-
-    const MCSchedClassDesc *SC = SM.getSchedClassDesc(RD.SchedClassID);
-    for (WriteState *WS : DependentWrites) {
-      unsigned WriteResID = WS->getWriteResourceID();
-      int ReadAdvance = STI.getReadAdvanceCycles(SC, RD.OpIndex, WriteResID);
-      WS->addUser(NewRDS, ReadAdvance);
-    }
-
-    // Prepare the set for another round.
-    DependentWrites.clear();
-  }
+ }
 
   // Now populate writes.
   for (const WriteDescriptor &WD : D.Writes) {
@@ -489,11 +462,8 @@ Instruction *InstrBuilder::createInstruc
     WriteState *NewWS = new WriteState(WD);
     NewIS->getDefs().emplace_back(std::unique_ptr<WriteState>(NewWS));
     NewWS->setRegisterID(RegID);
-    DU.addNewRegisterMapping(*NewWS);
   }
 
-  // Update Latency.
-  NewIS->setCyclesLeft(D.MaxLatency);
   return NewIS;
 }
 

Modified: llvm/trunk/tools/llvm-mca/InstrBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/InstrBuilder.h?rev=327514&r1=327513&r2=327514&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/InstrBuilder.h (original)
+++ llvm/trunk/tools/llvm-mca/InstrBuilder.h Wed Mar 14 07:57:23 2018
@@ -15,7 +15,6 @@
 #ifndef LLVM_TOOLS_LLVM_MCA_INSTRBUILDER_H
 #define LLVM_TOOLS_LLVM_MCA_INSTRBUILDER_H
 
-#include "Dispatch.h"
 #include "Instruction.h"
 #include "llvm/MC/MCInstrInfo.h"
 #include "llvm/MC/MCSubtargetInfo.h"
@@ -53,7 +52,7 @@ public:
                                         const llvm::MCInst &MCI);
 
   Instruction *createInstruction(const llvm::MCSubtargetInfo &STI,
-                                 DispatchUnit &DU, unsigned Idx,
+                                 unsigned Idx,
                                  const llvm::MCInst &MCI);
 };
 

Modified: llvm/trunk/tools/llvm-mca/Instruction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Instruction.h?rev=327514&r1=327513&r2=327514&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/Instruction.h (original)
+++ llvm/trunk/tools/llvm-mca/Instruction.h Wed Mar 14 07:57:23 2018
@@ -131,6 +131,7 @@ public:
 /// writes only partially update the register associated to this read.
 class ReadState {
   const ReadDescriptor &RD;
+  unsigned RegisterID;
   unsigned DependentWrites;
   int CyclesLeft;
   unsigned TotalCycles;
@@ -142,14 +143,15 @@ public:
     return (CyclesLeft == UNKNOWN_CYCLES || CyclesLeft == 0);
   }
 
-  ReadState(const ReadDescriptor &Desc)
-      : RD(Desc), DependentWrites(0), CyclesLeft(UNKNOWN_CYCLES),
-        TotalCycles(0) {}
+  ReadState(const ReadDescriptor &Desc, unsigned RegID)
+      : RD(Desc), RegisterID(RegID), DependentWrites(0),
+        CyclesLeft(UNKNOWN_CYCLES), TotalCycles(0) {}
   ReadState(const ReadState &Other) = delete;
   ReadState &operator=(const ReadState &Other) = delete;
 
   const ReadDescriptor &getDescriptor() const { return RD; }
   unsigned getSchedClass() const { return RD.SchedClassID; }
+  unsigned getRegisterID() const { return RegisterID; }
   void cycleEvent();
   void writeStartEvent(unsigned Cycles);
   void setDependentWrites(unsigned Writes) { DependentWrites = Writes; }




More information about the llvm-commits mailing list