O3: Fix mispredicts from non control instructions.

The squash inside the fetch unit should not attempt to remove them from the
branch predictor as non-control instructions are not pushed into the predictor.
This commit is contained in:
Matt Horsnell 2011-01-18 16:30:05 -06:00
parent 5ebf3b2808
commit 62f2097917
4 changed files with 16 additions and 4 deletions

View file

@ -87,6 +87,7 @@ struct DefaultIEWDefaultCommit {
bool squash[Impl::MaxThreads];
bool branchMispredict[Impl::MaxThreads];
DynInstPtr mispredictInst[Impl::MaxThreads];
bool branchTaken[Impl::MaxThreads];
Addr mispredPC[Impl::MaxThreads];
TheISA::PCState pc[Impl::MaxThreads];
@ -107,6 +108,7 @@ struct IssueStruct {
/** Struct that defines all backwards communication. */
template<class Impl>
struct TimeBufStruct {
typedef typename Impl::DynInstPtr DynInstPtr;
struct decodeComm {
bool squash;
bool predIncorrect;
@ -117,6 +119,7 @@ struct TimeBufStruct {
// @todo: Might want to package this kind of branch stuff into a single
// struct as it is used pretty frequently.
bool branchMispredict;
DynInstPtr mispredictInst;
bool branchTaken;
Addr mispredPC;
TheISA::PCState nextPC;
@ -156,6 +159,7 @@ struct TimeBufStruct {
bool robSquashing;
bool branchMispredict;
DynInstPtr mispredictInst;
bool branchTaken;
Addr mispredPC;
TheISA::PCState pc;
@ -175,7 +179,6 @@ struct TimeBufStruct {
InstSeqNum nonSpecSeqNum;
// Hack for now to send back an uncached access to the IEW stage.
typedef typename Impl::DynInstPtr DynInstPtr;
bool uncached;
DynInstPtr uncachedLoad;

View file

@ -520,6 +520,7 @@ DefaultCommit<Impl>::squashAll(ThreadID tid)
toIEW->commitInfo[tid].robSquashing = true;
toIEW->commitInfo[tid].branchMispredict = false;
toIEW->commitInfo[tid].mispredictInst = NULL;
toIEW->commitInfo[tid].pc = pc[tid];
}
@ -814,7 +815,8 @@ DefaultCommit<Impl>::commit()
toIEW->commitInfo[tid].branchMispredict =
fromIEW->branchMispredict[tid];
toIEW->commitInfo[tid].mispredictInst =
fromIEW->mispredictInst[tid];
toIEW->commitInfo[tid].branchTaken =
fromIEW->branchTaken[tid];

View file

@ -902,8 +902,14 @@ DefaultFetch<Impl>::checkSignalsAndUpdate(ThreadID tid)
fromCommit->commitInfo[tid].doneSeqNum,
tid);
// Also check if there's a mispredict that happened.
if (fromCommit->commitInfo[tid].branchMispredict) {
// If it was a branch mispredict on a control instruction, update the
// branch predictor with that instruction, otherwise just kill the
// invalid state we generated in after sequence number
assert(!fromCommit->commitInfo[tid].branchMispredict ||
fromCommit->commitInfo[tid].mispredictInst);
if (fromCommit->commitInfo[tid].branchMispredict &&
fromCommit->commitInfo[tid].mispredictInst->isControl()) {
branchPred.squash(fromCommit->commitInfo[tid].doneSeqNum,
fromCommit->commitInfo[tid].pc,
fromCommit->commitInfo[tid].branchTaken,

View file

@ -456,6 +456,7 @@ DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, ThreadID tid)
toCommit->squashedSeqNum[tid] = inst->seqNum;
toCommit->mispredPC[tid] = inst->instAddr();
toCommit->branchMispredict[tid] = true;
toCommit->mispredictInst[tid] = inst;
toCommit->branchTaken[tid] = inst->pcState().branching();
TheISA::PCState pc = inst->pcState();