42#include "debug/Fetch.hh"
43#include "debug/Tage.hh"
48namespace branch_prediction
53 logRatioBiModalHystEntries(
p.logRatioBiModalHystEntries),
54 nHistoryTables(
p.nHistoryTables),
55 tagTableCounterBits(
p.tagTableCounterBits),
56 tagTableUBits(
p.tagTableUBits),
57 histBufferSize(
p.histBufferSize),
60 pathHistBits(
p.pathHistBits),
61 tagTableTagWidths(
p.tagTableTagWidths),
62 logTagTableSizes(
p.logTagTableSizes),
63 threadHistory(
p.numThreads),
64 logUResetPeriod(
p.logUResetPeriod),
65 initialTCounterValue(
p.initialTCounterValue),
66 numUseAltOnNa(
p.numUseAltOnNa),
67 useAltOnNaBits(
p.useAltOnNaBits),
68 maxNumAlloc(
p.maxNumAlloc),
70 speculativeHistUpdate(
p.speculativeHistUpdate),
71 instShiftAmt(
p.instShiftAmt),
73 stats(this, nHistoryTables)
111 history.pathHist = 0;
113 history.gHist = history.globalHistory;
160 DPRINTF(Tage,
"HistLength:%d, TTSize:%d, TTTWidth:%d\n",
192 DPRINTF(Tage,
"BTB miss resets prediction: %lx\n", branch_pc);
217 A = A & ((1ULL << size) - 1);
263 assert(nbits <=
sizeof(T) << 3);
265 if (ctr < ((1 << (nbits - 1)) - 1))
268 if (ctr > -(1 << (nbits - 1)))
281 assert(nbits <=
sizeof(uint8_t) << 3);
283 if (ctr < ((1 << nbits) - 1))
309 }
else if (inter > 0) {
312 const bool pred = inter >> 1;
313 const bool hyst = inter & 1;
316 DPRINTF(Tage,
"Updating branch %lx, pred:%d, hyst:%d\n",
pc,
pred, hyst);
325 DPRINTF(Tage,
"Rolling over the histories\n");
336 h[0] = (dir) ? 1 : 0;
364 bool pred_taken =
true;
385 for (
int i =
bi->hitBank - 1;
i > 0;
i--) {
394 if (
bi->hitBank > 0) {
395 if (
bi->altBank > 0) {
403 bi->longestMatchPred =
412 || !
bi->pseudoNewAlloc) {
413 bi->tagePred =
bi->longestMatchPred;
416 bi->tagePred =
bi->altTaken;
422 bi->tagePred =
bi->altTaken;
423 bi->longestMatchPred =
bi->altTaken;
428 pred_taken = (
bi->tagePred);
429 DPRINTF(Tage,
"Predict for %lx: taken?:%d, tagePred:%d, altPred:%d\n",
430 branch_pc, pred_taken,
bi->tagePred,
bi->altTaken);
432 bi->branchPC = branch_pc;
433 bi->condBranch = cond_branch;
461 int X =
bi->hitBank + 1;
474 unsigned numAllocated = 0;
521 if (preAdjustAlloc) {
525 if (
bi->hitBank > 0) {
528 bool PseudoNewAlloc =
bi->pseudoNewAlloc;
531 if (PseudoNewAlloc) {
532 if (
bi->longestMatchPred == taken) {
537 if (
bi->longestMatchPred !=
bi->altTaken) {
545 if (!preAdjustAlloc) {
557 if (
bi->hitBank > 0) {
558 DPRINTF(Tage,
"Updating tag table entry (%d,%d) for branch %lx\n",
559 bi->hitBank,
bi->hitBankIndex, branch_pc);
564 if (
gtable[
bi->hitBank][
bi->hitBankIndex].
u == 0) {
565 if (
bi->altBank > 0) {
568 DPRINTF(Tage,
"Updating tag table entry (%d,%d) for"
569 " branch %lx\n",
bi->hitBank,
bi->hitBankIndex,
572 if (
bi->altBank == 0) {
578 if (
bi->tagePred !=
bi->altTaken) {
621 DPRINTF(Tage,
"Updating global histories with branch:%lx; taken?:%d, "
622 "path Hist: %x; pointer:%d\n", branch_pc, taken, tHist.
pathHist,
638 DPRINTF(Tage,
"Restoring branch info: %lx; taken? %d; PathHistory:%x, "
639 "pointer:%d\n",
bi->branchPC,taken,
bi->pathHist,
bi->ptGhist);
643 tHist.
gHist[0] = (taken ? 1 : 0);
664 if (taken ==
bi->tagePred) {
666 switch (
bi->provider) {
676 switch (
bi->provider) {
680 if (
bi->altTaken == taken) {
692 switch (
bi->provider) {
695 if (
bi->longestMatchPred == taken) {
701 switch (
bi->provider) {
714 for (
unsigned i = 0;
i < 32;
i++) {
716 int gh_offset =
bi->ptGhist +
i;
727 : statistics::
Group(parent),
728 ADD_STAT(longestMatchProviderCorrect, statistics::units::Count::get(),
729 "Number of times TAGE Longest Match is the provider and the "
730 "prediction is correct"),
731 ADD_STAT(altMatchProviderCorrect, statistics::units::Count::get(),
732 "Number of times TAGE Alt Match is the provider and the "
733 "prediction is correct"),
734 ADD_STAT(bimodalAltMatchProviderCorrect, statistics::units::Count::get(),
735 "Number of times TAGE Alt Match is the bimodal and it is the "
736 "provider and the prediction is correct"),
737 ADD_STAT(bimodalProviderCorrect, statistics::units::Count::get(),
738 "Number of times there are no hits on the TAGE tables and the "
739 "bimodal prediction is correct"),
740 ADD_STAT(longestMatchProviderWrong, statistics::units::Count::get(),
741 "Number of times TAGE Longest Match is the provider and the "
742 "prediction is wrong"),
743 ADD_STAT(altMatchProviderWrong, statistics::units::Count::get(),
744 "Number of times TAGE Alt Match is the provider and the "
745 "prediction is wrong"),
746 ADD_STAT(bimodalAltMatchProviderWrong, statistics::units::Count::get(),
747 "Number of times TAGE Alt Match is the bimodal and it is the "
748 "provider and the prediction is wrong"),
749 ADD_STAT(bimodalProviderWrong, statistics::units::Count::get(),
750 "Number of times there are no hits on the TAGE tables and the "
751 "bimodal prediction is wrong"),
752 ADD_STAT(altMatchProviderWouldHaveHit, statistics::units::Count::get(),
753 "Number of times TAGE Longest Match is the provider, the "
754 "prediction is wrong and Alt Match prediction was correct"),
755 ADD_STAT(longestMatchProviderWouldHaveHit, statistics::units::Count::get(),
756 "Number of times TAGE Alt Match is the provider, the "
757 "prediction is wrong and Longest Match prediction was correct"),
758 ADD_STAT(longestMatchProvider, statistics::units::Count::get(),
759 "TAGE provider for longest match"),
760 ADD_STAT(altMatchProvider, statistics::units::Count::get(),
761 "TAGE provider for alt match")
770 return gtable[hitBank][hitBankIndex].
ctr;
800 bits += bimodalTableSize;
Abstract superclass for simulation objects.
TAGEBase(const TAGEBaseParams &p)
virtual void updateHistories(ThreadID tid, Addr branch_pc, bool taken, BranchInfo *b, bool speculative, const StaticInstPtr &inst=nullStaticInstPtr, Addr target=MaxAddr)
(Speculatively) updates global histories (path and direction).
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 BranchInfo * makeBranchInfo()
virtual void extraAltCalc(BranchInfo *bi)
Extra steps for calculating altTaken For this base TAGE class it does nothing.
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
void updateGHist(uint8_t *&h, bool dir, uint8_t *tab, int &PT)
(Speculatively) updates the global branch history.
unsigned getGHR(ThreadID tid, BranchInfo *bi) const
std::vector< bool > btablePrediction
const unsigned histBufferSize
void btbUpdate(ThreadID tid, Addr branch_addr, BranchInfo *&bi)
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 ...
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 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 void squash(ThreadID tid, bool taken, BranchInfo *bi, Addr target)
Restores speculatively updated path and direction histories.
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
std::vector< bool > noSkip
const bool speculativeHistUpdate
int getPathHist(ThreadID tid) const
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.
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.
Derived & init(size_type size)
Set this vector to have the given size.
#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.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria 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.
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]