cpu: Implement per-thread GHRs
authorCurtis Dunham <Curtis.Dunham@arm.com>
Tue, 5 Apr 2016 17:20:19 +0000 (12:20 -0500)
committerCurtis Dunham <Curtis.Dunham@arm.com>
Tue, 5 Apr 2016 17:20:19 +0000 (12:20 -0500)
Branch predictors that use GHRs should index them on a
per-thread basis.  This makes that so.

src/cpu/pred/2bit_local.cc
src/cpu/pred/2bit_local.hh
src/cpu/pred/bi_mode.cc
src/cpu/pred/bi_mode.hh
src/cpu/pred/bpred_unit.cc
src/cpu/pred/bpred_unit.hh
src/cpu/pred/tournament.cc
src/cpu/pred/tournament.hh

index 36ca1593e57432728eef71292b4d5d19fcc03eb9..9e1c781c58b84031e6b543603c22387d1a72ce1c 100644 (file)
@@ -78,7 +78,7 @@ LocalBP::reset()
 }
 
 void
-LocalBP::btbUpdate(Addr branch_addr, void * &bp_history)
+LocalBP::btbUpdate(ThreadID tid, Addr branch_addr, void * &bp_history)
 {
 // Place holder for a function that is called to update predictor history when
 // a BTB entry is invalid or not found.
@@ -86,7 +86,7 @@ LocalBP::btbUpdate(Addr branch_addr, void * &bp_history)
 
 
 bool
-LocalBP::lookup(Addr branch_addr, void * &bp_history)
+LocalBP::lookup(ThreadID tid, Addr branch_addr, void * &bp_history)
 {
     bool taken;
     uint8_t counter_val;
@@ -117,7 +117,8 @@ LocalBP::lookup(Addr branch_addr, void * &bp_history)
 }
 
 void
-LocalBP::update(Addr branch_addr, bool taken, void *bp_history, bool squashed)
+LocalBP::update(ThreadID tid, Addr branch_addr, bool taken, void *bp_history,
+                bool squashed)
 {
     assert(bp_history == NULL);
     unsigned local_predictor_idx;
@@ -152,7 +153,7 @@ LocalBP::getLocalIndex(Addr &branch_addr)
 }
 
 void
-LocalBP::uncondBranch(Addr pc, void *&bp_history)
+LocalBP::uncondBranch(ThreadID tid, Addr pc, void *&bp_history)
 {
 }
 
index 61e2dc24e9853fa1d7f2e8086707e9e1b7b0186d..e3f87491b556b24207f14dc531c85d3b2bc69e2d 100644 (file)
@@ -66,7 +66,7 @@ class LocalBP : public BPredUnit
      */
     LocalBP(const LocalBPParams *params);
 
-    virtual void uncondBranch(Addr pc, void * &bp_history);
+    virtual void uncondBranch(ThreadID tid, Addr pc, void * &bp_history);
 
     /**
      * Looks up the given address in the branch predictor and returns
@@ -75,7 +75,7 @@ class LocalBP : public BPredUnit
      * @param bp_history Pointer to any bp history state.
      * @return Whether or not the branch is taken.
      */
-    bool lookup(Addr branch_addr, void * &bp_history);
+    bool lookup(ThreadID tid, Addr branch_addr, void * &bp_history);
 
     /**
      * Updates the branch predictor to Not Taken if a BTB entry is
@@ -84,19 +84,20 @@ class LocalBP : public BPredUnit
      * @param bp_history Pointer to any bp history state.
      * @return Whether or not the branch is taken.
      */
-    void btbUpdate(Addr branch_addr, void * &bp_history);
+    void btbUpdate(ThreadID tid, Addr branch_addr, void * &bp_history);
 
     /**
      * Updates the branch predictor with the actual result of a branch.
      * @param branch_addr The address of the branch to update.
      * @param taken Whether or not the branch was taken.
      */
-    void update(Addr branch_addr, bool taken, void *bp_history, bool squashed);
+    void update(ThreadID tid, Addr branch_addr, bool taken, void *bp_history,
+                bool squashed);
 
-    void retireSquashed(void *bp_history)
+    void retireSquashed(ThreadID tid, void *bp_history)
     { assert(bp_history == NULL); }
 
-    void squash(void *bp_history)
+    void squash(ThreadID tid, void *bp_history)
     { assert(bp_history == NULL); }
 
     void reset();
index bc974bac8f315c686460d7f171e1682b5199c246..48e798d9681e82e2ed1fd54cbf8051cd26ef41cf 100644 (file)
@@ -38,7 +38,7 @@
 
 BiModeBP::BiModeBP(const BiModeBPParams *params)
     : BPredUnit(params),
-      globalHistoryReg(0),
+      globalHistoryReg(params->numThreads, 0),
       globalHistoryBits(ceilLog2(params->globalPredictorSize)),
       choicePredictorSize(params->choicePredictorSize),
       choiceCtrBits(params->choiceCtrBits),
@@ -77,23 +77,23 @@ BiModeBP::BiModeBP(const BiModeBPParams *params)
  * chooses the taken array and the taken array predicts taken.
  */
 void
-BiModeBP::uncondBranch(Addr pc, void * &bpHistory)
+BiModeBP::uncondBranch(ThreadID tid, Addr pc, void * &bpHistory)
 {
     BPHistory *history = new BPHistory;
-    history->globalHistoryReg = globalHistoryReg;
+    history->globalHistoryReg = globalHistoryReg[tid];
     history->takenUsed = true;
     history->takenPred = true;
     history->notTakenPred = true;
     history->finalPred = true;
     bpHistory = static_cast<void*>(history);
-    updateGlobalHistReg(true);
+    updateGlobalHistReg(tid, true);
 }
 
 void
-BiModeBP::squash(void *bpHistory)
+BiModeBP::squash(ThreadID tid, void *bpHistory)
 {
     BPHistory *history = static_cast<BPHistory*>(bpHistory);
-    globalHistoryReg = history->globalHistoryReg;
+    globalHistoryReg[tid] = history->globalHistoryReg;
 
     delete history;
 }
@@ -108,12 +108,12 @@ BiModeBP::squash(void *bpHistory)
  * direction predictors for the final branch prediction.
  */
 bool
-BiModeBP::lookup(Addr branchAddr, void * &bpHistory)
+BiModeBP::lookup(ThreadID tid, Addr branchAddr, void * &bpHistory)
 {
     unsigned choiceHistoryIdx = ((branchAddr >> instShiftAmt)
                                 & choiceHistoryMask);
     unsigned globalHistoryIdx = (((branchAddr >> instShiftAmt)
-                                ^ globalHistoryReg)
+                                ^ globalHistoryReg[tid])
                                 & globalHistoryMask);
 
     assert(choiceHistoryIdx < choicePredictorSize);
@@ -128,7 +128,7 @@ BiModeBP::lookup(Addr branchAddr, void * &bpHistory)
     bool finalPrediction;
 
     BPHistory *history = new BPHistory;
-    history->globalHistoryReg = globalHistoryReg;
+    history->globalHistoryReg = globalHistoryReg[tid];
     history->takenUsed = choicePrediction;
     history->takenPred = takenGHBPrediction;
     history->notTakenPred = notTakenGHBPrediction;
@@ -141,15 +141,15 @@ BiModeBP::lookup(Addr branchAddr, void * &bpHistory)
 
     history->finalPred = finalPrediction;
     bpHistory = static_cast<void*>(history);
-    updateGlobalHistReg(finalPrediction);
+    updateGlobalHistReg(tid, finalPrediction);
 
     return finalPrediction;
 }
 
 void
-BiModeBP::btbUpdate(Addr branchAddr, void * &bpHistory)
+BiModeBP::btbUpdate(ThreadID tid, Addr branchAddr, void * &bpHistory)
 {
-    globalHistoryReg &= (historyRegisterMask & ~ULL(1));
+    globalHistoryReg[tid] &= (historyRegisterMask & ~ULL(1));
 }
 
 /* Only the selected direction predictor will be updated with the final
@@ -159,7 +159,8 @@ BiModeBP::btbUpdate(Addr branchAddr, void * &bpHistory)
  * the direction predictors makes a correct final prediction.
  */
 void
-BiModeBP::update(Addr branchAddr, bool taken, void *bpHistory, bool squashed)
+BiModeBP::update(ThreadID tid, Addr branchAddr, bool taken, void *bpHistory,
+                 bool squashed)
 {
     if (bpHistory) {
         BPHistory *history = static_cast<BPHistory*>(bpHistory);
@@ -218,11 +219,11 @@ BiModeBP::update(Addr branchAddr, bool taken, void *bpHistory, bool squashed)
 
         if (squashed) {
             if (taken) {
-                globalHistoryReg = (history->globalHistoryReg << 1) | 1;
+                globalHistoryReg[tid] = (history->globalHistoryReg << 1) | 1;
             } else {
-                globalHistoryReg = (history->globalHistoryReg << 1);
+                globalHistoryReg[tid] = (history->globalHistoryReg << 1);
             }
-            globalHistoryReg &= historyRegisterMask;
+            globalHistoryReg[tid] &= historyRegisterMask;
         } else {
             delete history;
         }
@@ -230,24 +231,24 @@ BiModeBP::update(Addr branchAddr, bool taken, void *bpHistory, bool squashed)
 }
 
 void
-BiModeBP::retireSquashed(void *bp_history)
+BiModeBP::retireSquashed(ThreadID tid, void *bp_history)
 {
     BPHistory *history = static_cast<BPHistory*>(bp_history);
     delete history;
 }
 
 unsigned
-BiModeBP::getGHR(void *bp_history) const
+BiModeBP::getGHR(ThreadID tid, void *bp_history) const
 {
     return static_cast<BPHistory*>(bp_history)->globalHistoryReg;
 }
 
 void
-BiModeBP::updateGlobalHistReg(bool taken)
+BiModeBP::updateGlobalHistReg(ThreadID tid, bool taken)
 {
-    globalHistoryReg = taken ? (globalHistoryReg << 1) | 1 :
-                               (globalHistoryReg << 1);
-    globalHistoryReg &= historyRegisterMask;
+    globalHistoryReg[tid] = taken ? (globalHistoryReg[tid] << 1) | 1 :
+                               (globalHistoryReg[tid] << 1);
+    globalHistoryReg[tid] &= historyRegisterMask;
 }
 
 BiModeBP*
index 120a6ffd94fb59d82cce3449597b82ae49fd58d1..96b3b2ef77a5512ed76778a29e49185598e9ee55 100644 (file)
@@ -57,16 +57,17 @@ class BiModeBP : public BPredUnit
 {
   public:
     BiModeBP(const BiModeBPParams *params);
-    void uncondBranch(Addr pc, void * &bp_history);
-    void squash(void *bp_history);
-    bool lookup(Addr branch_addr, void * &bp_history);
-    void btbUpdate(Addr branch_addr, void * &bp_history);
-    void update(Addr branch_addr, bool taken, void *bp_history, bool squashed);
-    void retireSquashed(void *bp_history);
-    unsigned getGHR(void *bp_history) const;
+    void uncondBranch(ThreadID tid, Addr pc, void * &bp_history);
+    void squash(ThreadID tid, void *bp_history);
+    bool lookup(ThreadID tid, Addr branch_addr, void * &bp_history);
+    void btbUpdate(ThreadID tid, Addr branch_addr, void * &bp_history);
+    void update(ThreadID tid, Addr branch_addr, bool taken, void *bp_history,
+                bool squashed);
+    void retireSquashed(ThreadID tid, void *bp_history);
+    unsigned getGHR(ThreadID tid, void *bp_history) const;
 
   private:
-    void updateGlobalHistReg(bool taken);
+    void updateGlobalHistReg(ThreadID tid, bool taken);
 
     struct BPHistory {
         unsigned globalHistoryReg;
@@ -95,7 +96,7 @@ class BiModeBP : public BPredUnit
     // not-taken direction predictors
     std::vector<SatCounter> notTakenCounters;
 
-    unsigned globalHistoryReg;
+    std::vector<unsigned> globalHistoryReg;
     unsigned globalHistoryBits;
     unsigned historyRegisterMask;
 
index 43ac8a60845f708835782476d24c4d5468248355..04a05eaa48e57d87d1505eb3fbc05503ee1f15d3 100644 (file)
@@ -195,10 +195,10 @@ BPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum,
         DPRINTF(Branch, "[tid:%i]: Unconditional control.\n", tid);
         pred_taken = true;
         // Tell the BP there was an unconditional branch.
-        uncondBranch(pc.instAddr(), bp_history);
+        uncondBranch(tid, pc.instAddr(), bp_history);
     } else {
         ++condPredicted;
-        pred_taken = lookup(pc.instAddr(), bp_history);
+        pred_taken = lookup(tid, pc.instAddr(), bp_history);
 
         DPRINTF(Branch, "[tid:%i]: [sn:%i] Branch predictor"
                 " predicted %i for PC %s\n", tid, seqNum,  pred_taken, pc);
@@ -265,7 +265,7 @@ BPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum,
                     // because the BTB did not have an entry
                     // The predictor needs to be updated accordingly
                     if (!inst->isCall() && !inst->isReturn()) {
-                        btbUpdate(pc.instAddr(), bp_history);
+                        btbUpdate(tid, pc.instAddr(), bp_history);
                         DPRINTF(Branch, "[tid:%i]:[sn:%i] btbUpdate"
                                 " called for %s\n", tid, seqNum, pc);
                     } else if (inst->isCall() && !inst->isUncondCtrl()) {
@@ -278,8 +278,8 @@ BPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum,
                 predict_record.wasIndirect = true;
                 ++indirectLookups;
                 //Consult indirect predictor on indirect control
-                if (iPred.lookup(pc.instAddr(), getGHR(bp_history), target,
-                        tid)) {
+                if (iPred.lookup(pc.instAddr(), getGHR(tid, bp_history),
+                        target, tid)) {
                     // Indirect predictor hit
                     ++indirectHits;
                     DPRINTF(Branch, "[tid:%i]: Instruction %s predicted "
@@ -346,7 +346,7 @@ BPredUnit::predictInOrder(const StaticInstPtr &inst, const InstSeqNum &seqNum,
         DPRINTF(Branch, "[tid:%i] Unconditional control.\n", tid);
         pred_taken = true;
         // Tell the BP there was an unconditional branch.
-        uncondBranch(instPC.instAddr(), bp_history);
+        uncondBranch(tid, instPC.instAddr(), bp_history);
 
         if (inst->isReturn() && RAS[tid].empty()) {
             DPRINTF(Branch, "[tid:%i] RAS is empty, predicting "
@@ -356,7 +356,7 @@ BPredUnit::predictInOrder(const StaticInstPtr &inst, const InstSeqNum &seqNum,
     } else {
         ++condPredicted;
 
-        pred_taken = lookup(predPC.instAddr(), bp_history);
+        pred_taken = lookup(tid, predPC.instAddr(), bp_history);
     }
 
     PredictorHistory predict_record(seqNum, predPC.instAddr(), pred_taken,
@@ -451,10 +451,11 @@ BPredUnit::update(const InstSeqNum &done_sn, ThreadID tid)
            predHist[tid].back().seqNum <= done_sn) {
         // Update the branch predictor with the correct results.
         if (!predHist[tid].back().wasSquashed) {
-            update(predHist[tid].back().pc, predHist[tid].back().predTaken,
-                predHist[tid].back().bpHistory, false);
+            update(tid, predHist[tid].back().pc,
+                        predHist[tid].back().predTaken,
+                        predHist[tid].back().bpHistory, false);
         } else {
-            retireSquashed(predHist[tid].back().bpHistory);
+            retireSquashed(tid, predHist[tid].back().bpHistory);
         }
 
         predHist[tid].pop_back();
@@ -485,7 +486,7 @@ BPredUnit::squash(const InstSeqNum &squashed_sn, ThreadID tid)
         }
 
         // This call should delete the bpHistory.
-        squash(pred_hist.front().bpHistory);
+        squash(tid, pred_hist.front().bpHistory);
 
         DPRINTF(Branch, "[tid:%i]: Removing history for [sn:%i] "
                 "PC %s.\n", tid, pred_hist.front().seqNum,
@@ -550,9 +551,9 @@ BPredUnit::squash(const InstSeqNum &squashed_sn,
         }
 
         // Have to get GHR here because the update deletes bpHistory
-        unsigned ghr = getGHR(hist_it->bpHistory);
+        unsigned ghr = getGHR(tid, hist_it->bpHistory);
 
-        update((*hist_it).pc, actually_taken,
+        update(tid, (*hist_it).pc, actually_taken,
                pred_hist.front().bpHistory, true);
         hist_it->wasSquashed = true;
 
index fb10a8beef0f756d863ad8f0435cd17c4a41c599..c5e73f59df47ab3b3bbdc792fc38fcfc7fd43e96 100644 (file)
@@ -98,7 +98,7 @@ class BPredUnit : public SimObject
                         TheISA::PCState &predPC, ThreadID tid);
 
     // @todo: Rename this function.
-    virtual void uncondBranch(Addr pc, void * &bp_history) = 0;
+    virtual void uncondBranch(ThreadID tid, Addr pc, void * &bp_history) = 0;
 
     /**
      * Tells the branch predictor to commit any updates until the given
@@ -133,7 +133,7 @@ class BPredUnit : public SimObject
      * @param bp_history Pointer to the history object.  The predictor
      * will need to update any state and delete the object.
      */
-    virtual void squash(void *bp_history) = 0;
+    virtual void squash(ThreadID tid, void *bp_history) = 0;
 
     /**
      * Looks up a given PC in the BP to see if it is taken or not taken.
@@ -142,7 +142,7 @@ class BPredUnit : public SimObject
      * has the branch predictor state associated with the lookup.
      * @return Whether the branch is taken or not taken.
      */
-    virtual bool lookup(Addr instPC, void * &bp_history) = 0;
+    virtual bool lookup(ThreadID tid, Addr instPC, void * &bp_history) = 0;
 
      /**
      * If a branch is not taken, because the BTB address is invalid or missing,
@@ -152,7 +152,7 @@ class BPredUnit : public SimObject
      * @param bp_history Pointer that will be set to an object that
      * has the branch predictor state associated with the lookup.
      */
-    virtual void btbUpdate(Addr instPC, void * &bp_history) = 0;
+    virtual void btbUpdate(ThreadID tid, Addr instPC, void * &bp_history) = 0;
 
     /**
      * Looks up a given PC in the BTB to see if a matching entry exists.
@@ -180,15 +180,15 @@ class BPredUnit : public SimObject
      * squash operation.
      * @todo Make this update flexible enough to handle a global predictor.
      */
-    virtual void update(Addr instPC, bool taken, void *bp_history,
-                        bool squashed) = 0;
+    virtual void update(ThreadID tid, Addr instPC, bool taken,
+                        void *bp_history, bool squashed) = 0;
      /**
      * Deletes the associated history with a branch, performs no predictor
      * updates.  Used for branches that mispredict and update tables but
      * are still speculative and later retire.
      * @param bp_history History to delete associated with this predictor
      */
-    virtual void retireSquashed(void *bp_history) = 0;
+    virtual void retireSquashed(ThreadID tid, void *bp_history) = 0;
 
     /**
      * Updates the BTB with the target of a branch.
@@ -199,7 +199,7 @@ class BPredUnit : public SimObject
     { BTB.update(instPC, target, 0); }
 
 
-    virtual unsigned getGHR(void* bp_history) const { return 0; }
+    virtual unsigned getGHR(ThreadID tid, void* bp_history) const { return 0; }
 
     void dump();
 
index 2dd48a09c4a244867b18b7c057d7238dbb1832cf..319606871291812b85c0ef59011cc71cb36fc611 100644 (file)
@@ -52,6 +52,7 @@ TournamentBP::TournamentBP(const TournamentBPParams *params)
       localHistoryBits(ceilLog2(params->localPredictorSize)),
       globalPredictorSize(params->globalPredictorSize),
       globalCtrBits(params->globalCtrBits),
+      globalHistory(params->numThreads, 0),
       globalHistoryBits(
           ceilLog2(params->globalPredictorSize) >
           ceilLog2(params->choicePredictorSize) ?
@@ -92,8 +93,6 @@ TournamentBP::TournamentBP(const TournamentBPParams *params)
     for (int i = 0; i < globalPredictorSize; ++i)
         globalCtrs[i].setBits(globalCtrBits);
 
-    //Clear the global history
-    globalHistory = 0;
     // Set up the global history mask
     // this is equivalent to mask(log2(globalPredictorSize)
     globalHistoryMask = globalPredictorSize - 1;
@@ -145,18 +144,18 @@ TournamentBP::calcLocHistIdx(Addr &branch_addr)
 
 inline
 void
-TournamentBP::updateGlobalHistTaken()
+TournamentBP::updateGlobalHistTaken(ThreadID tid)
 {
-    globalHistory = (globalHistory << 1) | 1;
-    globalHistory = globalHistory & historyRegisterMask;
+    globalHistory[tid] = (globalHistory[tid] << 1) | 1;
+    globalHistory[tid] = globalHistory[tid] & historyRegisterMask;
 }
 
 inline
 void
-TournamentBP::updateGlobalHistNotTaken()
+TournamentBP::updateGlobalHistNotTaken(ThreadID tid)
 {
-    globalHistory = (globalHistory << 1);
-    globalHistory = globalHistory & historyRegisterMask;
+    globalHistory[tid] = (globalHistory[tid] << 1);
+    globalHistory[tid] = globalHistory[tid] & historyRegisterMask;
 }
 
 inline
@@ -177,18 +176,18 @@ TournamentBP::updateLocalHistNotTaken(unsigned local_history_idx)
 
 
 void
-TournamentBP::btbUpdate(Addr branch_addr, void * &bp_history)
+TournamentBP::btbUpdate(ThreadID tid, Addr branch_addr, void * &bp_history)
 {
     unsigned local_history_idx = calcLocHistIdx(branch_addr);
     //Update Global History to Not Taken (clear LSB)
-    globalHistory &= (historyRegisterMask & ~ULL(1));
+    globalHistory[tid] &= (historyRegisterMask & ~ULL(1));
     //Update Local History to Not Taken
     localHistoryTable[local_history_idx] =
        localHistoryTable[local_history_idx] & (localPredictorMask & ~ULL(1));
 }
 
 bool
-TournamentBP::lookup(Addr branch_addr, void * &bp_history)
+TournamentBP::lookup(ThreadID tid, Addr branch_addr, void * &bp_history)
 {
     bool local_prediction;
     unsigned local_history_idx;
@@ -204,16 +203,16 @@ TournamentBP::lookup(Addr branch_addr, void * &bp_history)
     local_prediction = localCtrs[local_predictor_idx].read() > localThreshold;
 
     //Lookup in the global predictor to get its branch prediction
-    global_prediction =
-      globalCtrs[globalHistory & globalHistoryMask].read() > globalThreshold;
+    global_prediction = globalThreshold <
+      globalCtrs[globalHistory[tid] & globalHistoryMask].read();
 
     //Lookup in the choice predictor to see which one to use
-    choice_prediction =
-      choiceCtrs[globalHistory & choiceHistoryMask].read() > choiceThreshold;
+    choice_prediction = choiceThreshold <
+      choiceCtrs[globalHistory[tid] & choiceHistoryMask].read();
 
     // Create BPHistory and pass it back to be recorded.
     BPHistory *history = new BPHistory;
-    history->globalHistory = globalHistory;
+    history->globalHistory = globalHistory[tid];
     history->localPredTaken = local_prediction;
     history->globalPredTaken = global_prediction;
     history->globalUsed = choice_prediction;
@@ -227,21 +226,21 @@ TournamentBP::lookup(Addr branch_addr, void * &bp_history)
     // all histories.
     if (choice_prediction) {
         if (global_prediction) {
-            updateGlobalHistTaken();
+            updateGlobalHistTaken(tid);
             updateLocalHistTaken(local_history_idx);
             return true;
         } else {
-            updateGlobalHistNotTaken();
+            updateGlobalHistNotTaken(tid);
             updateLocalHistNotTaken(local_history_idx);
             return false;
         }
     } else {
         if (local_prediction) {
-            updateGlobalHistTaken();
+            updateGlobalHistTaken(tid);
             updateLocalHistTaken(local_history_idx);
             return true;
         } else {
-            updateGlobalHistNotTaken();
+            updateGlobalHistNotTaken(tid);
             updateLocalHistNotTaken(local_history_idx);
             return false;
         }
@@ -249,11 +248,11 @@ TournamentBP::lookup(Addr branch_addr, void * &bp_history)
 }
 
 void
-TournamentBP::uncondBranch(Addr pc, void * &bp_history)
+TournamentBP::uncondBranch(ThreadID tid, Addr pc, void * &bp_history)
 {
     // Create BPHistory and pass it back to be recorded.
     BPHistory *history = new BPHistory;
-    history->globalHistory = globalHistory;
+    history->globalHistory = globalHistory[tid];
     history->localPredTaken = true;
     history->globalPredTaken = true;
     history->globalUsed = true;
@@ -261,12 +260,12 @@ TournamentBP::uncondBranch(Addr pc, void * &bp_history)
     history->localHistory = invalidPredictorIndex;
     bp_history = static_cast<void *>(history);
 
-    updateGlobalHistTaken();
+    updateGlobalHistTaken(tid);
 }
 
 void
-TournamentBP::update(Addr branch_addr, bool taken, void *bp_history,
-                     bool squashed)
+TournamentBP::update(ThreadID tid, Addr branch_addr, bool taken,
+                     void *bp_history, bool squashed)
 {
     unsigned local_history_idx;
     unsigned local_predictor_idx M5_VAR_USED;
@@ -332,15 +331,15 @@ TournamentBP::update(Addr branch_addr, bool taken, void *bp_history,
         }
         if (squashed) {
              if (taken) {
-                globalHistory = (history->globalHistory << 1) | 1;
-                globalHistory = globalHistory & historyRegisterMask;
+                globalHistory[tid] = (history->globalHistory << 1) | 1;
+                globalHistory[tid] = globalHistory[tid] & historyRegisterMask;
                 if (old_local_pred_valid) {
                     localHistoryTable[local_history_idx] =
                      (history->localHistory << 1) | 1;
                 }
              } else {
-                globalHistory = (history->globalHistory << 1);
-                globalHistory = globalHistory & historyRegisterMask;
+                globalHistory[tid] = (history->globalHistory << 1);
+                globalHistory[tid] = globalHistory[tid] & historyRegisterMask;
                 if (old_local_pred_valid) {
                      localHistoryTable[local_history_idx] =
                      history->localHistory << 1;
@@ -359,19 +358,19 @@ TournamentBP::update(Addr branch_addr, bool taken, void *bp_history,
 }
 
 void
-TournamentBP::retireSquashed(void *bp_history)
+TournamentBP::retireSquashed(ThreadID tid, void *bp_history)
 {
     BPHistory *history = static_cast<BPHistory *>(bp_history);
     delete history;
 }
 
 void
-TournamentBP::squash(void *bp_history)
+TournamentBP::squash(ThreadID tid, void *bp_history)
 {
     BPHistory *history = static_cast<BPHistory *>(bp_history);
 
     // Restore global history to state prior to this branch.
-    globalHistory = history->globalHistory;
+    globalHistory[tid] = history->globalHistory;
 
     // Restore local history
     if (history->localHistoryIdx != invalidPredictorIndex) {
@@ -389,7 +388,7 @@ TournamentBPParams::create()
 }
 
 unsigned
-TournamentBP::getGHR(void *bp_history) const
+TournamentBP::getGHR(ThreadID tid, void *bp_history) const
 {
     return static_cast<BPHistory *>(bp_history)->globalHistory;
 }
index 82a1daa64dea630c4036bf49ac3626100c490f08..3aa17e03041f36b0ca694813ba7801c4bf333bc1 100644 (file)
@@ -77,7 +77,7 @@ class TournamentBP : public BPredUnit
      * @param bp_history Pointer that will be set to the BPHistory object.
      * @return Whether or not the branch is taken.
      */
-    bool lookup(Addr branch_addr, void * &bp_history);
+    bool lookup(ThreadID tid, Addr branch_addr, void * &bp_history);
 
     /**
      * Records that there was an unconditional branch, and modifies
@@ -85,7 +85,7 @@ class TournamentBP : public BPredUnit
      * global history stored in it.
      * @param bp_history Pointer that will be set to the BPHistory object.
      */
-    void uncondBranch(Addr pc, void * &bp_history);
+    void uncondBranch(ThreadID tid, Addr pc, void * &bp_history);
     /**
      * Updates the branch predictor to Not Taken if a BTB entry is
      * invalid or not found.
@@ -93,7 +93,7 @@ class TournamentBP : public BPredUnit
      * @param bp_history Pointer to any bp history state.
      * @return Whether or not the branch is taken.
      */
-    void btbUpdate(Addr branch_addr, void * &bp_history);
+    void btbUpdate(ThreadID tid, Addr branch_addr, void * &bp_history);
     /**
      * Updates the branch predictor with the actual result of a branch.
      * @param branch_addr The address of the branch to update.
@@ -103,21 +103,19 @@ class TournamentBP : public BPredUnit
      * @param squashed is set when this function is called during a squash
      * operation.
      */
-    void update(Addr branch_addr, bool taken, void *bp_history, bool squashed);
+    void update(ThreadID tid, Addr branch_addr, bool taken, void *bp_history,
+                bool squashed);
 
-    void retireSquashed(void *bp_history);
+    void retireSquashed(ThreadID tid, void *bp_history);
 
     /**
      * Restores the global branch history on a squash.
      * @param bp_history Pointer to the BPHistory object that has the
      * previous global branch history in it.
      */
-    void squash(void *bp_history);
+    void squash(ThreadID tid, void *bp_history);
 
-    unsigned getGHR(void *bp_history) const;
-
-    /** Returns the global history. */
-    inline unsigned readGlobalHist() { return globalHistory; }
+    unsigned getGHR(ThreadID tid, void *bp_history) const;
 
   private:
     /**
@@ -134,10 +132,10 @@ class TournamentBP : public BPredUnit
     inline unsigned calcLocHistIdx(Addr &branch_addr);
 
     /** Updates global history as taken. */
-    inline void updateGlobalHistTaken();
+    inline void updateGlobalHistTaken(ThreadID tid);
 
     /** Updates global history as not taken. */
-    inline void updateGlobalHistNotTaken();
+    inline void updateGlobalHistNotTaken(ThreadID tid);
 
     /**
      * Updates local histories as taken.
@@ -211,7 +209,7 @@ class TournamentBP : public BPredUnit
     /** Global history register. Contains as much history as specified by
      *  globalHistoryBits. Actual number of bits used is determined by
      *  globalHistoryMask and choiceHistoryMask. */
-    unsigned globalHistory;
+    std::vector<unsigned> globalHistory;
 
     /** Number of bits for the global history. Determines maximum number of
         entries in global and choice predictor tables. */