43#include "debug/Fetch.hh"
44#include "debug/Tage.hh"
78 noSkip.resize(nHistoryTables + 1, true);
112 history.pathHist = 0;
113 history.nonSpecPathHist = 0;
160 DPRINTF(Tage,
"HistLength:%d, TTSize:%d, TTTWidth:%d\n",
198 A = A & ((1ULL << size) - 1);
244 assert(nbits <=
sizeof(T) << 3);
246 if (ctr < ((1 << (nbits - 1)) - 1))
249 if (ctr > -(1 << (nbits - 1)))
262 assert(nbits <=
sizeof(uint8_t) << 3);
264 if (ctr < ((1 << nbits) - 1))
290 }
else if (inter > 0) {
293 const bool pred = inter >> 1;
294 const bool hyst = inter & 1;
297 DPRINTF(Tage,
"Updating branch %lx, pred:%d, hyst:%d\n",
pc,
pred, hyst);
310 DPRINTF(Tage,
"Rolling over the histories\n");
321 const int rollbackBuffer = 1000;
322 for (
int i = 0;
i < (
maxHist + rollbackBuffer);
i++) {
331 for (
int i = 0;
i <
n;
i++) {
376 assert(
bi->branchPC == branch_pc);
383 bi->bimodalIndex =
bindex(branch_pc);
397 for (
int i =
bi->hitBank - 1;
i > 0;
i--) {
406 if (
bi->hitBank > 0) {
407 if (
bi->altBank > 0) {
415 bi->longestMatchPred =
418 abs(2 *
gtable[
bi->hitBank][
bi->hitBankIndex].ctr + 1) <= 1;
424 || !
bi->pseudoNewAlloc) {
425 bi->tagePred =
bi->longestMatchPred;
428 bi->tagePred =
bi->altTaken;
434 bi->tagePred =
bi->altTaken;
435 bi->longestMatchPred =
bi->altTaken;
439 DPRINTF(Tage,
"Predict for %lx: tagePred:%d, altPred:%d\n",
440 branch_pc,
bi->tagePred,
bi->altTaken);
469 int X =
bi->hitBank + 1;
482 unsigned numAllocated = 0;
486 gtable[
i][
bi->tableIndices[
i]].ctr = (taken) ? 0 : -1;
529 if (preAdjustAlloc) {
533 if (
bi->hitBank > 0) {
536 bool PseudoNewAlloc =
bi->pseudoNewAlloc;
539 if (PseudoNewAlloc) {
540 if (
bi->longestMatchPred == taken) {
545 if (
bi->longestMatchPred !=
bi->altTaken) {
553 if (!preAdjustAlloc) {
565 if (
bi->hitBank > 0) {
566 DPRINTF(Tage,
"Updating tag table entry (%d,%d) for branch %lx\n",
567 bi->hitBank,
bi->hitBankIndex, branch_pc);
572 if (
gtable[
bi->hitBank][
bi->hitBankIndex].u == 0) {
573 if (
bi->altBank > 0) {
576 DPRINTF(Tage,
"Updating tag table entry (%d,%d) for"
577 " branch %lx\n",
bi->hitBank,
bi->hitBankIndex,
580 if (
bi->altBank == 0) {
586 if (
bi->tagePred !=
bi->altTaken) {
621 bi->ghist = taken ? 1 : 0;
632 bool taken,
Addr target,
665 if (!
bi->valid &&
bi->condBranch) {
671 assert(
bi->nGhist == 0);
676 branch_pc, target,
bi);
680 "Updating global histories with branch:%lx; taken?:%d, "
681 "path Hist: %x; pointer:%d\n",
718 for (
int n = 0;
n <
bi->nGhist;
n++) {
734 bi->modified =
false;
739 int brtype,
Addr target)
const
746 cur_phist = (cur_phist << 1) + pathbit;
768 if (taken ==
bi->tagePred) {
770 switch (
bi->provider) {
774 stats.bimodalAltMatchProviderCorrect++;
780 switch (
bi->provider) {
783 stats.longestMatchProviderWrong++;
784 if (
bi->altTaken == taken) {
785 stats.altMatchProviderWouldHaveHit++;
789 stats.bimodalAltMatchProviderWrong++;
792 stats.altMatchProviderWrong++;
796 switch (
bi->provider) {
799 if (
bi->longestMatchPred == taken) {
800 stats.longestMatchProviderWouldHaveHit++;
805 switch (
bi->provider) {
808 stats.longestMatchProvider[
bi->hitBank]++;
809 stats.altMatchProvider[
bi->altBank]++;
819 for (
unsigned i = 0;
i < 16;
i++) {
831 "Number of times TAGE Longest Match is the provider and the "
832 "prediction is correct"),
834 "Number of times TAGE Alt Match is the provider and the "
835 "prediction is correct"),
837 "Number of times TAGE Alt Match is the bimodal and it is the "
838 "provider and the prediction is correct"),
840 "Number of times there are no hits on the TAGE tables and the "
841 "bimodal prediction is correct"),
843 "Number of times TAGE Longest Match is the provider and the "
844 "prediction is wrong"),
846 "Number of times TAGE Alt Match is the provider and the "
847 "prediction is wrong"),
849 "Number of times TAGE Alt Match is the bimodal and it is the "
850 "provider and the prediction is wrong"),
852 "Number of times there are no hits on the TAGE tables and the "
853 "bimodal prediction is wrong"),
855 "Number of times TAGE Longest Match is the provider, the "
856 "prediction is wrong and Alt Match prediction was correct"),
858 "Number of times TAGE Alt Match is the provider, the "
859 "prediction is wrong and Longest Match prediction was correct"),
861 "TAGE provider for longest match"),
863 "TAGE provider for alt match")
872 return gtable[hitBank][hitBankIndex].ctr;
903 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.
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
virtual int calcNewPathHist(ThreadID tid, Addr pc, int cur_phist, bool taken, int brtype, Addr target) const
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
const bool takenOnlyHistory
Use taken only history.
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
std::vector< uint8_t > globalHist
FoldedHistory * computeTags[2]