summaryrefslogtreecommitdiff
path: root/src/cpu/o3/rename_impl.hh
diff options
context:
space:
mode:
authorBinh Pham <binhpham@cs.rutgers.edu>2014-06-21 10:26:43 -0700
committerBinh Pham <binhpham@cs.rutgers.edu>2014-06-21 10:26:43 -0700
commit0782d92286ded450b7e615fefbd5d6d5e738c8cd (patch)
treef69fc67a0957740bab56e11ca9587834da3e18fa /src/cpu/o3/rename_impl.hh
parentfdb965f5c17d8866a63c206e1975460544d8eda9 (diff)
downloadgem5-0782d92286ded450b7e615fefbd5d6d5e738c8cd.tar.xz
o3: split load & store queue full cases in rename
Check for free entries in Load Queue and Store Queue separately to avoid cases when load cannot be renamed due to full Store Queue and vice versa. This work was done while Binh was an intern at AMD Research.
Diffstat (limited to 'src/cpu/o3/rename_impl.hh')
-rw-r--r--src/cpu/o3/rename_impl.hh109
1 files changed, 79 insertions, 30 deletions
diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh
index dcf1d4c66..49abb0055 100644
--- a/src/cpu/o3/rename_impl.hh
+++ b/src/cpu/o3/rename_impl.hh
@@ -131,10 +131,14 @@ DefaultRename<Impl>::regStats()
.name(name() + ".IQFullEvents")
.desc("Number of times rename has blocked due to IQ full")
.prereq(renameIQFullEvents);
- renameLSQFullEvents
- .name(name() + ".LSQFullEvents")
- .desc("Number of times rename has blocked due to LSQ full")
- .prereq(renameLSQFullEvents);
+ renameLQFullEvents
+ .name(name() + ".LQFullEvents")
+ .desc("Number of times rename has blocked due to LQ full")
+ .prereq(renameLQFullEvents);
+ renameSQFullEvents
+ .name(name() + ".SQFullEvents")
+ .desc("Number of times rename has blocked due to SQ full")
+ .prereq(renameSQFullEvents);
renameFullRegistersEvents
.name(name() + ".FullRegisterEvents")
.desc("Number of times there has been no free registers")
@@ -237,7 +241,8 @@ DefaultRename<Impl>::resetStage()
renameStatus[tid] = Idle;
freeEntries[tid].iqEntries = iew_ptr->instQueue.numFreeEntries(tid);
- freeEntries[tid].lsqEntries = iew_ptr->ldstQueue.numFreeEntries(tid);
+ freeEntries[tid].lqEntries = iew_ptr->ldstQueue.numFreeLoadEntries(tid);
+ freeEntries[tid].sqEntries = iew_ptr->ldstQueue.numFreeStoreEntries(tid);
freeEntries[tid].robEntries = commit_ptr->numROBFreeEntries(tid);
emptyROB[tid] = true;
@@ -246,6 +251,8 @@ DefaultRename<Impl>::resetStage()
serializeInst[tid] = NULL;
instsInProgress[tid] = 0;
+ loadsInProgress[tid] = 0;
+ storesInProgress[tid] = 0;
serializeOnNextInst[tid] = false;
}
@@ -420,7 +427,10 @@ DefaultRename<Impl>::tick()
// @todo: make into updateProgress function
for (ThreadID tid = 0; tid < numThreads; tid++) {
instsInProgress[tid] -= fromIEW->iewInfo[tid].dispatched;
-
+ loadsInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToLQ;
+ storesInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToSQ;
+ assert(loadsInProgress[tid] >= 0);
+ assert(storesInProgress[tid] >= 0);
assert(instsInProgress[tid] >=0);
}
@@ -509,7 +519,6 @@ DefaultRename<Impl>::renameInsts(ThreadID tid)
// entries.
int free_rob_entries = calcFreeROBEntries(tid);
int free_iq_entries = calcFreeIQEntries(tid);
- int free_lsq_entries = calcFreeLSQEntries(tid);
int min_free_entries = free_rob_entries;
FullSource source = ROB;
@@ -519,22 +528,15 @@ DefaultRename<Impl>::renameInsts(ThreadID tid)
source = IQ;
}
- if (free_lsq_entries < min_free_entries) {
- min_free_entries = free_lsq_entries;
- source = LSQ;
- }
-
// Check if there's any space left.
if (min_free_entries <= 0) {
- DPRINTF(Rename, "[tid:%u]: Blocking due to no free ROB/IQ/LSQ "
+ DPRINTF(Rename, "[tid:%u]: Blocking due to no free ROB/IQ/ "
"entries.\n"
"ROB has %i free entries.\n"
- "IQ has %i free entries.\n"
- "LSQ has %i free entries.\n",
+ "IQ has %i free entries.\n",
tid,
free_rob_entries,
- free_iq_entries,
- free_lsq_entries);
+ free_iq_entries);
blockThisCycle = true;
@@ -585,6 +587,28 @@ DefaultRename<Impl>::renameInsts(ThreadID tid)
inst = insts_to_rename.front();
+ //For all kind of instructions, check ROB and IQ first
+ //For load instruction, check LQ size and take into account the inflight loads
+ //For store instruction, check SQ size and take into account the inflight stores
+
+ if (inst->isLoad()) {
+ if(calcFreeLQEntries(tid) <= 0) {
+ DPRINTF(Rename, "[tid:%u]: Cannot rename due to no free LQ\n");
+ source = LQ;
+ incrFullStat(source);
+ break;
+ }
+ }
+
+ if (inst->isStore()) {
+ if(calcFreeSQEntries(tid) <= 0) {
+ DPRINTF(Rename, "[tid:%u]: Cannot rename due to no free SQ\n");
+ source = SQ;
+ incrFullStat(source);
+ break;
+ }
+ }
+
insts_to_rename.pop_front();
if (renameStatus[tid] == Unblocking) {
@@ -665,6 +689,12 @@ DefaultRename<Impl>::renameInsts(ThreadID tid)
renameDestRegs(inst, inst->threadNumber);
+ if (inst->isLoad()) {
+ loadsInProgress[tid]++;
+ }
+ if (inst->isStore()) {
+ storesInProgress[tid]++;
+ }
++renamed_insts;
@@ -1122,14 +1152,26 @@ DefaultRename<Impl>::calcFreeIQEntries(ThreadID tid)
template <class Impl>
inline int
-DefaultRename<Impl>::calcFreeLSQEntries(ThreadID tid)
+DefaultRename<Impl>::calcFreeLQEntries(ThreadID tid)
{
- int num_free = freeEntries[tid].lsqEntries -
- (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLSQ);
-
- //DPRINTF(Rename,"[tid:%i]: %i lsq free\n",tid,num_free);
+ int num_free = freeEntries[tid].lqEntries -
+ (loadsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLQ);
+ DPRINTF(Rename, "calcFreeLQEntries: free lqEntries: %d, loadsInProgress: %d, "
+ "loads dispatchedToLQ: %d\n", freeEntries[tid].lqEntries,
+ loadsInProgress[tid], fromIEW->iewInfo[tid].dispatchedToLQ);
+ return num_free;
+}
- return num_free;
+template <class Impl>
+inline int
+DefaultRename<Impl>::calcFreeSQEntries(ThreadID tid)
+{
+ int num_free = freeEntries[tid].sqEntries -
+ (storesInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToSQ);
+ DPRINTF(Rename, "calcFreeSQEntries: free sqEntries: %d, storesInProgress: %d, "
+ "stores dispatchedToSQ: %d\n", freeEntries[tid].sqEntries,
+ storesInProgress[tid], fromIEW->iewInfo[tid].dispatchedToSQ);
+ return num_free;
}
template <class Impl>
@@ -1187,7 +1229,7 @@ DefaultRename<Impl>::checkStall(ThreadID tid)
} else if (calcFreeIQEntries(tid) <= 0) {
DPRINTF(Rename,"[tid:%i]: Stall: IQ has 0 free entries.\n", tid);
ret_val = true;
- } else if (calcFreeLSQEntries(tid) <= 0) {
+ } else if (calcFreeLQEntries(tid) <= 0 && calcFreeSQEntries(tid) <= 0) {
DPRINTF(Rename,"[tid:%i]: Stall: LSQ has 0 free entries.\n", tid);
ret_val = true;
} else if (renameMap[tid]->numFreeEntries() <= 0) {
@@ -1211,8 +1253,10 @@ DefaultRename<Impl>::readFreeEntries(ThreadID tid)
if (fromIEW->iewInfo[tid].usedIQ)
freeEntries[tid].iqEntries = fromIEW->iewInfo[tid].freeIQEntries;
- if (fromIEW->iewInfo[tid].usedLSQ)
- freeEntries[tid].lsqEntries = fromIEW->iewInfo[tid].freeLSQEntries;
+ if (fromIEW->iewInfo[tid].usedLSQ) {
+ freeEntries[tid].lqEntries = fromIEW->iewInfo[tid].freeLQEntries;
+ freeEntries[tid].sqEntries = fromIEW->iewInfo[tid].freeSQEntries;
+ }
if (fromCommit->commitInfo[tid].usedROB) {
freeEntries[tid].robEntries =
@@ -1220,11 +1264,13 @@ DefaultRename<Impl>::readFreeEntries(ThreadID tid)
emptyROB[tid] = fromCommit->commitInfo[tid].emptyROB;
}
- DPRINTF(Rename, "[tid:%i]: Free IQ: %i, Free ROB: %i, Free LSQ: %i\n",
+ DPRINTF(Rename, "[tid:%i]: Free IQ: %i, Free ROB: %i, "
+ "Free LQ: %i, Free SQ: %i\n",
tid,
freeEntries[tid].iqEntries,
freeEntries[tid].robEntries,
- freeEntries[tid].lsqEntries);
+ freeEntries[tid].lqEntries,
+ freeEntries[tid].sqEntries);
DPRINTF(Rename, "[tid:%i]: %i instructions not yet in ROB\n",
tid, instsInProgress[tid]);
@@ -1363,8 +1409,11 @@ DefaultRename<Impl>::incrFullStat(const FullSource &source)
case IQ:
++renameIQFullEvents;
break;
- case LSQ:
- ++renameLSQFullEvents;
+ case LQ:
+ ++renameLQFullEvents;
+ break;
+ case SQ:
+ ++renameSQFullEvents;
break;
default:
panic("Rename full stall stat should be incremented for a reason!");