47 #include "debug/Fetch.hh"
48 #include "debug/LTage.hh"
52 logSizeBiMP(params->logSizeBiMP),
53 logSizeTagTables(params->logSizeTagTables),
54 logSizeLoopPred(params->logSizeLoopPred),
55 nHistoryTables(params->nHistoryTables),
56 tagTableCounterBits(params->tagTableCounterBits),
57 histBufferSize(params->histBufferSize),
58 minHist(params->minHist),
59 maxHist(params->maxHist),
60 minTagWidth(params->minTagWidth),
61 threadHistory(params->numThreads)
63 assert(params->histBufferSize > params->maxHist * 2);
71 history.gHist = history.globalHistory;
100 for (
int i = 1;
i <= 2;
i++)
102 for (
int i = 3;
i <= 6;
i++)
104 for (
int i = 7;
i <= 10;
i++)
106 for (
int i = 11;
i <= 12;
i++)
109 for (
auto& history : threadHistory) {
116 history.computeTags[0][
i].init(
117 history.computeIndices[i].origLength,
tagWidths[i]);
118 history.computeTags[1][
i].init(
119 history.computeIndices[i].origLength,
tagWidths[i] - 1);
120 DPRINTF(LTage,
"HistLength:%d, TTSize:%d, TTTWidth:%d\n",
155 A = A & ((
ULL(1) <<
size) - 1);
197 assert(nbits <=
sizeof(int8_t) << 3);
199 if (ctr < ((1 << (nbits - 1)) - 1))
202 if (ctr > -(1 << (nbits - 1)))
225 }
else if (inter > 0) {
230 DPRINTF(LTage,
"Updating branch %lx, pred:%d, hyst:%d\n",
244 for (
int i = 0;
i < 4;
i++) {
265 if (taken !=
ltable[index].dir) {
288 DPRINTF(LTage,
"Loop Prediction success:%lx\n",pc);
297 if (
ltable[idx].numIter != 0) {
305 if (taken !=
ltable[idx].dir) {
307 DPRINTF(LTage,
"Loop End predicted successfully:%lx\n", pc);
309 if (
ltable[idx].confidence < 7) {
313 if (
ltable[idx].numIter < 3) {
321 DPRINTF(LTage,
"Loop End predicted incorrectly:%lx\n", pc);
322 if (
ltable[idx].numIter == 0) {
340 for (
int i = 0;
i < 4;
i++) {
341 int loop_hit = (nrand +
i) & 3;
343 if (
ltable[idx].age == 0) {
344 DPRINTF(LTage,
"Allocating loop pred entry for branch %lx\n",
368 DPRINTF(LTage,
"Rolling over the histories\n");
379 h[0] = (dir) ? 1 : 0;
390 for (
unsigned i = 0;
i < 32;
i++) {
395 val |= ((
threadHistory[tid].globalHistory[gh_offset] & 0x1) <<
i);
408 bool pred_taken =
true;
476 DPRINTF(LTage,
"Predict for %lx: taken?:%d, loopTaken?:%d, "
477 "loopValid?:%d, loopUseCounter:%d, tagePred:%d, altPred:%d\n",
499 squash(tid, taken, bp_history);
506 DPRINTF(LTage,
"Updating tables for branch:%lx; taken?:%d\n",
519 bool longest_match_pred =
false;
528 if (PseudoNewAlloc) {
529 if (longest_match_pred == taken) {
534 if (longest_match_pred != bi->
altTaken) {
589 DPRINTF(LTage,
"Updating tag table entry (%d,%d) for branch %lx\n",
599 DPRINTF(LTage,
"Updating tag table entry (%d,%d) for"
609 if (longest_match_pred != bi->
altTaken) {
610 if (longest_match_pred == taken) {
633 bool pathbit = ((branch_pc) & 1);
652 DPRINTF(LTage,
"Updating global histories with branch:%lx; taken?:%d, "
653 "path Hist: %x; pointer:%d\n", branch_pc, taken, tHist.
pathHist,
662 DPRINTF(LTage,
"Restoring branch info: %lx; taken? %d; PathHistory:%x, "
667 tHist.
gHist[0] = (taken ? 1 : 0);
704 bool retval =
predict(tid, branch_pc,
true, bp_history);
706 DPRINTF(LTage,
"Lookup branch: %lx; predict:%d\n", branch_pc, retval);
719 DPRINTF(LTage,
"BTB miss resets prediction: %lx\n", branch_pc);
735 DPRINTF(LTage,
"UnConditionalBranch: %lx\n", br_pc);
736 predict(tid, br_pc,
false, bp_history);
743 LTAGEParams::create()
745 return new LTAGE(
this);
void updateHistories(ThreadID tid, Addr branch_pc, bool taken, void *b)
(Speculatively) updates global histories (path and direction).
LTAGE(const LTAGEParams *params)
void init(int original_length, int compressed_length)
const unsigned nHistoryTables
int lindex(Addr pc_in) const
Computes the index used to access the loop predictor.
void baseUpdate(Addr pc, bool taken, BranchInfo *bi)
Updates the bimodal predictor.
const unsigned minTagWidth
void btbUpdate(ThreadID tid, Addr branch_addr, void *&bp_history) override
If a branch is not taken, because the BTB address is invalid or missing, this function sets the appro...
unsigned getGHR(ThreadID tid, void *bp_history) const override
int8_t useAltPredForNewlyAllocated
std::enable_if< std::is_integral< T >::value, T >::type random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
void uncondBranch(ThreadID tid, Addr br_pc, void *&bp_history) override
std::vector< ThreadHistory > threadHistory
const unsigned logSizeLoopPred
void squash(ThreadID tid, void *bp_history) override
int gindex(ThreadID tid, Addr pc, int bank) const
Computes the index used to access a partially tagged table.
void loopUpdate(Addr pc, bool Taken, BranchInfo *bi)
Updates the loop predictor.
int bindex(Addr pc_in) const
Computes the index used to access the bimodal table.
bool getBimodePred(Addr pc, BranchInfo *bi) const
Get a branch prediction from the bimodal predictor.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
#define ULL(N)
uint64_t constant
FoldedHistory * computeIndices
const unsigned tagTableCounterBits
FoldedHistory * computeTags[2]
Basically a wrapper class to hold both the branch predictor and the BTB.
int16_t ThreadID
Thread index/ID type.
const unsigned logSizeBiMP
bool predict(ThreadID tid, Addr branch_pc, bool cond_branch, void *&b)
Get a branch prediction from L-TAGE.
const unsigned histBufferSize
int F(int phist, int size, int bank) const
Utility function to shuffle the path history depending on which tagged table we are accessing...
const unsigned logSizeTagTables
uint16_t gtag(ThreadID tid, Addr pc, int bank) const
Computes the partial tag of a tagged table.
bool getLoop(Addr pc, BranchInfo *bi) const
Get a branch prediction from the loop predictor.
void updateGHist(uint8_t *&h, bool dir, uint8_t *tab, int &PT)
(Speculatively) updates the global branch history.
void specLoopUpdate(Addr pc, bool taken, BranchInfo *bi)
Speculatively updates the loop predictor iteration count.
bool lookup(ThreadID tid, Addr branch_addr, void *&bp_history) override
Looks up a given PC in the BP to see if it is taken or not taken.
void ctrUpdate(int8_t &ctr, bool taken, int nbits)
Updates a direction counter based on the actual branch outcome.
if(it_gpu==gpuTypeMap.end())
void update(ThreadID tid, Addr branch_addr, bool taken, void *bp_history, bool squashed) override
Updates the BP with taken/not taken information.