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");
323 for (
int i = 0;
i <
n;
i++) {
368 assert(
bi->branchPC == branch_pc);
375 bi->bimodalIndex =
bindex(branch_pc);
389 for (
int i =
bi->hitBank - 1;
i > 0;
i--) {
398 if (
bi->hitBank > 0) {
399 if (
bi->altBank > 0) {
407 bi->longestMatchPred =
410 abs(2 *
gtable[
bi->hitBank][
bi->hitBankIndex].ctr + 1) <= 1;
416 || !
bi->pseudoNewAlloc) {
417 bi->tagePred =
bi->longestMatchPred;
420 bi->tagePred =
bi->altTaken;
426 bi->tagePred =
bi->altTaken;
427 bi->longestMatchPred =
bi->altTaken;
431 DPRINTF(Tage,
"Predict for %lx: tagePred:%d, altPred:%d\n",
432 branch_pc,
bi->tagePred,
bi->altTaken);
461 int X =
bi->hitBank + 1;
474 unsigned numAllocated = 0;
478 gtable[
i][
bi->tableIndices[
i]].ctr = (taken) ? 0 : -1;
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) {
613 bi->ghist = taken ? 1 : 0;
624 bool taken,
Addr target,
657 if (!
bi->valid &&
bi->condBranch) {
663 assert(
bi->nGhist == 0);
668 branch_pc, target,
bi);
672 "Updating global histories with branch:%lx; taken?:%d, "
673 "path Hist: %x; pointer:%d\n",
710 for (
int n = 0;
n <
bi->nGhist;
n++) {
722 bi->modified =
false;
727 int brtype,
Addr target)
const
734 cur_phist = (cur_phist << 1) + pathbit;
756 if (taken ==
bi->tagePred) {
758 switch (
bi->provider) {
762 stats.bimodalAltMatchProviderCorrect++;
768 switch (
bi->provider) {
771 stats.longestMatchProviderWrong++;
772 if (
bi->altTaken == taken) {
773 stats.altMatchProviderWouldHaveHit++;
777 stats.bimodalAltMatchProviderWrong++;
780 stats.altMatchProviderWrong++;
784 switch (
bi->provider) {
787 if (
bi->longestMatchPred == taken) {
788 stats.longestMatchProviderWouldHaveHit++;
793 switch (
bi->provider) {
796 stats.longestMatchProvider[
bi->hitBank]++;
797 stats.altMatchProvider[
bi->altBank]++;
807 for (
unsigned i = 0;
i < 16;
i++) {
819 "Number of times TAGE Longest Match is the provider and the "
820 "prediction is correct"),
822 "Number of times TAGE Alt Match is the provider and the "
823 "prediction is correct"),
825 "Number of times TAGE Alt Match is the bimodal and it is the "
826 "provider and the prediction is correct"),
828 "Number of times there are no hits on the TAGE tables and the "
829 "bimodal prediction is correct"),
831 "Number of times TAGE Longest Match is the provider and the "
832 "prediction is wrong"),
834 "Number of times TAGE Alt Match is the provider and the "
835 "prediction is wrong"),
837 "Number of times TAGE Alt Match is the bimodal and it is the "
838 "provider and the prediction is wrong"),
840 "Number of times there are no hits on the TAGE tables and the "
841 "bimodal prediction is wrong"),
843 "Number of times TAGE Longest Match is the provider, the "
844 "prediction is wrong and Alt Match prediction was correct"),
846 "Number of times TAGE Alt Match is the provider, the "
847 "prediction is wrong and Longest Match prediction was correct"),
849 "TAGE provider for longest match"),
851 "TAGE provider for alt match")
860 return gtable[hitBank][hitBankIndex].ctr;
891 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]