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:
parent
5ebf3b2808
commit
62f2097917
4 changed files with 16 additions and 4 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue