cpu-o3: convert lsq_unit to new style stats

Removes unused stats: invAddrLoads, invAddrSwpfs, lsqBlockedLoads

Change-Id: Icd7fc6d8a040f4a1f9b190409b7cdb0a57fd68cf
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/33394
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh
index 9a04fe6..497c532 100644
--- a/src/cpu/o3/iew_impl.hh
+++ b/src/cpu/o3/iew_impl.hh
@@ -146,7 +146,6 @@
     using namespace Stats;
 
     instQueue.regStats();
-    ldstQueue.regStats();
 
     iewIdleCycles
         .name(name() + ".iewIdleCycles")
diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh
index 35c2873..bc5e154 100644
--- a/src/cpu/o3/lsq.hh
+++ b/src/cpu/o3/lsq.hh
@@ -856,9 +856,6 @@
     /** Returns the name of the LSQ. */
     std::string name() const;
 
-    /** Registers statistics of each LSQ unit. */
-    void regStats();
-
     /** Sets the pointer to the list of active threads. */
     void setActiveThreads(std::list<ThreadID> *at_ptr);
 
diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index a535dcc..7657b23 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -118,16 +118,6 @@
 
 template<class Impl>
 void
-LSQ<Impl>::regStats()
-{
-    //Initialize LSQs
-    for (ThreadID tid = 0; tid < numThreads; tid++) {
-        thread[tid].regStats();
-    }
-}
-
-template<class Impl>
-void
 LSQ<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
 {
     activeThreads = at_ptr;
diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh
index 70995d6..3d6e3f0 100644
--- a/src/cpu/o3/lsq_unit.hh
+++ b/src/cpu/o3/lsq_unit.hh
@@ -45,6 +45,7 @@
 #include <algorithm>
 #include <cstring>
 #include <map>
+#include <memory>
 #include <queue>
 
 #include "arch/generic/debugfaults.hh"
@@ -225,7 +226,10 @@
      * contructor is deleted explicitly. However, STL vector requires
      * a valid copy constructor for the base type at compile time.
      */
-    LSQUnit(const LSQUnit &l) { panic("LSQUnit is not copy-able"); }
+    LSQUnit(const LSQUnit &l): stats(nullptr)
+    {
+        panic("LSQUnit is not copy-able");
+    }
 
     /** Initializes the LSQ unit with the specified number of entries. */
     void init(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params,
@@ -234,9 +238,6 @@
     /** Returns the name of the LSQ unit. */
     std::string name() const;
 
-    /** Registers statistics. */
-    void regStats();
-
     /** Sets the pointer to the dcache port. */
     void setDcachePort(RequestPort *dcache_port);
 
@@ -561,39 +562,35 @@
     /** Flag for memory model. */
     bool needsTSO;
 
+  protected:
     // Will also need how many read/write ports the Dcache has.  Or keep track
     // of that in stage that is one level up, and only call executeLoad/Store
     // the appropriate number of times.
-    /** Total number of loads forwaded from LSQ stores. */
-    Stats::Scalar lsqForwLoads;
+    struct LSQUnitStats : public Stats::Group{
+        LSQUnitStats(Stats::Group *parent);
 
-    /** Total number of loads ignored due to invalid addresses. */
-    Stats::Scalar invAddrLoads;
+        /** Total number of loads forwaded from LSQ stores. */
+        Stats::Scalar forwLoads;
 
-    /** Total number of squashed loads. */
-    Stats::Scalar lsqSquashedLoads;
+        /** Total number of squashed loads. */
+        Stats::Scalar squashedLoads;
 
-    /** Total number of responses from the memory system that are
-     * ignored due to the instruction already being squashed. */
-    Stats::Scalar lsqIgnoredResponses;
+        /** Total number of responses from the memory system that are
+         * ignored due to the instruction already being squashed. */
+        Stats::Scalar ignoredResponses;
 
-    /** Tota number of memory ordering violations. */
-    Stats::Scalar lsqMemOrderViolation;
+        /** Tota number of memory ordering violations. */
+        Stats::Scalar memOrderViolation;
 
-    /** Total number of squashed stores. */
-    Stats::Scalar lsqSquashedStores;
+        /** Total number of squashed stores. */
+        Stats::Scalar squashedStores;
 
-    /** Total number of software prefetches ignored due to invalid addresses. */
-    Stats::Scalar invAddrSwpfs;
+        /** Number of loads that were rescheduled. */
+        Stats::Scalar rescheduledLoads;
 
-    /** Ready loads blocked due to partial store-forwarding. */
-    Stats::Scalar lsqBlockedLoads;
-
-    /** Number of loads that were rescheduled. */
-    Stats::Scalar lsqRescheduledLoads;
-
-    /** Number of times the LSQ is blocked due to the cache. */
-    Stats::Scalar lsqCacheBlocked;
+        /** Number of times the LSQ is blocked due to the cache. */
+        Stats::Scalar blockedByCache;
+    } stats;
 
   public:
     /** Executes the load at the given index. */
@@ -658,7 +655,7 @@
         iewStage->rescheduleMemInst(load_inst);
         load_inst->clearIssued();
         load_inst->effAddrValid(false);
-        ++lsqRescheduledLoads;
+        ++stats.rescheduledLoads;
         DPRINTF(LSQUnit, "Strictly ordered load [sn:%lli] PC %s\n",
                 load_inst->seqNum, load_inst->pcState());
 
@@ -873,7 +870,7 @@
                 cpu->schedule(wb, curTick());
 
                 // Don't need to do anything special for split loads.
-                ++lsqForwLoads;
+                ++stats.forwLoads;
 
                 return NoFault;
             } else if (coverage == AddrRangeCoverage::PartialAddrRangeCoverage) {
@@ -900,7 +897,7 @@
                 iewStage->rescheduleMemInst(load_inst);
                 load_inst->clearIssued();
                 load_inst->effAddrValid(false);
-                ++lsqRescheduledLoads;
+                ++stats.rescheduledLoads;
 
                 // Do not generate a writeback event as this instruction is not
                 // complete.
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index fcbfc9c..808a671 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -208,7 +208,7 @@
       lastRetiredHtmUid(0),
       cacheBlockMask(0), stalled(false),
       isStoreBlocked(false), storeInFlight(false), hasPendingRequest(false),
-      pendingRequest(nullptr)
+      pendingRequest(nullptr), stats(nullptr)
 {
 }
 
@@ -224,6 +224,8 @@
 
     lsq = lsq_ptr;
 
+    cpu->addStatGroup(csprintf("lsq%i", lsqID).c_str(), &stats);
+
     DPRINTF(LSQUnit, "Creating LSQUnit%i object.\n",lsqID);
 
     depCheckShift = params->LSQDepCheckShift;
@@ -265,49 +267,20 @@
     }
 }
 
-template<class Impl>
-void
-LSQUnit<Impl>::regStats()
+template <class Impl>
+LSQUnit<Impl>::LSQUnitStats::LSQUnitStats(Stats::Group *parent)
+    : Stats::Group(parent),
+      ADD_STAT(forwLoads, "Number of loads that had data forwarded from"
+          " stores"),
+      ADD_STAT(squashedLoads, "Number of loads squashed"),
+      ADD_STAT(ignoredResponses, "Number of memory responses ignored"
+          " because the instruction is squashed"),
+      ADD_STAT(memOrderViolation, "Number of memory ordering violations"),
+      ADD_STAT(squashedStores, "Number of stores squashed"),
+      ADD_STAT(rescheduledLoads, "Number of loads that were rescheduled"),
+      ADD_STAT(blockedByCache, "Number of times an access to memory failed"
+          " due to the cache being blocked")
 {
-    lsqForwLoads
-        .name(name() + ".forwLoads")
-        .desc("Number of loads that had data forwarded from stores");
-
-    invAddrLoads
-        .name(name() + ".invAddrLoads")
-        .desc("Number of loads ignored due to an invalid address");
-
-    lsqSquashedLoads
-        .name(name() + ".squashedLoads")
-        .desc("Number of loads squashed");
-
-    lsqIgnoredResponses
-        .name(name() + ".ignoredResponses")
-        .desc("Number of memory responses ignored because the instruction is squashed");
-
-    lsqMemOrderViolation
-        .name(name() + ".memOrderViolation")
-        .desc("Number of memory ordering violations");
-
-    lsqSquashedStores
-        .name(name() + ".squashedStores")
-        .desc("Number of stores squashed");
-
-    invAddrSwpfs
-        .name(name() + ".invAddrSwpfs")
-        .desc("Number of software prefetches ignored due to an invalid address");
-
-    lsqBlockedLoads
-        .name(name() + ".blockedLoads")
-        .desc("Number of blocked loads due to partial load-store forwarding");
-
-    lsqRescheduledLoads
-        .name(name() + ".rescheduledLoads")
-        .desc("Number of loads that were rescheduled");
-
-    lsqCacheBlocked
-        .name(name() + ".cacheBlocked")
-        .desc("Number of times an access to memory failed due to the cache being blocked");
 }
 
 template<class Impl>
@@ -587,7 +560,7 @@
                                 inst->seqNum, ld_inst->seqNum, ld_eff_addr1);
                         memDepViolator = ld_inst;
 
-                        ++lsqMemOrderViolation;
+                        ++stats.memOrderViolation;
 
                         return std::make_shared<GenericISA::M5PanicFault>(
                             "Detected fault with inst [sn:%lli] and "
@@ -614,7 +587,7 @@
                         inst->seqNum, ld_inst->seqNum, ld_eff_addr1);
                 memDepViolator = ld_inst;
 
-                ++lsqMemOrderViolation;
+                ++stats.memOrderViolation;
 
                 return std::make_shared<GenericISA::M5PanicFault>(
                     "Detected fault with "
@@ -1005,7 +978,7 @@
         --loads;
 
         loadQueue.pop_back();
-        ++lsqSquashedLoads;
+        ++stats.squashedLoads;
     }
 
     // hardware transactional memory
@@ -1077,7 +1050,7 @@
         --stores;
 
         storeQueue.pop_back();
-        ++lsqSquashedStores;
+        ++stats.squashedStores;
     }
 }
 
@@ -1122,7 +1095,7 @@
     // Squashed instructions do not need to complete their access.
     if (inst->isSquashed()) {
         assert (!inst->isStore() || inst->isStoreConditional());
-        ++lsqIgnoredResponses;
+        ++stats.ignoredResponses;
         return;
     }
 
@@ -1269,7 +1242,7 @@
     } else {
         if (cache_got_blocked) {
             lsq->cacheBlocked(true);
-            ++lsqCacheBlocked;
+            ++stats.blockedByCache;
         }
         if (!isLoad) {
             assert(state->request() == storeWBIt->request());