diff options
author | Mitch Hayenga <mitch.hayenga@arm.com> | 2016-04-05 12:20:19 -0500 |
---|---|---|
committer | Mitch Hayenga <mitch.hayenga@arm.com> | 2016-04-05 12:20:19 -0500 |
commit | d99deff8ea296fd28b48da08aba577a1e7dfc01b (patch) | |
tree | bb8645f94f33b45b040776e5e0dd0a0d8edb306f | |
parent | 0fd4bb7f12d8a633f3ff0abe61d4f3a78bca6f84 (diff) | |
download | gem5-d99deff8ea296fd28b48da08aba577a1e7dfc01b.tar.xz |
cpu: Implement per-thread GHRs
Branch predictors that use GHRs should index them on a
per-thread basis. This makes that so.
This is a re-spin of fb51231 after the revert (bd1c6789).
-rw-r--r-- | src/cpu/pred/2bit_local.cc | 9 | ||||
-rw-r--r-- | src/cpu/pred/2bit_local.hh | 13 | ||||
-rw-r--r-- | src/cpu/pred/bi_mode.cc | 45 | ||||
-rw-r--r-- | src/cpu/pred/bi_mode.hh | 19 | ||||
-rw-r--r-- | src/cpu/pred/bpred_unit.cc | 27 | ||||
-rw-r--r-- | src/cpu/pred/bpred_unit.hh | 16 | ||||
-rw-r--r-- | src/cpu/pred/tournament.cc | 65 | ||||
-rw-r--r-- | src/cpu/pred/tournament.hh | 24 |
8 files changed, 110 insertions, 108 deletions
diff --git a/src/cpu/pred/2bit_local.cc b/src/cpu/pred/2bit_local.cc index 36ca1593e..9e1c781c5 100644 --- a/src/cpu/pred/2bit_local.cc +++ b/src/cpu/pred/2bit_local.cc @@ -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) { } diff --git a/src/cpu/pred/2bit_local.hh b/src/cpu/pred/2bit_local.hh index 61e2dc24e..e3f87491b 100644 --- a/src/cpu/pred/2bit_local.hh +++ b/src/cpu/pred/2bit_local.hh @@ -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(); diff --git a/src/cpu/pred/bi_mode.cc b/src/cpu/pred/bi_mode.cc index bc974bac8..48e798d96 100644 --- a/src/cpu/pred/bi_mode.cc +++ b/src/cpu/pred/bi_mode.cc @@ -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* diff --git a/src/cpu/pred/bi_mode.hh b/src/cpu/pred/bi_mode.hh index 120a6ffd9..96b3b2ef7 100644 --- a/src/cpu/pred/bi_mode.hh +++ b/src/cpu/pred/bi_mode.hh @@ -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; diff --git a/src/cpu/pred/bpred_unit.cc b/src/cpu/pred/bpred_unit.cc index d12e9f9f7..91e43f50e 100644 --- a/src/cpu/pred/bpred_unit.cc +++ b/src/cpu/pred/bpred_unit.cc @@ -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; diff --git a/src/cpu/pred/bpred_unit.hh b/src/cpu/pred/bpred_unit.hh index fb10a8bee..c5e73f59d 100644 --- a/src/cpu/pred/bpred_unit.hh +++ b/src/cpu/pred/bpred_unit.hh @@ -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(); diff --git a/src/cpu/pred/tournament.cc b/src/cpu/pred/tournament.cc index 2dd48a09c..319606871 100644 --- a/src/cpu/pred/tournament.cc +++ b/src/cpu/pred/tournament.cc @@ -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; } diff --git a/src/cpu/pred/tournament.hh b/src/cpu/pred/tournament.hh index 82a1daa64..3aa17e030 100644 --- a/src/cpu/pred/tournament.hh +++ b/src/cpu/pred/tournament.hh @@ -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. */ |