43#include "debug/Fetch.hh"
44#include "debug/Tage.hh"
78 noSkip.resize(nHistoryTables + 1, true);
112 history.pathHist = 0;
113 history.nonSpecPathHist = 0;
115 history.gHist = history.globalHistory;
162 DPRINTF(Tage,
"HistLength:%d, TTSize:%d, TTTWidth:%d\n",
200 A = A & ((1ULL << size) - 1);
246 assert(nbits <=
sizeof(T) << 3);
248 if (ctr < ((1 << (nbits - 1)) - 1))
251 if (ctr > -(1 << (nbits - 1)))
264 assert(nbits <=
sizeof(uint8_t) << 3);
266 if (ctr < ((1 << nbits) - 1))
292 }
else if (inter > 0) {
295 const bool pred = inter >> 1;
296 const bool hyst = inter & 1;
299 DPRINTF(Tage,
"Updating branch %lx, pred:%d, hyst:%d\n",
pc,
pred, hyst);
312 DPRINTF(Tage,
"Rolling over the histories\n");
326 for (
int i = 0;
i <
n;
i++) {
331 *(tHist.
gHist) = (bv & 1) ? 1 : 0;
370 assert(
bi->branchPC == branch_pc);
377 bi->bimodalIndex =
bindex(branch_pc);
391 for (
int i =
bi->hitBank - 1;
i > 0;
i--) {
400 if (
bi->hitBank > 0) {
401 if (
bi->altBank > 0) {
409 bi->longestMatchPred =
412 abs(2 *
gtable[
bi->hitBank][
bi->hitBankIndex].ctr + 1) <= 1;
418 || !
bi->pseudoNewAlloc) {
419 bi->tagePred =
bi->longestMatchPred;
422 bi->tagePred =
bi->altTaken;
428 bi->tagePred =
bi->altTaken;
429 bi->longestMatchPred =
bi->altTaken;
433 DPRINTF(Tage,
"Predict for %lx: tagePred:%d, altPred:%d\n",
434 branch_pc,
bi->tagePred,
bi->altTaken);
463 int X =
bi->hitBank + 1;
476 unsigned numAllocated = 0;
480 gtable[
i][
bi->tableIndices[
i]].ctr = (taken) ? 0 : -1;
523 if (preAdjustAlloc) {
527 if (
bi->hitBank > 0) {
530 bool PseudoNewAlloc =
bi->pseudoNewAlloc;
533 if (PseudoNewAlloc) {
534 if (
bi->longestMatchPred == taken) {
539 if (
bi->longestMatchPred !=
bi->altTaken) {
547 if (!preAdjustAlloc) {
559 if (
bi->hitBank > 0) {
560 DPRINTF(Tage,
"Updating tag table entry (%d,%d) for branch %lx\n",
561 bi->hitBank,
bi->hitBankIndex, branch_pc);
566 if (
gtable[
bi->hitBank][
bi->hitBankIndex].u == 0) {
567 if (
bi->altBank > 0) {
570 DPRINTF(Tage,
"Updating tag table entry (%d,%d) for"
571 " branch %lx\n",
bi->hitBank,
bi->hitBankIndex,
574 if (
bi->altBank == 0) {
580 if (
bi->tagePred !=
bi->altTaken) {
600 bi->ghist = taken ? 1 : 0;
609 bool taken,
Addr target,
641 if (!
bi->valid &&
bi->condBranch) {
647 assert(
bi->nGhist == 0);
652 branch_pc, target,
bi);
655 DPRINTF(Tage,
"Updating global histories with branch:%lx; taken?:%d, "
656 "path Hist: %x; pointer:%d\n", branch_pc, taken,
695 for (
int n = 0;
n <
bi->nGhist;
n++) {
707 bi->modified =
false;
714 cur_phist = (cur_phist << 1) + pathbit;
736 if (taken ==
bi->tagePred) {
738 switch (
bi->provider) {
742 stats.bimodalAltMatchProviderCorrect++;
748 switch (
bi->provider) {
751 stats.longestMatchProviderWrong++;
752 if (
bi->altTaken == taken) {
753 stats.altMatchProviderWouldHaveHit++;
757 stats.bimodalAltMatchProviderWrong++;
760 stats.altMatchProviderWrong++;
764 switch (
bi->provider) {
767 if (
bi->longestMatchPred == taken) {
768 stats.longestMatchProviderWouldHaveHit++;
773 switch (
bi->provider) {
776 stats.longestMatchProvider[
bi->hitBank]++;
777 stats.altMatchProvider[
bi->altBank]++;
787 for (
unsigned i = 0;
i < 16;
i++) {
801 "Number of times TAGE Longest Match is the provider and the "
802 "prediction is correct"),
804 "Number of times TAGE Alt Match is the provider and the "
805 "prediction is correct"),
807 "Number of times TAGE Alt Match is the bimodal and it is the "
808 "provider and the prediction is correct"),
810 "Number of times there are no hits on the TAGE tables and the "
811 "bimodal prediction is correct"),
813 "Number of times TAGE Longest Match is the provider and the "
814 "prediction is wrong"),
816 "Number of times TAGE Alt Match is the provider and the "
817 "prediction is wrong"),
819 "Number of times TAGE Alt Match is the bimodal and it is the "
820 "provider and the prediction is wrong"),
822 "Number of times there are no hits on the TAGE tables and the "
823 "bimodal prediction is wrong"),
825 "Number of times TAGE Longest Match is the provider, the "
826 "prediction is wrong and Alt Match prediction was correct"),
828 "Number of times TAGE Alt Match is the provider, the "
829 "prediction is wrong and Longest Match prediction was correct"),
831 "TAGE provider for longest match"),
833 "TAGE provider for alt match")
842 return gtable[hitBank][hitBankIndex].ctr;
873 bits += bimodalTableSize;
int getPathHist(ThreadID tid, bool speculative=true) const
TAGEBase(const TAGEBaseParams &p)
virtual int branchTypeExtra(const StaticInstPtr &inst)
This function acts as a hook for other TAGE implementations to adjust the branch type.
virtual BranchInfo * makeBranchInfo(Addr pc, bool conditional)
const unsigned tagTableUBits
virtual void handleAllocAndUReset(bool alloc, bool taken, BranchInfo *bi, int nrand)
Handles Allocation and U bits reset on an update.
virtual void initFoldedHistories(ThreadHistory &history)
Initialization of the folded histories.
static void ctrUpdate(T &ctr, bool taken, int nbits)
Updates a direction counter based on the actual branch outcome.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
bool isSpeculativeUpdateEnabled() const
virtual unsigned getUseAltIdx(BranchInfo *bi, Addr branch_pc)
Calculation of the index for useAltPredForNewlyAllocated On this base TAGE implementation it is alway...
virtual void resetUctr(uint8_t &u)
Algorithm for resetting a single U counter.
virtual void extraAltCalc(BranchInfo *bi)
Extra steps for calculating altTaken For this base TAGE class it does nothing.
int calcNewPathHist(ThreadID tid, Addr pc, int cur_phist) const
static void unsignedCtrUpdate(uint8_t &ctr, bool up, unsigned nbits)
Updates an unsigned counter based on up/down parameter.
unsigned getTageCtrBits() const
virtual void handleUReset()
Handles the U bits reset.
virtual void updateStats(bool taken, BranchInfo *bi)
Update the stats.
virtual void calculateParameters()
Calculates the history lengths and some other paramters in derived classes.
const unsigned logRatioBiModalHystEntries
std::vector< bool > btableHysteresis
std::vector< bool > btablePrediction
const unsigned histBufferSize
const unsigned nHistoryTables
virtual void adjustAlloc(bool &alloc, bool taken, bool pred_taken)
Extra calculation to tell whether TAGE allocaitons may happen or not on an update For this base TAGE ...
void recordHistState(ThreadID tid, BranchInfo *bi)
Records the current state of the histories to be able to restore it in case of a mispredicted specula...
std::vector< ThreadHistory > threadHistory
virtual void calculateIndicesAndTags(ThreadID tid, Addr branch_pc, BranchInfo *bi)
On a prediction, calculates the TAGE indices and tags for all the different history lengths.
virtual bool getBimodePred(Addr pc, BranchInfo *bi) const
Get a branch prediction from the bimodal predictor.
const unsigned pathHistBits
int8_t getCtr(int hitBank, int hitBankIndex) const
virtual void squash(ThreadID tid, bool taken, Addr target, const StaticInstPtr &inst, BranchInfo *bi)
Restores speculatively updated path and direction histories.
virtual uint16_t gtag(ThreadID tid, Addr pc, int bank) const
Computes the partial tag of a tagged table.
std::vector< int > logTagTableSizes
void baseUpdate(Addr pc, bool taken, BranchInfo *bi)
Updates the bimodal predictor.
const unsigned instShiftAmt
virtual int F(int phist, int size, int bank) const
Utility function to shuffle the path history depending on which tagged table we are accessing.
bool tagePredict(ThreadID tid, Addr branch_pc, bool cond_branch, BranchInfo *bi)
TAGE prediction called from TAGE::predict.
std::vector< int8_t > useAltPredForNewlyAllocated
unsigned getGHR(ThreadID tid) const
virtual void updatePathAndGlobalHistory(ThreadID tid, int brtype, bool taken, Addr branch_pc, Addr target, BranchInfo *bi)
Does the actual update of path and global history.
std::vector< bool > noSkip
const bool speculativeHistUpdate
virtual void updateHistories(ThreadID tid, Addr branch_pc, bool speculative, bool taken, Addr target, const StaticInstPtr &inst, BranchInfo *bi)
(Speculatively) updates global histories (path and direction).
std::vector< unsigned > tagTableTagWidths
const unsigned tagTableCounterBits
gem5::branch_prediction::TAGEBase::TAGEBaseStats stats
virtual void condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken, BranchInfo *bi, int nrand, Addr corrTarget, bool pred, bool preAdjustAlloc=false)
Update TAGE for conditional branches.
virtual void buildTageTables()
Instantiates the TAGE table entries.
void updateGHist(ThreadID tid, uint64_t bv, uint8_t n)
Internal history update function.
const int64_t initialTCounterValue
virtual int gindex(ThreadID tid, Addr pc, int bank) const
Computes the index used to access a partially tagged table.
virtual void handleTAGEUpdate(Addr branch_pc, bool taken, BranchInfo *bi)
Handles the update of the TAGE entries.
size_t getSizeInBits() const
virtual int bindex(Addr pc_in) const
Computes the index used to access the bimodal table.
void restoreHistState(ThreadID tid, BranchInfo *bi)
Restore the state of the histories in case of detecting a mispredicted speculative update.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
SimObject(const Params &p)
Copyright (c) 2024 Arm Limited All rights reserved.
int16_t ThreadID
Thread index/ID type.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
RefCountingPtr< StaticInst > StaticInstPtr
void init(int original_length, int compressed_length)
statistics::Scalar longestMatchProviderCorrect
statistics::Vector longestMatchProvider
statistics::Scalar altMatchProviderCorrect
statistics::Scalar bimodalAltMatchProviderCorrect
statistics::Scalar bimodalAltMatchProviderWrong
statistics::Scalar longestMatchProviderWouldHaveHit
statistics::Scalar longestMatchProviderWrong
statistics::Scalar bimodalProviderWrong
statistics::Vector altMatchProvider
TAGEBaseStats(statistics::Group *parent, unsigned nHistoryTables)
statistics::Scalar bimodalProviderCorrect
statistics::Scalar altMatchProviderWouldHaveHit
statistics::Scalar altMatchProviderWrong
FoldedHistory * computeIndices
FoldedHistory * computeTags[2]