O3: Track if the RAS has been pushed or not to pop the RAS if neccessary.
Add new flag (named pushedRAS) in the PredictorHistory structure. This flag tracks whether the RAS has been pushed or not during a prediction. Then, in the squash function it is used to pop the RAS if necessary.
This commit is contained in:
@@ -207,7 +207,7 @@ class BPredUnit
|
||||
bool pred_taken, void *bp_history,
|
||||
ThreadID _tid)
|
||||
: seqNum(seq_num), pc(instPC), bpHistory(bp_history), RASTarget(0),
|
||||
RASIndex(0), tid(_tid), predTaken(pred_taken), usedRAS(0),
|
||||
RASIndex(0), tid(_tid), predTaken(pred_taken), usedRAS(0), pushedRAS(0),
|
||||
wasCall(0), wasReturn(0), validBTB(0)
|
||||
{}
|
||||
|
||||
@@ -242,6 +242,9 @@ class BPredUnit
|
||||
/** Whether or not the RAS was used. */
|
||||
bool usedRAS;
|
||||
|
||||
/* Wether or not the RAS was pushed */
|
||||
bool pushedRAS;
|
||||
|
||||
/** Whether or not the instruction was a call. */
|
||||
bool wasCall;
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ BPredUnit<Impl>::predict(DynInstPtr &inst, TheISA::PCState &pc, ThreadID tid)
|
||||
|
||||
if (inst->isCall()) {
|
||||
RAS[tid].push(pc);
|
||||
|
||||
predict_record.pushedRAS = true;
|
||||
// Record that it was a call so that the top RAS entry can
|
||||
// be popped off if the speculation is incorrect.
|
||||
predict_record.wasCall = true;
|
||||
@@ -253,6 +253,7 @@ BPredUnit<Impl>::predict(DynInstPtr &inst, TheISA::PCState &pc, ThreadID tid)
|
||||
tid, inst->seqNum, inst->pcState());
|
||||
} else if (inst->isCall() && !inst->isUncondCtrl()) {
|
||||
RAS[tid].pop();
|
||||
predict_record.pushedRAS = false;
|
||||
}
|
||||
TheISA::advancePC(target, inst->staticInst);
|
||||
}
|
||||
@@ -308,7 +309,7 @@ BPredUnit<Impl>::squash(const InstSeqNum &squashed_sn, ThreadID tid)
|
||||
|
||||
RAS[tid].restore(pred_hist.front().RASIndex,
|
||||
pred_hist.front().RASTarget);
|
||||
} else if(pred_hist.front().wasCall && pred_hist.front().validBTB) {
|
||||
} else if(pred_hist.front().wasCall && pred_hist.front().pushedRAS) {
|
||||
// Was a call but predicated false. Pop RAS here
|
||||
DPRINTF(Fetch, "BranchPred: [tid: %i] Squashing"
|
||||
" Call [sn:%i] PC: %s Popping RAS\n", tid,
|
||||
@@ -408,7 +409,7 @@ BPredUnit<Impl>::squash(const InstSeqNum &squashed_sn,
|
||||
hist_it->RASIndex, hist_it->RASTarget);
|
||||
RAS[tid].restore(hist_it->RASIndex, hist_it->RASTarget);
|
||||
|
||||
} else if (hist_it->wasCall && hist_it->validBTB) {
|
||||
} else if (hist_it->wasCall && hist_it->pushedRAS) {
|
||||
//Was a Call but predicated false. Pop RAS here
|
||||
DPRINTF(Fetch, "BranchPred: [tid: %i] Incorrectly predicted"
|
||||
" Call [sn:%i] PC: %s Popping RAS\n", tid,
|
||||
|
||||
Reference in New Issue
Block a user