Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/49716 )

Change subject: cpu-o3: Manage per-register-type free lists with an array.
......................................................................

cpu-o3: Manage per-register-type free lists with an array.

Change-Id: Ie32b9fda87780c3ac15e0a5e309d50df05a99f0c
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49716
Reviewed-by: Giacomo Travaglini <giacomo.travagl...@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travagl...@arm.com>
Tested-by: kokoro <noreply+kok...@google.com>
---
M src/cpu/o3/cpu.cc
M src/cpu/o3/free_list.hh
M src/cpu/o3/rename_map.cc
3 files changed, 51 insertions(+), 200 deletions(-)

Approvals:
  Giacomo Travaglini: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass




diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index bc71825..bc117b9 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -229,14 +229,14 @@
                 ++ridx) {
             // Note that we can't use the rename() method because we don't
             // want special treatment for the zero register at this point
-            PhysRegIdPtr phys_reg = freeList.getIntReg();
+            PhysRegIdPtr phys_reg = freeList.getReg(IntRegClass);
             renameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg);
commitRenameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg);
         }

for (RegIndex ridx = 0; ridx < regClasses.at(FloatRegClass).numRegs();
                 ++ridx) {
-            PhysRegIdPtr phys_reg = freeList.getFloatReg();
+            PhysRegIdPtr phys_reg = freeList.getReg(FloatRegClass);
             renameMap[tid].setEntry(RegId(FloatRegClass, ridx), phys_reg);
             commitRenameMap[tid].setEntry(
                     RegId(FloatRegClass, ridx), phys_reg);
@@ -246,7 +246,7 @@
         /* Initialize the full-vector interface */
         for (RegIndex ridx = 0; ridx < numVecs; ++ridx) {
             RegId rid = RegId(VecRegClass, ridx);
-            PhysRegIdPtr phys_reg = freeList.getVecReg();
+            PhysRegIdPtr phys_reg = freeList.getReg(VecRegClass);
             renameMap[tid].setEntry(rid, phys_reg);
             commitRenameMap[tid].setEntry(rid, phys_reg);
         }
@@ -254,14 +254,14 @@
         const size_t numElems = regClasses.at(VecElemClass).numRegs();
         for (RegIndex ridx = 0; ridx < numElems; ++ridx) {
             RegId lrid = RegId(VecElemClass, ridx);
-            PhysRegIdPtr phys_elem = freeList.getVecElem();
+            PhysRegIdPtr phys_elem = freeList.getReg(VecElemClass);
             renameMap[tid].setEntry(lrid, phys_elem);
             commitRenameMap[tid].setEntry(lrid, phys_elem);
         }

         for (RegIndex ridx = 0;
                 ridx < regClasses.at(VecPredRegClass).numRegs(); ++ridx) {
-            PhysRegIdPtr phys_reg = freeList.getVecPredReg();
+            PhysRegIdPtr phys_reg = freeList.getReg(VecPredRegClass);
renameMap[tid].setEntry(RegId(VecPredRegClass, ridx), phys_reg);
             commitRenameMap[tid].setEntry(
                     RegId(VecPredRegClass, ridx), phys_reg);
@@ -269,7 +269,7 @@

         for (RegIndex ridx = 0; ridx < regClasses.at(CCRegClass).numRegs();
                 ++ridx) {
-            PhysRegIdPtr phys_reg = freeList.getCCReg();
+            PhysRegIdPtr phys_reg = freeList.getReg(CCRegClass);
             renameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg);
commitRenameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg);
         }
@@ -730,7 +730,7 @@
     const auto &regClasses = isa[tid]->regClasses();

for (RegIndex idx = 0; idx < regClasses.at(IntRegClass).numRegs(); idx++) {
-        PhysRegIdPtr phys_reg = freeList.getIntReg();
+        PhysRegIdPtr phys_reg = freeList.getReg(IntRegClass);
         renameMap[tid].setEntry(RegId(IntRegClass, idx), phys_reg);
         scoreboard.setReg(phys_reg);
     }
@@ -738,14 +738,14 @@
     //Bind Float Regs to Rename Map
     for (RegIndex idx = 0; idx < regClasses.at(FloatRegClass).numRegs();
             idx++) {
-        PhysRegIdPtr phys_reg = freeList.getFloatReg();
+        PhysRegIdPtr phys_reg = freeList.getReg(FloatRegClass);
         renameMap[tid].setEntry(RegId(FloatRegClass, idx), phys_reg);
         scoreboard.setReg(phys_reg);
     }

     //Bind condition-code Regs to Rename Map
for (RegIndex idx = 0; idx < regClasses.at(CCRegClass).numRegs(); idx++) {
-        PhysRegIdPtr phys_reg = freeList.getCCReg();
+        PhysRegIdPtr phys_reg = freeList.getReg(CCRegClass);
         renameMap[tid].setEntry(RegId(CCRegClass, idx), phys_reg);
         scoreboard.setReg(phys_reg);
     }
diff --git a/src/cpu/o3/free_list.hh b/src/cpu/o3/free_list.hh
index 54edfc1..408d6e0 100644
--- a/src/cpu/o3/free_list.hh
+++ b/src/cpu/o3/free_list.hh
@@ -42,6 +42,8 @@
 #ifndef __CPU_O3_FREE_LIST_HH__
 #define __CPU_O3_FREE_LIST_HH__

+#include <algorithm>
+#include <array>
 #include <iostream>
 #include <queue>

@@ -127,26 +129,7 @@
      *  explicitly because Scoreboard is not a SimObject. */
     const std::string _name;

-    /** The list of free integer registers. */
-    SimpleFreeList intList;
-
-    /** The list of free floating point registers. */
-    SimpleFreeList floatList;
-
-    /** The following two are exclusive interfaces. */
-    /** @{ */
-    /** The list of free vector registers. */
-    SimpleFreeList vecList;
-
-    /** The list of free vector element registers. */
-    SimpleFreeList vecElemList;
-    /** @} */
-
-    /** The list of free predicate registers. */
-    SimpleFreeList predList;
-
-    /** The list of free condition-code registers. */
-    SimpleFreeList ccList;
+    std::array<SimpleFreeList, CCRegClass + 1> freeLists;

     /**
      * The register file object is used only to distinguish integer
@@ -175,174 +158,39 @@
     /** Gives the name of the freelist. */
     std::string name() const { return _name; };

-    /** Returns a pointer to the condition-code free list */
-    SimpleFreeList *getCCList() { return &ccList; }
-
-    /** Gets a free integer register. */
-    PhysRegIdPtr getIntReg() { return intList.getReg(); }
-
-    /** Gets a free fp register. */
-    PhysRegIdPtr getFloatReg() { return floatList.getReg(); }
-
-    /** Gets a free vector register. */
-    PhysRegIdPtr getVecReg() { return vecList.getReg(); }
-
-    /** Gets a free vector elemenet register. */
-    PhysRegIdPtr getVecElem() { return vecElemList.getReg(); }
-
-    /** Gets a free predicate register. */
-    PhysRegIdPtr getVecPredReg() { return predList.getReg(); }
-
-    /** Gets a free cc register. */
-    PhysRegIdPtr getCCReg() { return ccList.getReg(); }
-
-    /** Adds a register back to the free list. */
-    void addReg(PhysRegIdPtr freed_reg);
+    /** Gets a free register of type type. */
+ PhysRegIdPtr getReg(RegClassType type) { return freeLists[type].getReg(); }

     /** Adds a register back to the free list. */
     template<class InputIt>
-    void addRegs(InputIt first, InputIt last);
-
-    /** Adds an integer register back to the free list. */
-    void addIntReg(PhysRegIdPtr freed_reg) { intList.addReg(freed_reg); }
-
-    /** Adds a fp register back to the free list. */
- void addFloatReg(PhysRegIdPtr freed_reg) { floatList.addReg(freed_reg); }
-
-    /** Adds a vector register back to the free list. */
-    void addVecReg(PhysRegIdPtr freed_reg) { vecList.addReg(freed_reg); }
-
-    /** Adds a vector element register back to the free list. */
-    void addVecElem(PhysRegIdPtr freed_reg) {
-        vecElemList.addReg(freed_reg);
+    void
+    addRegs(InputIt first, InputIt last)
+    {
+        std::for_each(first, last, [this](auto &reg) { addReg(&reg); });
     }

-    /** Adds a predicate register back to the free list. */
- void addVecPredReg(PhysRegIdPtr freed_reg) { predList.addReg(freed_reg); }
+    /** Adds a register back to the free list. */
+    void
+    addReg(PhysRegIdPtr freed_reg)
+    {
+        freeLists[freed_reg->classValue()].addReg(freed_reg);
+    }

-    /** Adds a cc register back to the free list. */
-    void addCCReg(PhysRegIdPtr freed_reg) { ccList.addReg(freed_reg); }
+    /** Checks if there are any free registers of type type. */
+    bool
+    hasFreeRegs(RegClassType type) const
+    {
+        return freeLists[type].hasFreeRegs();
+    }

-    /** Checks if there are any free integer registers. */
-    bool hasFreeIntRegs() const { return intList.hasFreeRegs(); }
-
-    /** Checks if there are any free fp registers. */
-    bool hasFreeFloatRegs() const { return floatList.hasFreeRegs(); }
-
-    /** Checks if there are any free vector registers. */
-    bool hasFreeVecRegs() const { return vecList.hasFreeRegs(); }
-
-    /** Checks if there are any free vector registers. */
-    bool hasFreeVecElems() const { return vecElemList.hasFreeRegs(); }
-
-    /** Checks if there are any free predicate registers. */
-    bool hasFreeVecPredRegs() const { return predList.hasFreeRegs(); }
-
-    /** Checks if there are any free cc registers. */
-    bool hasFreeCCRegs() const { return ccList.hasFreeRegs(); }
-
-    /** Returns the number of free integer registers. */
-    unsigned numFreeIntRegs() const { return intList.numFreeRegs(); }
-
-    /** Returns the number of free fp registers. */
-    unsigned numFreeFloatRegs() const { return floatList.numFreeRegs(); }
-
-    /** Returns the number of free vector registers. */
-    unsigned numFreeVecRegs() const { return vecList.numFreeRegs(); }
-
-    /** Returns the number of free vector registers. */
-    unsigned numFreeVecElems() const { return vecElemList.numFreeRegs(); }
-
-    /** Returns the number of free predicate registers. */
-    unsigned numFreeVecPredRegs() const { return predList.numFreeRegs(); }
-
-    /** Returns the number of free cc registers. */
-    unsigned numFreeCCRegs() const { return ccList.numFreeRegs(); }
+    /** Returns the number of free registers of type type. */
+    unsigned
+    numFreeRegs(RegClassType type) const
+    {
+        return freeLists[type].numFreeRegs();
+    }
 };

-template<class InputIt>
-inline void
-UnifiedFreeList::addRegs(InputIt first, InputIt last)
-{
-    // Are there any registers to add?
-    if (first == last)
-        return;
-
-    panic_if((first != last) &&
-            first->classValue() != (last-1)->classValue(),
-            "Attempt to add mixed type regs: %s and %s",
-            first->className(),
-            (last-1)->className());
-    switch (first->classValue()) {
-        case IntRegClass:
-            intList.addRegs(first, last);
-            break;
-        case FloatRegClass:
-            floatList.addRegs(first, last);
-            break;
-        case VecRegClass:
-            vecList.addRegs(first, last);
-            break;
-        case VecElemClass:
-            vecElemList.addRegs(first, last);
-            break;
-        case VecPredRegClass:
-            predList.addRegs(first, last);
-            break;
-        case CCRegClass:
-            ccList.addRegs(first, last);
-            break;
-        default:
-            panic("Unexpected RegClass (%s)",
-                                   first->className());
-    }
-
-}
-
-inline void
-UnifiedFreeList::addReg(PhysRegIdPtr freed_reg)
-{
-    DPRINTF(FreeList,"Freeing register %i (%s).\n", freed_reg->index(),
-            freed_reg->className());
-    //Might want to add in a check for whether or not this register is
-    //already in there.  A bit vector or something similar would be useful.
-    switch (freed_reg->classValue()) {
-        case IntRegClass:
-            intList.addReg(freed_reg);
-            break;
-        case FloatRegClass:
-            floatList.addReg(freed_reg);
-            break;
-        case VecRegClass:
-            vecList.addReg(freed_reg);
-            break;
-        case VecElemClass:
-            vecElemList.addReg(freed_reg);
-            break;
-        case VecPredRegClass:
-            predList.addReg(freed_reg);
-            break;
-        case CCRegClass:
-            ccList.addReg(freed_reg);
-            break;
-        default:
-            panic("Unexpected RegClass (%s)",
-                                   freed_reg->className());
-    }
-
-    // These assert conditions ensure that the number of free
-    // registers are not more than the # of total Physical  Registers.
-    // If this were false, it would mean that registers
-    // have been freed twice, overflowing the free register
-    // pool and potentially crashing SMT workloads.
-    // ----
-    // Comment out for now so as to not potentially break
-    // CMP and single-threaded workloads
-    // ----
-    // assert(freeIntRegs.size() <= numPhysicalIntRegs);
-    // assert(freeFloatRegs.size() <= numPhysicalFloatRegs);
-}
-
 } // namespace o3
 } // namespace gem5

diff --git a/src/cpu/o3/rename_map.cc b/src/cpu/o3/rename_map.cc
index d665b6a..256b4bf 100644
--- a/src/cpu/o3/rename_map.cc
+++ b/src/cpu/o3/rename_map.cc
@@ -115,18 +115,8 @@
 {
     regFile = _regFile;

-    renameMaps[IntRegClass].init(regClasses.at(IntRegClass),
-            &(freeList->intList));
-    renameMaps[FloatRegClass].init(regClasses.at(FloatRegClass),
-            &(freeList->floatList));
-    renameMaps[VecRegClass].init(regClasses.at(VecRegClass),
-            &(freeList->vecList));
-    renameMaps[VecElemClass].init(regClasses.at(VecElemClass),
-            &(freeList->vecElemList));
-    renameMaps[VecPredRegClass].init(regClasses.at(VecPredRegClass),
-            &(freeList->predList));
-    renameMaps[CCRegClass].init(regClasses.at(CCRegClass),
-            &(freeList->ccList));
+    for (int i = 0; i < renameMaps.size(); i++)
+        renameMaps[i].init(regClasses.at(i), &(freeList->freeLists[i]));
 }

 bool

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/49716
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ie32b9fda87780c3ac15e0a5e309d50df05a99f0c
Gerrit-Change-Number: 49716
Gerrit-PatchSet: 57
Gerrit-Owner: Gabe Black <gabe.bl...@gmail.com>
Gerrit-Reviewer: Gabe Black <gabe.bl...@gmail.com>
Gerrit-Reviewer: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to