cpu-o3,stats: Update stats style of inst_queue & inst_queue_impl
authorHoa Nguyen <hoanguyen@ucdavis.edu>
Fri, 16 Oct 2020 00:50:01 +0000 (17:50 -0700)
committerHoa Nguyen <hoanguyen@ucdavis.edu>
Thu, 19 Nov 2020 22:46:48 +0000 (22:46 +0000)
Change-Id: I95c2e194e757437fb8c3b3f530bce363e24f9a8e
Signed-off-by: Hoa Nguyen <hoanguyen@ucdavis.edu>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/36176
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/cpu/o3/cpu.cc
src/cpu/o3/iew.hh
src/cpu/o3/iew_impl.hh
src/cpu/o3/inst_queue.hh
src/cpu/o3/inst_queue_impl.hh

index 1ef8154446594b916f1bc10ae7710d9d43bfa2c9..8461d0609654088a52548e1e1e44e256c4a14514 100644 (file)
@@ -447,8 +447,6 @@ FullO3CPU<Impl>::regStats()
         .precision(6);
     totalIpc =  sum(committedInsts) / numCycles;
 
-    this->iew.regStats();
-
     intRegfileReads
         .name(name() + ".int_regfile_reads")
         .desc("number of integer regfile reads")
index 683902a5ede4dc38237832e3f76de6e9dca3a0f5..b62451034cf1108f15625b44cf44dfad3a9387aa 100644 (file)
@@ -136,9 +136,6 @@ class DefaultIEW
     /** Returns the name of the DefaultIEW stage. */
     std::string name() const;
 
-    /** Registers statistics. */
-    void regStats();
-
     /** Registers probes. */
     void regProbePoints();
 
index fc89a89104f3935120926ba05a8b0383287f97a6..a50a94a69710caf5137efe988dd2979e04290129 100644 (file)
@@ -243,13 +243,6 @@ ExecutedInstStats::ExecutedInstStats(O3CPU *cpu)
         .flags(Stats::total);
 }
 
-template <class Impl>
-void
-DefaultIEW<Impl>::regStats()
-{
-    instQueue.regStats();
-}
-
 template<class Impl>
 void
 DefaultIEW<Impl>::startupStage()
@@ -689,7 +682,7 @@ DefaultIEW<Impl>::updateStatus()
     // If there are no ready instructions waiting to be scheduled by the IQ,
     // and there's no stores waiting to write back, and dispatch is not
     // unblocking, then there is no internal activity for the IEW stage.
-    instQueue.intInstQueueReads++;
+    instQueue.iqIOStats.intInstQueueReads++;
     if (_status == Active && !instQueue.hasReadyInsts() &&
         !ldstQueue.willWB() && !any_unblocking) {
         DPRINTF(IEW, "IEW switching to idle\n");
index 1aebfa0d200414d3f8db9ebc567555750dd80e83..0286a6e4199399090cd0959f6753ef124a686f98 100644 (file)
@@ -130,9 +130,6 @@ class InstructionQueue
     /** Returns the name of the IQ. */
     std::string name() const;
 
-    /** Registers statistics. */
-    void regStats();
-
     /** Resets all instruction queue state. */
     void resetState();
 
@@ -472,75 +469,87 @@ class InstructionQueue
      */
     void dumpInsts();
 
-    /** Stat for number of instructions added. */
-    Stats::Scalar iqInstsAdded;
-    /** Stat for number of non-speculative instructions added. */
-    Stats::Scalar iqNonSpecInstsAdded;
-
-    Stats::Scalar iqInstsIssued;
-    /** Stat for number of integer instructions issued. */
-    Stats::Scalar iqIntInstsIssued;
-    /** Stat for number of floating point instructions issued. */
-    Stats::Scalar iqFloatInstsIssued;
-    /** Stat for number of branch instructions issued. */
-    Stats::Scalar iqBranchInstsIssued;
-    /** Stat for number of memory instructions issued. */
-    Stats::Scalar iqMemInstsIssued;
-    /** Stat for number of miscellaneous instructions issued. */
-    Stats::Scalar iqMiscInstsIssued;
-    /** Stat for number of squashed instructions that were ready to issue. */
-    Stats::Scalar iqSquashedInstsIssued;
-    /** Stat for number of squashed instructions examined when squashing. */
-    Stats::Scalar iqSquashedInstsExamined;
-    /** Stat for number of squashed instruction operands examined when
-     * squashing.
-     */
-    Stats::Scalar iqSquashedOperandsExamined;
-    /** Stat for number of non-speculative instructions removed due to a squash.
-     */
-    Stats::Scalar iqSquashedNonSpecRemoved;
-    // Also include number of instructions rescheduled and replayed.
-
-    /** Distribution of number of instructions in the queue.
-     * @todo: Need to create struct to track the entry time for each
-     * instruction. */
-//    Stats::VectorDistribution queueResDist;
-    /** Distribution of the number of instructions issued. */
-    Stats::Distribution numIssuedDist;
-    /** Distribution of the cycles it takes to issue an instruction.
-     * @todo: Need to create struct to track the ready time for each
-     * instruction. */
-//    Stats::VectorDistribution issueDelayDist;
-
-    /** Number of times an instruction could not be issued because a
-     * FU was busy.
-     */
-    Stats::Vector statFuBusy;
-//    Stats::Vector dist_unissued;
-    /** Stat for total number issued for each instruction type. */
-    Stats::Vector2d statIssuedInstType;
-
-    /** Number of instructions issued per cycle. */
-    Stats::Formula issueRate;
-
-    /** Number of times the FU was busy. */
-    Stats::Vector fuBusy;
-    /** Number of times the FU was busy per instruction issued. */
-    Stats::Formula fuBusyRate;
+    struct IQStats : public Stats::Group
+    {
+        IQStats(O3CPU *cpu, const unsigned &total_width);
+        /** Stat for number of instructions added. */
+        Stats::Scalar instsAdded;
+        /** Stat for number of non-speculative instructions added. */
+        Stats::Scalar nonSpecInstsAdded;
+
+        Stats::Scalar instsIssued;
+        /** Stat for number of integer instructions issued. */
+        Stats::Scalar intInstsIssued;
+        /** Stat for number of floating point instructions issued. */
+        Stats::Scalar floatInstsIssued;
+        /** Stat for number of branch instructions issued. */
+        Stats::Scalar branchInstsIssued;
+        /** Stat for number of memory instructions issued. */
+        Stats::Scalar memInstsIssued;
+        /** Stat for number of miscellaneous instructions issued. */
+        Stats::Scalar miscInstsIssued;
+        /** Stat for number of squashed instructions that were ready to
+         *  issue. */
+        Stats::Scalar squashedInstsIssued;
+        /** Stat for number of squashed instructions examined when
+         *  squashing. */
+        Stats::Scalar squashedInstsExamined;
+        /** Stat for number of squashed instruction operands examined when
+         * squashing.
+         */
+        Stats::Scalar squashedOperandsExamined;
+        /** Stat for number of non-speculative instructions removed due to
+         *  a squash.
+         */
+        Stats::Scalar squashedNonSpecRemoved;
+        // Also include number of instructions rescheduled and replayed.
+
+        /** Distribution of number of instructions in the queue.
+         * @todo: Need to create struct to track the entry time for each
+         * instruction. */
+        // Stats::VectorDistribution queueResDist;
+        /** Distribution of the number of instructions issued. */
+        Stats::Distribution numIssuedDist;
+        /** Distribution of the cycles it takes to issue an instruction.
+         * @todo: Need to create struct to track the ready time for each
+         * instruction. */
+        // Stats::VectorDistribution issueDelayDist;
+
+        /** Number of times an instruction could not be issued because a
+         * FU was busy.
+         */
+        Stats::Vector statFuBusy;
+        // Stats::Vector dist_unissued;
+        /** Stat for total number issued for each instruction type. */
+        Stats::Vector2d statIssuedInstType;
+
+        /** Number of instructions issued per cycle. */
+        Stats::Formula issueRate;
+
+        /** Number of times the FU was busy. */
+        Stats::Vector fuBusy;
+        /** Number of times the FU was busy per instruction issued. */
+        Stats::Formula fuBusyRate;
+    } iqStats;
+
    public:
-    Stats::Scalar intInstQueueReads;
-    Stats::Scalar intInstQueueWrites;
-    Stats::Scalar intInstQueueWakeupAccesses;
-    Stats::Scalar fpInstQueueReads;
-    Stats::Scalar fpInstQueueWrites;
-    Stats::Scalar fpInstQueueWakeupAccesses;
-    Stats::Scalar vecInstQueueReads;
-    Stats::Scalar vecInstQueueWrites;
-    Stats::Scalar vecInstQueueWakeupAccesses;
-
-    Stats::Scalar intAluAccesses;
-    Stats::Scalar fpAluAccesses;
-    Stats::Scalar vecAluAccesses;
+    struct IQIOStats : public Stats::Group
+    {
+        IQIOStats(Stats::Group *parent);
+        Stats::Scalar intInstQueueReads;
+        Stats::Scalar intInstQueueWrites;
+        Stats::Scalar intInstQueueWakeupAccesses;
+        Stats::Scalar fpInstQueueReads;
+        Stats::Scalar fpInstQueueWrites;
+        Stats::Scalar fpInstQueueWakeupAccesses;
+        Stats::Scalar vecInstQueueReads;
+        Stats::Scalar vecInstQueueWrites;
+        Stats::Scalar vecInstQueueWakeupAccesses;
+
+        Stats::Scalar intAluAccesses;
+        Stats::Scalar fpAluAccesses;
+        Stats::Scalar vecAluAccesses;
+    } iqIOStats;
 };
 
 #endif //__CPU_O3_INST_QUEUE_HH__
index 119dcd244d92a4fb3c420824d8824c4e24544b68..5041ab4e72480e5a9a95e9cf56e3df160312e834 100644 (file)
@@ -88,14 +88,15 @@ InstructionQueue<Impl>::InstructionQueue(O3CPU *cpu_ptr, IEW *iew_ptr,
       iewStage(iew_ptr),
       fuPool(params.fuPool),
       iqPolicy(params.smtIQPolicy),
+      numThreads(params.numThreads),
       numEntries(params.numIQEntries),
       totalWidth(params.issueWidth),
-      commitToIEWDelay(params.commitToIEWDelay)
+      commitToIEWDelay(params.commitToIEWDelay),
+      iqStats(cpu, totalWidth),
+      iqIOStats(cpu)
 {
     assert(fuPool);
 
-    numThreads = params.numThreads;
-
     // Set the number of total physical registers
     // As the vector registers have two addressing modes, they are added twice
     numPhysRegs = params.numPhysIntRegs + params.numPhysFloatRegs +
@@ -173,71 +174,70 @@ InstructionQueue<Impl>::name() const
 }
 
 template <class Impl>
-void
-InstructionQueue<Impl>::regStats()
+InstructionQueue<Impl>::
+IQStats::IQStats(O3CPU *cpu, const unsigned &total_width)
+    : Stats::Group(cpu),
+    ADD_STAT(instsAdded,
+             "Number of instructions added to the IQ (excludes non-spec)"),
+    ADD_STAT(nonSpecInstsAdded,
+             "Number of non-speculative instructions added to the IQ"),
+    ADD_STAT(instsIssued, "Number of instructions issued"),
+    ADD_STAT(intInstsIssued, "Number of integer instructions issued"),
+    ADD_STAT(floatInstsIssued, "Number of float instructions issued"),
+    ADD_STAT(branchInstsIssued, "Number of branch instructions issued"),
+    ADD_STAT(memInstsIssued, "Number of memory instructions issued"),
+    ADD_STAT(miscInstsIssued, "Number of miscellaneous instructions issued"),
+    ADD_STAT(squashedInstsIssued, "Number of squashed instructions issued"),
+    ADD_STAT(squashedInstsExamined,
+             "Number of squashed instructions iterated over during squash; "
+             "mainly for profiling"),
+    ADD_STAT(squashedOperandsExamined,
+             "Number of squashed operands that are examined and possibly "
+             "removed from graph"),
+    ADD_STAT(squashedNonSpecRemoved,
+             "Number of squashed non-spec instructions that were removed"),
+    ADD_STAT(numIssuedDist, "Number of insts issued each cycle"),
+    ADD_STAT(statFuBusy, "attempts to use FU when none available"),
+    ADD_STAT(statIssuedInstType, "Type of FU issued"),
+    ADD_STAT(issueRate, "Inst issue rate", instsIssued / cpu->numCycles),
+    ADD_STAT(fuBusy, "FU busy when requested"),
+    ADD_STAT(fuBusyRate, "FU busy rate (busy events/executed inst)")
 {
-    using namespace Stats;
-    iqInstsAdded
-        .name(name() + ".iqInstsAdded")
-        .desc("Number of instructions added to the IQ (excludes non-spec)")
-        .prereq(iqInstsAdded);
-
-    iqNonSpecInstsAdded
-        .name(name() + ".iqNonSpecInstsAdded")
-        .desc("Number of non-speculative instructions added to the IQ")
-        .prereq(iqNonSpecInstsAdded);
-
-    iqInstsIssued
-        .name(name() + ".iqInstsIssued")
-        .desc("Number of instructions issued")
-        .prereq(iqInstsIssued);
-
-    iqIntInstsIssued
-        .name(name() + ".iqIntInstsIssued")
-        .desc("Number of integer instructions issued")
-        .prereq(iqIntInstsIssued);
-
-    iqFloatInstsIssued
-        .name(name() + ".iqFloatInstsIssued")
-        .desc("Number of float instructions issued")
-        .prereq(iqFloatInstsIssued);
-
-    iqBranchInstsIssued
-        .name(name() + ".iqBranchInstsIssued")
-        .desc("Number of branch instructions issued")
-        .prereq(iqBranchInstsIssued);
-
-    iqMemInstsIssued
-        .name(name() + ".iqMemInstsIssued")
-        .desc("Number of memory instructions issued")
-        .prereq(iqMemInstsIssued);
-
-    iqMiscInstsIssued
-        .name(name() + ".iqMiscInstsIssued")
-        .desc("Number of miscellaneous instructions issued")
-        .prereq(iqMiscInstsIssued);
-
-    iqSquashedInstsIssued
-        .name(name() + ".iqSquashedInstsIssued")
-        .desc("Number of squashed instructions issued")
-        .prereq(iqSquashedInstsIssued);
-
-    iqSquashedInstsExamined
-        .name(name() + ".iqSquashedInstsExamined")
-        .desc("Number of squashed instructions iterated over during squash;"
-              " mainly for profiling")
-        .prereq(iqSquashedInstsExamined);
-
-    iqSquashedOperandsExamined
-        .name(name() + ".iqSquashedOperandsExamined")
-        .desc("Number of squashed operands that are examined and possibly "
-              "removed from graph")
-        .prereq(iqSquashedOperandsExamined);
-
-    iqSquashedNonSpecRemoved
-        .name(name() + ".iqSquashedNonSpecRemoved")
-        .desc("Number of squashed non-spec instructions that were removed")
-        .prereq(iqSquashedNonSpecRemoved);
+    instsAdded
+        .prereq(instsAdded);
+
+    nonSpecInstsAdded
+        .prereq(nonSpecInstsAdded);
+
+    instsIssued
+        .prereq(instsIssued);
+
+    intInstsIssued
+        .prereq(intInstsIssued);
+
+    floatInstsIssued
+        .prereq(floatInstsIssued);
+
+    branchInstsIssued
+        .prereq(branchInstsIssued);
+
+    memInstsIssued
+        .prereq(memInstsIssued);
+
+    miscInstsIssued
+        .prereq(miscInstsIssued);
+
+    squashedInstsIssued
+        .prereq(squashedInstsIssued);
+
+    squashedInstsExamined
+        .prereq(squashedInstsExamined);
+
+    squashedOperandsExamined
+        .prereq(squashedOperandsExamined);
+
+    squashedNonSpecRemoved
+        .prereq(squashedNonSpecRemoved);
 /*
     queueResDist
         .init(Num_OpClasses, 0, 99, 2)
@@ -250,10 +250,8 @@ InstructionQueue<Impl>::regStats()
     }
 */
     numIssuedDist
-        .init(0,totalWidth,1)
-        .name(name() + ".issued_per_cycle")
-        .desc("Number of insts issued each cycle")
-        .flags(pdf)
+        .init(0,total_width,1)
+        .flags(Stats::pdf)
         ;
 /*
     dist_unissued
@@ -267,10 +265,8 @@ InstructionQueue<Impl>::regStats()
     }
 */
     statIssuedInstType
-        .init(numThreads,Enums::Num_OpClass)
-        .name(name() + ".FU_type")
-        .desc("Type of FU issued")
-        .flags(total | pdf | dist)
+        .init(cpu->numThreads,Enums::Num_OpClass)
+        .flags(Stats::total | Stats::pdf | Stats::dist)
         ;
     statIssuedInstType.ysubnames(Enums::OpClassStrings);
 
@@ -284,7 +280,6 @@ InstructionQueue<Impl>::regStats()
         .desc("cycles from operands ready to issue")
         .flags(pdf | cdf)
         ;
-
     for (int i=0; i<Num_OpClasses; ++i) {
         std::stringstream subname;
         subname << opClassStrings[i] << "_delay";
@@ -292,101 +287,84 @@ InstructionQueue<Impl>::regStats()
     }
 */
     issueRate
-        .name(name() + ".rate")
-        .desc("Inst issue rate")
-        .flags(total)
+        .flags(Stats::total)
         ;
-    issueRate = iqInstsIssued / cpu->numCycles;
 
     statFuBusy
         .init(Num_OpClasses)
-        .name(name() + ".fu_full")
-        .desc("attempts to use FU when none available")
-        .flags(pdf | dist)
+        .flags(Stats::pdf | Stats::dist)
         ;
     for (int i=0; i < Num_OpClasses; ++i) {
         statFuBusy.subname(i, Enums::OpClassStrings[i]);
     }
 
     fuBusy
-        .init(numThreads)
-        .name(name() + ".fu_busy_cnt")
-        .desc("FU busy when requested")
-        .flags(total)
+        .init(cpu->numThreads)
+        .flags(Stats::total)
         ;
 
     fuBusyRate
-        .name(name() + ".fu_busy_rate")
-        .desc("FU busy rate (busy events/executed inst)")
-        .flags(total)
+        .flags(Stats::total)
         ;
-    fuBusyRate = fuBusy / iqInstsIssued;
-
-    for (ThreadID tid = 0; tid < numThreads; tid++) {
-        // Tell mem dependence unit to reg stats as well.
-        memDepUnit[tid].regStats();
-    }
+    fuBusyRate = fuBusy / instsIssued;
+}
 
+template <class Impl>
+InstructionQueue<Impl>::
+IQIOStats::IQIOStats(Stats::Group *parent)
+    : Stats::Group(parent),
+    ADD_STAT(intInstQueueReads, "Number of integer instruction queue reads"),
+    ADD_STAT(intInstQueueWrites, "Number of integer instruction queue writes"),
+    ADD_STAT(intInstQueueWakeupAccesses, "Number of integer instruction queue "
+                                         "wakeup accesses"),
+    ADD_STAT(fpInstQueueReads, "Number of floating instruction queue reads"),
+    ADD_STAT(fpInstQueueWrites, "Number of floating instruction queue writes"),
+    ADD_STAT(fpInstQueueWakeupAccesses, "Number of floating instruction queue "
+                                        "wakeup accesses"),
+    ADD_STAT(vecInstQueueReads, "Number of vector instruction queue reads"),
+    ADD_STAT(vecInstQueueWrites, "Number of vector instruction queue writes"),
+    ADD_STAT(vecInstQueueWakeupAccesses, "Number of vector instruction queue "
+                                         "wakeup accesses"),
+    ADD_STAT(intAluAccesses, "Number of integer alu accesses"),
+    ADD_STAT(fpAluAccesses, "Number of floating point alu accesses"),
+    ADD_STAT(vecAluAccesses, "Number of vector alu accesses")
+{
+    using namespace Stats;
     intInstQueueReads
-        .name(name() + ".int_inst_queue_reads")
-        .desc("Number of integer instruction queue reads")
         .flags(total);
 
     intInstQueueWrites
-        .name(name() + ".int_inst_queue_writes")
-        .desc("Number of integer instruction queue writes")
         .flags(total);
 
     intInstQueueWakeupAccesses
-        .name(name() + ".int_inst_queue_wakeup_accesses")
-        .desc("Number of integer instruction queue wakeup accesses")
         .flags(total);
 
     fpInstQueueReads
-        .name(name() + ".fp_inst_queue_reads")
-        .desc("Number of floating instruction queue reads")
         .flags(total);
 
     fpInstQueueWrites
-        .name(name() + ".fp_inst_queue_writes")
-        .desc("Number of floating instruction queue writes")
         .flags(total);
 
     fpInstQueueWakeupAccesses
-        .name(name() + ".fp_inst_queue_wakeup_accesses")
-        .desc("Number of floating instruction queue wakeup accesses")
         .flags(total);
 
     vecInstQueueReads
-        .name(name() + ".vec_inst_queue_reads")
-        .desc("Number of vector instruction queue reads")
         .flags(total);
 
     vecInstQueueWrites
-        .name(name() + ".vec_inst_queue_writes")
-        .desc("Number of vector instruction queue writes")
         .flags(total);
 
     vecInstQueueWakeupAccesses
-        .name(name() + ".vec_inst_queue_wakeup_accesses")
-        .desc("Number of vector instruction queue wakeup accesses")
         .flags(total);
 
     intAluAccesses
-        .name(name() + ".int_alu_accesses")
-        .desc("Number of integer alu accesses")
         .flags(total);
 
     fpAluAccesses
-        .name(name() + ".fp_alu_accesses")
-        .desc("Number of floating point alu accesses")
         .flags(total);
 
     vecAluAccesses
-        .name(name() + ".vec_alu_accesses")
-        .desc("Number of vector alu accesses")
         .flags(total);
-
 }
 
 template <class Impl>
@@ -577,11 +555,11 @@ void
 InstructionQueue<Impl>::insert(const DynInstPtr &new_inst)
 {
     if (new_inst->isFloating()) {
-        fpInstQueueWrites++;
+        iqIOStats.fpInstQueueWrites++;
     } else if (new_inst->isVector()) {
-        vecInstQueueWrites++;
+        iqIOStats.vecInstQueueWrites++;
     } else {
-        intInstQueueWrites++;
+        iqIOStats.intInstQueueWrites++;
     }
     // Make sure the instruction is valid
     assert(new_inst);
@@ -611,7 +589,7 @@ InstructionQueue<Impl>::insert(const DynInstPtr &new_inst)
         addIfReady(new_inst);
     }
 
-    ++iqInstsAdded;
+    ++iqStats.instsAdded;
 
     count[new_inst->threadNumber]++;
 
@@ -625,11 +603,11 @@ InstructionQueue<Impl>::insertNonSpec(const DynInstPtr &new_inst)
     // @todo: Clean up this code; can do it by setting inst as unable
     // to issue, then calling normal insert on the inst.
     if (new_inst->isFloating()) {
-        fpInstQueueWrites++;
+        iqIOStats.fpInstQueueWrites++;
     } else if (new_inst->isVector()) {
-        vecInstQueueWrites++;
+        iqIOStats.vecInstQueueWrites++;
     } else {
-        intInstQueueWrites++;
+        iqIOStats.intInstQueueWrites++;
     }
 
     assert(new_inst);
@@ -658,7 +636,7 @@ InstructionQueue<Impl>::insertNonSpec(const DynInstPtr &new_inst)
         memDepUnit[new_inst->threadNumber].insertNonSpec(new_inst);
     }
 
-    ++iqNonSpecInstsAdded;
+    ++iqStats.nonSpecInstsAdded;
 
     count[new_inst->threadNumber]++;
 
@@ -682,11 +660,11 @@ InstructionQueue<Impl>::getInstToExecute()
     DynInstPtr inst = std::move(instsToExecute.front());
     instsToExecute.pop_front();
     if (inst->isFloating()) {
-        fpInstQueueReads++;
+        iqIOStats.fpInstQueueReads++;
     } else if (inst->isVector()) {
-        vecInstQueueReads++;
+        iqIOStats.vecInstQueueReads++;
     } else {
-        intInstQueueReads++;
+        iqIOStats.intInstQueueReads++;
     }
     return inst;
 }
@@ -807,11 +785,11 @@ InstructionQueue<Impl>::scheduleReadyInsts()
         DynInstPtr issuing_inst = readyInsts[op_class].top();
 
         if (issuing_inst->isFloating()) {
-            fpInstQueueReads++;
+            iqIOStats.fpInstQueueReads++;
         } else if (issuing_inst->isVector()) {
-            vecInstQueueReads++;
+            iqIOStats.vecInstQueueReads++;
         } else {
-            intInstQueueReads++;
+            iqIOStats.intInstQueueReads++;
         }
 
         assert(issuing_inst->seqNum == (*order_it).oldestInst);
@@ -828,7 +806,7 @@ InstructionQueue<Impl>::scheduleReadyInsts()
 
             listOrder.erase(order_it++);
 
-            ++iqSquashedInstsIssued;
+            ++iqStats.squashedInstsIssued;
 
             continue;
         }
@@ -840,11 +818,11 @@ InstructionQueue<Impl>::scheduleReadyInsts()
         if (op_class != No_OpClass) {
             idx = fuPool->getUnit(op_class);
             if (issuing_inst->isFloating()) {
-                fpAluAccesses++;
+                iqIOStats.fpAluAccesses++;
             } else if (issuing_inst->isVector()) {
-                vecAluAccesses++;
+                iqIOStats.vecAluAccesses++;
             } else {
-                intAluAccesses++;
+                iqIOStats.intAluAccesses++;
             }
             if (idx > FUPool::NoFreeFU) {
                 op_latency = fuPool->getOpLatency(op_class);
@@ -914,16 +892,16 @@ InstructionQueue<Impl>::scheduleReadyInsts()
             }
 
             listOrder.erase(order_it++);
-            statIssuedInstType[tid][op_class]++;
+            iqStats.statIssuedInstType[tid][op_class]++;
         } else {
-            statFuBusy[op_class]++;
-            fuBusy[tid]++;
+            iqStats.statFuBusy[op_class]++;
+            iqStats.fuBusy[tid]++;
             ++order_it;
         }
     }
 
-    numIssuedDist.sample(total_issued);
-    iqInstsIssued+= total_issued;
+    iqStats.numIssuedDist.sample(total_issued);
+    iqStats.instsIssued+= total_issued;
 
     // If we issued any instructions, tell the CPU we had activity.
     // @todo If the way deferred memory instructions are handeled due to
@@ -990,11 +968,11 @@ InstructionQueue<Impl>::wakeDependents(const DynInstPtr &completed_inst)
 
     // The instruction queue here takes care of both floating and int ops
     if (completed_inst->isFloating()) {
-        fpInstQueueWakeupAccesses++;
+        iqIOStats.fpInstQueueWakeupAccesses++;
     } else if (completed_inst->isVector()) {
-        vecInstQueueWakeupAccesses++;
+        iqIOStats.vecInstQueueWakeupAccesses++;
     } else {
-        intInstQueueWakeupAccesses++;
+        iqIOStats.intInstQueueWakeupAccesses++;
     }
 
     DPRINTF(IQ, "Waking dependents of completed instruction.\n");
@@ -1184,7 +1162,7 @@ void
 InstructionQueue<Impl>::violation(const DynInstPtr &store,
                                   const DynInstPtr &faulting_load)
 {
-    intInstQueueWrites++;
+    iqIOStats.intInstQueueWrites++;
     memDepUnit[store->threadNumber].violation(store, faulting_load);
 }
 
@@ -1223,11 +1201,11 @@ InstructionQueue<Impl>::doSquash(ThreadID tid)
 
         DynInstPtr squashed_inst = (*squash_it);
         if (squashed_inst->isFloating()) {
-            fpInstQueueWrites++;
+            iqIOStats.fpInstQueueWrites++;
         } else if (squashed_inst->isVector()) {
-            vecInstQueueWrites++;
+            iqIOStats.vecInstQueueWrites++;
         } else {
-            intInstQueueWrites++;
+            iqIOStats.intInstQueueWrites++;
         }
 
         // Only handle the instruction if it actually is in the IQ and
@@ -1280,7 +1258,7 @@ InstructionQueue<Impl>::doSquash(ThreadID tid)
                                            squashed_inst);
                     }
 
-                    ++iqSquashedOperandsExamined;
+                    ++iqStats.squashedOperandsExamined;
                 }
 
             } else if (!squashed_inst->isStoreConditional() ||
@@ -1303,7 +1281,7 @@ InstructionQueue<Impl>::doSquash(ThreadID tid)
 
                     nonSpecInsts.erase(ns_inst_it);
 
-                    ++iqSquashedNonSpecRemoved;
+                    ++iqStats.squashedNonSpecRemoved;
                 }
             }
 
@@ -1344,7 +1322,7 @@ InstructionQueue<Impl>::doSquash(ThreadID tid)
             dependGraph.clearInst(dest_reg->flatIndex());
         }
         instList[tid].erase(squash_it--);
-        ++iqSquashedInstsExamined;
+        ++iqStats.squashedInstsExamined;
     }
 }