cpu-o3: bugfix of rename squash when SMT
In an SMT CPU, upon a squash, the phys regs used by mispredicted instructions can still be owned by executing instructions in IEW. If the regs are added back to freelist on this tick, the reg may be renamed to be used by another SMT thread. This causes reg ownership hazard, which may eventually freeze the CPU. This patch delays the freelist update to avoid the hazard. Change-Id: I993b3c7d357269f01146db61fc8a7b83a989ea45
This commit is contained in:
@@ -940,8 +940,11 @@ Rename::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid)
|
||||
// previous physical register that it was renamed to.
|
||||
renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
|
||||
|
||||
// Put the renamed physical register back on the free list.
|
||||
freeList->addReg(hb_it->newPhysReg);
|
||||
// The phys regs can still be owned by squashing but
|
||||
// executing instructions in IEW at this moment. To avoid
|
||||
// ownership hazard in SMT CPU, we delay the freelist update
|
||||
// until they are indeed squashed in the commit stage.
|
||||
freeingInProgress[tid].push_back(hb_it->newPhysReg);
|
||||
}
|
||||
|
||||
// Notify potential listeners that the register mapping needs to be
|
||||
@@ -1296,6 +1299,18 @@ Rename::checkSignalsAndUpdate(ThreadID tid)
|
||||
squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
|
||||
|
||||
return true;
|
||||
} else if (!fromCommit->commitInfo[tid].robSquashing &&
|
||||
!freeingInProgress[tid].empty()) {
|
||||
DPRINTF(Rename, "[tid:%i] Freeing phys regs of misspeculated "
|
||||
"instructions.\n", tid);
|
||||
|
||||
auto reg_it = freeingInProgress[tid].cbegin();
|
||||
while ( reg_it != freeingInProgress[tid].cend()){
|
||||
// Put the renamed physical register back on the free list.
|
||||
freeList->addReg(*reg_it);
|
||||
++reg_it;
|
||||
}
|
||||
freeingInProgress[tid].clear();
|
||||
}
|
||||
|
||||
if (checkStall(tid)) {
|
||||
|
||||
@@ -359,6 +359,9 @@ class Rename
|
||||
/** Free list interface. */
|
||||
UnifiedFreeList *freeList;
|
||||
|
||||
/** Hold phys regs to be released after squash finish */
|
||||
std::vector<PhysRegIdPtr> freeingInProgress[MaxThreads];
|
||||
|
||||
/** Pointer to the list of active threads. */
|
||||
std::list<ThreadID> *activeThreads;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user