summaryrefslogtreecommitdiff
path: root/cpu/o3/lsq_unit.hh
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/o3/lsq_unit.hh')
-rw-r--r--cpu/o3/lsq_unit.hh53
1 files changed, 35 insertions, 18 deletions
diff --git a/cpu/o3/lsq_unit.hh b/cpu/o3/lsq_unit.hh
index a6afff743..fe174a97d 100644
--- a/cpu/o3/lsq_unit.hh
+++ b/cpu/o3/lsq_unit.hh
@@ -101,6 +101,9 @@ class LSQUnit {
/** Returns the name of the LSQ unit. */
std::string name() const;
+ /** Registers statistics. */
+ void regStats();
+
/** Sets the CPU pointer. */
void setCPU(FullCPU *cpu_ptr)
{ cpu = cpu_ptr; }
@@ -153,9 +156,6 @@ class LSQUnit {
/** Writes back stores. */
void writebackStores();
- // @todo: Include stats in the LSQ unit.
- //void regStats();
-
/** Clears all the entries in the LQ. */
void clearLQ();
@@ -369,25 +369,34 @@ class LSQUnit {
// 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::Vector<> lsq_forw_loads;
+ /** Total number of loads forwaded from LSQ stores. */
+ Stats::Scalar<> lsqForwLoads;
+
+ /** Total number of loads ignored due to invalid addresses. */
+ Stats::Scalar<> invAddrLoads;
+
+ /** Total number of squashed loads. */
+ Stats::Scalar<> lsqSquashedLoads;
- // total number of loads ignored due to invalid addresses
- Stats::Vector<> inv_addr_loads;
+ /** Total number of responses from the memory system that are
+ * ignored due to the instruction already being squashed. */
+ Stats::Scalar<> lsqIgnoredResponses;
- // total number of software prefetches ignored due to invalid addresses
- Stats::Vector<> inv_addr_swpfs;
+ /** Total number of squashed stores. */
+ Stats::Scalar<> lsqSquashedStores;
- // total non-speculative bogus addresses seen (debug var)
- Counter sim_invalid_addrs;
- Stats::Vector<> fu_busy; //cumulative fu busy
+ /** Total number of software prefetches ignored due to invalid addresses. */
+ Stats::Scalar<> invAddrSwpfs;
- // ready loads blocked due to memory disambiguation
- Stats::Vector<> lsq_blocked_loads;
+ /** 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;
- Stats::Scalar<> lsqInversion;
-*/
public:
/** Executes the load at the given index. */
template <class T>
@@ -441,8 +450,9 @@ LSQUnit<Impl>::read(MemReqPtr &req, T &data, int load_idx)
// at the head of the LSQ and are ready to commit (at the head of the ROB
// too).
if (req->flags & UNCACHEABLE &&
- (load_idx != loadHead || !loadQueue[load_idx]->reachedCommit)) {
+ (load_idx != loadHead || !loadQueue[load_idx]->isAtCommit())) {
iewStage->rescheduleMemInst(loadQueue[load_idx]);
+ ++lsqRescheduledLoads;
return TheISA::genMachineCheckFault();
}
@@ -552,6 +562,8 @@ LSQUnit<Impl>::read(MemReqPtr &req, T &data, int load_idx)
// Tell IQ/mem dep unit that this instruction will need to be
// rescheduled eventually
iewStage->rescheduleMemInst(loadQueue[load_idx]);
+ iewStage->decrWb(loadQueue[load_idx]->seqNum);
+ ++lsqRescheduledLoads;
// Do not generate a writeback event as this instruction is not
// complete.
@@ -559,6 +571,7 @@ LSQUnit<Impl>::read(MemReqPtr &req, T &data, int load_idx)
"Store idx %i to load addr %#x\n",
store_idx, req->vaddr);
+ ++lsqBlockedLoads;
return NoFault;
}
}
@@ -579,6 +592,10 @@ LSQUnit<Impl>::read(MemReqPtr &req, T &data, int load_idx)
// if we have a cache, do cache access too
if (fault == NoFault && dcacheInterface) {
if (dcacheInterface->isBlocked()) {
+ ++lsqCacheBlocked;
+
+ iewStage->decrWb(inst->seqNum);
+
// There's an older load that's already going to squash.
if (isLoadBlocked && blockedLoadSeqNum < inst->seqNum)
return NoFault;