probe: Add probe in Fetch, IEW, Rename and Commit
authorRadhika Jagtap <radhika.jagtap@ARM.com>
Mon, 7 Dec 2015 22:42:15 +0000 (16:42 -0600)
committerRadhika Jagtap <radhika.jagtap@ARM.com>
Mon, 7 Dec 2015 22:42:15 +0000 (16:42 -0600)
This patch adds probe points in Fetch, IEW, Rename and Commit stages as follows.

A probe point is added in the Fetch stage for probing when a fetch request is
sent. Notify is fired on the probe point when a request is sent succesfully in
the first attempt as well as on a retry attempt.

Probe points are added in the IEW stage when an instruction begins to execute
and when execution is complete. This points can be used for monitoring the
execution time of an instruction.

Probe points are added in the Rename stage to probe renaming of source and
destination registers and when there is squashing. These probe points can be
used to track register dependencies and remove when there is squashing.

A probe point for squashing is added in Commit to probe squashed instructions.

src/cpu/o3/commit.hh
src/cpu/o3/commit_impl.hh
src/cpu/o3/cpu.cc
src/cpu/o3/fetch.hh
src/cpu/o3/fetch_impl.hh
src/cpu/o3/iew.hh
src/cpu/o3/iew_impl.hh
src/cpu/o3/rename.hh
src/cpu/o3/rename_impl.hh

index 6688a70dc8cbdf0797f709e9051ddabe827c0dee..48c169389a1ada86f602fef16fa7067c406673f4 100644 (file)
@@ -154,6 +154,8 @@ class DefaultCommit
     /** Probe Points. */
     ProbePointArg<DynInstPtr> *ppCommit;
     ProbePointArg<DynInstPtr> *ppCommitStall;
+    /** To probe when an instruction is squashed */
+    ProbePointArg<DynInstPtr> *ppSquash;
 
   public:
     /** Construct a DefaultCommit with the given parameters. */
index 5323e141335f63c361934c04e3988072f1316ba9..c6c6ea723fae508a253017b848a6de7adc9418c9 100644 (file)
@@ -173,6 +173,7 @@ DefaultCommit<Impl>::regProbePoints()
 {
     ppCommit = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Commit");
     ppCommitStall = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "CommitStall");
+    ppSquash = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Squash");
 }
 
 template <class Impl>
@@ -1010,6 +1011,8 @@ DefaultCommit<Impl>::commitInsts()
             rob->retireHead(commit_thread);
 
             ++commitSquashedInsts;
+            // Notify potential listeners that this instruction is squashed
+            ppSquash->notify(head_inst);
 
             // Record that the number of ROB entries has changed.
             changedROBNumEntries[tid] = true;
index 665654f6892dd2b36fe1115104f58d2d4389a8e4..69476216711b5442098f33ea791328644e5eef41 100644 (file)
@@ -416,6 +416,7 @@ FullO3CPU<Impl>::regProbePoints()
     ppDataAccessComplete = new ProbePointArg<std::pair<DynInstPtr, PacketPtr> >(getProbeManager(), "DataAccessComplete");
 
     fetch.regProbePoints();
+    rename.regProbePoints();
     iew.regProbePoints();
     commit.regProbePoints();
 }
index 536568bc27c908ec4f00d4d5cbeb829acd7f47cd..672fb499be63a7861449c5f1252409ed3a158641 100644 (file)
@@ -197,6 +197,8 @@ class DefaultFetch
 
     /** Probe points. */
     ProbePointArg<DynInstPtr> *ppFetch;
+    /** To probe when a fetch request is successfully sent. */
+    ProbePointArg<RequestPtr> *ppFetchRequestSent;
 
   public:
     /** DefaultFetch constructor. */
index cb123afd28e89709e44808d84fc7353166f11ada..4b1479bcbc3d6f03d29635e797f8f677f3b3b498 100644 (file)
@@ -171,6 +171,9 @@ void
 DefaultFetch<Impl>::regProbePoints()
 {
     ppFetch = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Fetch");
+    ppFetchRequestSent = new ProbePointArg<RequestPtr>(cpu->getProbeManager(),
+                                                       "FetchRequest");
+
 }
 
 template <class Impl>
@@ -695,6 +698,9 @@ DefaultFetch<Impl>::finishTranslation(const Fault &fault, RequestPtr mem_req)
                     "response.\n", tid);
             lastIcacheStall[tid] = curTick();
             fetchStatus[tid] = IcacheWaitResponse;
+            // Notify Fetch Request probe when a packet containing a fetch
+            // request is successfully sent
+            ppFetchRequestSent->notify(mem_req);
         }
     } else {
         // Don't send an instruction to decode if we can't handle it.
@@ -1422,6 +1428,9 @@ DefaultFetch<Impl>::recvReqRetry()
 
         if (cpu->getInstPort().sendTimingReq(retryPkt)) {
             fetchStatus[retryTid] = IcacheWaitResponse;
+            // Notify Fetch Request probe when a retryPkt is successfully sent.
+            // Note that notify must be called before retryPkt is set to NULL.
+            ppFetchRequestSent->notify(retryPkt->req);
             retryPkt = NULL;
             retryTid = InvalidThreadID;
             cacheBlocked = false;
index 957a085aef9fa0d102209cb440ff8edd8b3ab9f2..de8834005de44fbbdc6c25640ca17d6879e365b7 100644 (file)
@@ -126,6 +126,10 @@ class DefaultIEW
     /** Probe points. */
     ProbePointArg<DynInstPtr> *ppMispredict;
     ProbePointArg<DynInstPtr> *ppDispatch;
+    /** To probe when instruction execution begins. */
+    ProbePointArg<DynInstPtr> *ppExecute;
+    /** To probe when instruction execution is complete. */
+    ProbePointArg<DynInstPtr> *ppToCommit;
 
   public:
     /** Constructs a DefaultIEW with the given parameters. */
index ae76aa9e144b25a24b6d1a27291fbe44e7948fc8..e02429b14bee62d11d0de8a8b62cea509edb1a4d 100644 (file)
@@ -125,6 +125,18 @@ DefaultIEW<Impl>::regProbePoints()
 {
     ppDispatch = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Dispatch");
     ppMispredict = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Mispredict");
+    /**
+     * Probe point with dynamic instruction as the argument used to probe when
+     * an instruction starts to execute.
+     */
+    ppExecute = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(),
+                                              "Execute");
+    /**
+     * Probe point with dynamic instruction as the argument used to probe when
+     * an instruction execution completes and it is marked ready to commit.
+     */
+    ppToCommit = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(),
+                                               "ToCommit");
 }
 
 template <class Impl>
@@ -1190,6 +1202,10 @@ DefaultIEW<Impl>::executeInsts()
         DPRINTF(IEW, "Execute: Processing PC %s, [tid:%i] [sn:%i].\n",
                 inst->pcState(), inst->threadNumber,inst->seqNum);
 
+        // Notify potential listeners that this instruction has started
+        // executing
+        ppExecute->notify(inst);
+
         // Check if the instruction is squashed; if so then skip it
         if (inst->isSquashed()) {
             DPRINTF(IEW, "Execute: Instruction was squashed. PC: %s, [tid:%i]"
@@ -1402,6 +1418,9 @@ DefaultIEW<Impl>::writebackInsts()
                 inst->seqNum, inst->pcState());
 
         iewInstsToCommit[tid]++;
+        // Notify potential listeners that execution is complete for this
+        // instruction.
+        ppToCommit->notify(inst);
 
         // Some instructions will be sent to commit without having
         // executed because they need commit to handle them.
index a543cefb81c8659c9c8f7e95e0329fc9398ad0f4..f8becc114157e3ed1d9508e7c22320e28ae116a0 100644 (file)
 #define __CPU_O3_RENAME_HH__
 
 #include <list>
+#include <utility>
 
 #include "base/statistics.hh"
 #include "config/the_isa.hh"
 #include "cpu/timebuf.hh"
+#include "sim/probe/probe.hh"
 
 struct DerivO3CPUParams;
 
@@ -119,6 +121,16 @@ class DefaultRename
     /** Per-thread status. */
     ThreadStatus renameStatus[Impl::MaxThreads];
 
+    /** Probe points. */
+    typedef typename std::pair<InstSeqNum, short int> SeqNumRegPair;
+    /** To probe when register renaming for an instruction is complete */
+    ProbePointArg<DynInstPtr> *ppRename;
+    /**
+     * To probe when an instruction is squashed and the register mapping
+     * for it needs to be undone
+     */
+    ProbePointArg<SeqNumRegPair> *ppSquashInRename;
+
   public:
     /** DefaultRename constructor. */
     DefaultRename(O3CPU *_cpu, DerivO3CPUParams *params);
@@ -129,6 +141,9 @@ class DefaultRename
     /** Registers statistics. */
     void regStats();
 
+    /** Registers probes. */
+    void regProbePoints();
+
     /** Sets the main backwards communication time buffer pointer. */
     void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
 
index 43b7ba9aa18057228be8ae577a34cd2c42d7cd8a..b19b3414cd10ffbfea30f42634fa04a0ca654293 100644 (file)
@@ -184,6 +184,15 @@ DefaultRename<Impl>::regStats()
         .prereq(fpRenameLookups);
 }
 
+template <class Impl>
+void
+DefaultRename<Impl>::regProbePoints()
+{
+    ppRename = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Rename");
+    ppSquashInRename = new ProbePointArg<SeqNumRegPair>(cpu->getProbeManager(),
+                                                        "SquashInRename");
+}
+
 template <class Impl>
 void
 DefaultRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
@@ -697,7 +706,9 @@ DefaultRename<Impl>::renameInsts(ThreadID tid)
                 storesInProgress[tid]++;
         }
         ++renamed_insts;
-
+        // Notify potential listeners that source and destination registers for
+        // this instruction have been renamed.
+        ppRename->notify(inst);
 
         // Put instruction in rename queue.
         toIEW->insts[toIEWIndex] = inst;
@@ -929,6 +940,12 @@ DefaultRename<Impl>::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid)
             freeList->addReg(hb_it->newPhysReg);
         }
 
+        // Notify potential listeners that the register mapping needs to be
+        // removed because the instruction it was mapped to got squashed. Note
+        // that this is done before hb_it is incremented.
+        ppSquashInRename->notify(std::make_pair(hb_it->instSeqNum,
+                                                hb_it->newPhysReg));
+
         historyBuffer[tid].erase(hb_it++);
 
         ++renameUndoneMaps;