O3: Track if the RAS has been pushed or not to pop the RAS if neccessary.
authorNathanael Premillieu <npremill@irisa.fr>
Fri, 29 Jun 2012 15:18:29 +0000 (11:18 -0400)
committerNathanael Premillieu <npremill@irisa.fr>
Fri, 29 Jun 2012 15:18:29 +0000 (11:18 -0400)
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.

src/cpu/o3/bpred_unit.hh
src/cpu/o3/bpred_unit_impl.hh

index 8bfab11a9939f1c48a89eefe079ba88c022bd991..c1afb4720c9a3aeb51acaab756fc7e46bd85420a 100644 (file)
@@ -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;
 
index 1e75de90c3e054877ae74a597901f691c52bb566..6f0e5e3e0ccf9c89f2a83c353ca698d92902df30 100644 (file)
@@ -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,