gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
tage_base.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 The University of Wisconsin
3  *
4  * Copyright (c) 2006 INRIA (Institut National de Recherche en
5  * Informatique et en Automatique / French National Research Institute
6  * for Computer Science and Applied Mathematics)
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are
12  * met: redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer;
14  * redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution;
17  * neither the name of the copyright holders nor the names of its
18  * contributors may be used to endorse or promote products derived from
19  * this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Authors: Vignyan Reddy, Dibakar Gope and Arthur Perais,
34  * from André Seznec's code.
35  */
36 
37 /* @file
38  * Implementation of a TAGE branch predictor
39  */
40 
41 #include "cpu/pred/tage_base.hh"
42 
43 #include "base/intmath.hh"
44 #include "base/logging.hh"
45 #include "debug/Fetch.hh"
46 #include "debug/Tage.hh"
47 
48 TAGEBase::TAGEBase(const TAGEBaseParams *p)
49  : SimObject(p),
50  logRatioBiModalHystEntries(p->logRatioBiModalHystEntries),
51  nHistoryTables(p->nHistoryTables),
52  tagTableCounterBits(p->tagTableCounterBits),
53  tagTableUBits(p->tagTableUBits),
54  histBufferSize(p->histBufferSize),
55  minHist(p->minHist),
56  maxHist(p->maxHist),
57  pathHistBits(p->pathHistBits),
58  tagTableTagWidths(p->tagTableTagWidths),
59  logTagTableSizes(p->logTagTableSizes),
60  threadHistory(p->numThreads),
61  logUResetPeriod(p->logUResetPeriod),
62  initialTCounterValue(p->initialTCounterValue),
63  numUseAltOnNa(p->numUseAltOnNa),
64  useAltOnNaBits(p->useAltOnNaBits),
65  maxNumAlloc(p->maxNumAlloc),
66  noSkip(p->noSkip),
67  speculativeHistUpdate(p->speculativeHistUpdate),
68  instShiftAmt(p->instShiftAmt),
69  initialized(false)
70 {
71  if (noSkip.empty()) {
72  // Set all the table to enabled by default
73  noSkip.resize(nHistoryTables + 1, true);
74  }
75 }
76 
79  return new BranchInfo(*this);
80 }
81 
82 void
84 {
85  if (initialized) {
86  return;
87  }
88  // Current method for periodically resetting the u counter bits only
89  // works for 1 or 2 bits
90  // Also make sure that it is not 0
91  assert(tagTableUBits <= 2 && (tagTableUBits > 0));
92 
93  // we use int type for the path history, so it cannot be more than
94  // its size
95  assert(pathHistBits <= (sizeof(int)*8));
96 
97  // initialize the counter to half of the period
98  assert(logUResetPeriod != 0);
100 
101  assert(histBufferSize > maxHist * 2);
102 
104 
105  for (auto& history : threadHistory) {
106  history.pathHist = 0;
107  history.globalHistory = new uint8_t[histBufferSize];
108  history.gHist = history.globalHistory;
109  memset(history.gHist, 0, histBufferSize);
110  history.ptGhist = 0;
111  }
112 
113  histLengths = new int [nHistoryTables+1];
114 
116 
117  assert(tagTableTagWidths.size() == (nHistoryTables+1));
118  assert(logTagTableSizes.size() == (nHistoryTables+1));
119 
120  // First entry is for the Bimodal table and it is untagged in this
121  // implementation
122  assert(tagTableTagWidths[0] == 0);
123 
124  for (auto& history : threadHistory) {
125  history.computeIndices = new FoldedHistory[nHistoryTables+1];
126  history.computeTags[0] = new FoldedHistory[nHistoryTables+1];
127  history.computeTags[1] = new FoldedHistory[nHistoryTables+1];
128 
129  initFoldedHistories(history);
130  }
131 
132  const uint64_t bimodalTableSize = ULL(1) << logTagTableSizes[0];
133  btablePrediction.resize(bimodalTableSize, false);
134  btableHysteresis.resize(bimodalTableSize >> logRatioBiModalHystEntries,
135  true);
136 
137  gtable = new TageEntry*[nHistoryTables + 1];
138  buildTageTables();
139 
140  tableIndices = new int [nHistoryTables+1];
141  tableTags = new int [nHistoryTables+1];
142  initialized = true;
143 }
144 
145 void
147 {
148  for (int i = 1; i <= nHistoryTables; i++) {
149  history.computeIndices[i].init(
151  history.computeTags[0][i].init(
153  history.computeTags[1][i].init(
154  history.computeIndices[i].origLength, tagTableTagWidths[i]-1);
155  DPRINTF(Tage, "HistLength:%d, TTSize:%d, TTTWidth:%d\n",
157  }
158 }
159 
160 void
162 {
163  for (int i = 1; i <= nHistoryTables; i++) {
164  gtable[i] = new TageEntry[1<<(logTagTableSizes[i])];
165  }
166 }
167 
168 void
170 {
171  histLengths[1] = minHist;
173 
174  for (int i = 2; i <= nHistoryTables; i++) {
175  histLengths[i] = (int) (((double) minHist *
176  pow ((double) (maxHist) / (double) minHist,
177  (double) (i - 1) / (double) ((nHistoryTables- 1))))
178  + 0.5);
179  }
180 }
181 
182 void
184 {
185  if (speculativeHistUpdate) {
186  ThreadHistory& tHist = threadHistory[tid];
187  DPRINTF(Tage, "BTB miss resets prediction: %lx\n", branch_pc);
188  assert(tHist.gHist == &tHist.globalHistory[tHist.ptGhist]);
189  tHist.gHist[0] = 0;
190  for (int i = 1; i <= nHistoryTables; i++) {
191  tHist.computeIndices[i].comp = bi->ci[i];
192  tHist.computeTags[0][i].comp = bi->ct0[i];
193  tHist.computeTags[1][i].comp = bi->ct1[i];
194  tHist.computeIndices[i].update(tHist.gHist);
195  tHist.computeTags[0][i].update(tHist.gHist);
196  tHist.computeTags[1][i].update(tHist.gHist);
197  }
198  }
199 }
200 
201 int
202 TAGEBase::bindex(Addr pc_in) const
203 {
204  return ((pc_in >> instShiftAmt) & ((ULL(1) << (logTagTableSizes[0])) - 1));
205 }
206 
207 int
208 TAGEBase::F(int A, int size, int bank) const
209 {
210  int A1, A2;
211 
212  A = A & ((ULL(1) << size) - 1);
213  A1 = (A & ((ULL(1) << logTagTableSizes[bank]) - 1));
214  A2 = (A >> logTagTableSizes[bank]);
215  A2 = ((A2 << bank) & ((ULL(1) << logTagTableSizes[bank]) - 1))
216  + (A2 >> (logTagTableSizes[bank] - bank));
217  A = A1 ^ A2;
218  A = ((A << bank) & ((ULL(1) << logTagTableSizes[bank]) - 1))
219  + (A >> (logTagTableSizes[bank] - bank));
220  return (A);
221 }
222 
223 // gindex computes a full hash of pc, ghist and pathHist
224 int
225 TAGEBase::gindex(ThreadID tid, Addr pc, int bank) const
226 {
227  int index;
228  int hlen = (histLengths[bank] > pathHistBits) ? pathHistBits :
229  histLengths[bank];
230  const unsigned int shiftedPc = pc >> instShiftAmt;
231  index =
232  shiftedPc ^
233  (shiftedPc >> ((int) abs(logTagTableSizes[bank] - bank) + 1)) ^
234  threadHistory[tid].computeIndices[bank].comp ^
235  F(threadHistory[tid].pathHist, hlen, bank);
236 
237  return (index & ((ULL(1) << (logTagTableSizes[bank])) - 1));
238 }
239 
240 
241 // Tag computation
242 uint16_t
243 TAGEBase::gtag(ThreadID tid, Addr pc, int bank) const
244 {
245  int tag = (pc >> instShiftAmt) ^
246  threadHistory[tid].computeTags[0][bank].comp ^
247  (threadHistory[tid].computeTags[1][bank].comp << 1);
248 
249  return (tag & ((ULL(1) << tagTableTagWidths[bank]) - 1));
250 }
251 
252 
253 // Up-down saturating counter
254 template<typename T>
255 void
256 TAGEBase::ctrUpdate(T & ctr, bool taken, int nbits)
257 {
258  assert(nbits <= sizeof(T) << 3);
259  if (taken) {
260  if (ctr < ((1 << (nbits - 1)) - 1))
261  ctr++;
262  } else {
263  if (ctr > -(1 << (nbits - 1)))
264  ctr--;
265  }
266 }
267 
268 // int8_t and int versions of this function may be needed
269 template void TAGEBase::ctrUpdate(int8_t & ctr, bool taken, int nbits);
270 template void TAGEBase::ctrUpdate(int & ctr, bool taken, int nbits);
271 
272 // Up-down unsigned saturating counter
273 void
274 TAGEBase::unsignedCtrUpdate(uint8_t & ctr, bool up, unsigned nbits)
275 {
276  assert(nbits <= sizeof(uint8_t) << 3);
277  if (up) {
278  if (ctr < ((1 << nbits) - 1))
279  ctr++;
280  } else {
281  if (ctr)
282  ctr--;
283  }
284 }
285 
286 // Bimodal prediction
287 bool
289 {
290  return btablePrediction[bi->bimodalIndex];
291 }
292 
293 
294 // Update the bimodal predictor: a hysteresis bit is shared among N prediction
295 // bits (N = 2 ^ logRatioBiModalHystEntries)
296 void
298 {
299  int inter = (btablePrediction[bi->bimodalIndex] << 1)
301  if (taken) {
302  if (inter < 3)
303  inter++;
304  } else if (inter > 0) {
305  inter--;
306  }
307  const bool pred = inter >> 1;
308  const bool hyst = inter & 1;
309  btablePrediction[bi->bimodalIndex] = pred;
311  DPRINTF(Tage, "Updating branch %lx, pred:%d, hyst:%d\n", pc, pred, hyst);
312 }
313 
314 // shifting the global history: we manage the history in a big table in order
315 // to reduce simulation time
316 void
317 TAGEBase::updateGHist(uint8_t * &h, bool dir, uint8_t * tab, int &pt)
318 {
319  if (pt == 0) {
320  DPRINTF(Tage, "Rolling over the histories\n");
321  // Copy beginning of globalHistoryBuffer to end, such that
322  // the last maxHist outcomes are still reachable
323  // through pt[0 .. maxHist - 1].
324  for (int i = 0; i < maxHist; i++)
325  tab[histBufferSize - maxHist + i] = tab[i];
326  pt = histBufferSize - maxHist;
327  h = &tab[pt];
328  }
329  pt--;
330  h--;
331  h[0] = (dir) ? 1 : 0;
332 }
333 
334 void
336  BranchInfo* bi)
337 {
338  // computes the table addresses and the partial tags
339  for (int i = 1; i <= nHistoryTables; i++) {
340  tableIndices[i] = gindex(tid, branch_pc, i);
341  bi->tableIndices[i] = tableIndices[i];
342  tableTags[i] = gtag(tid, branch_pc, i);
343  bi->tableTags[i] = tableTags[i];
344  }
345 }
346 
347 unsigned
349 {
350  // There is only 1 counter on the base TAGE implementation
351  return 0;
352 }
353 
354 bool
356  bool cond_branch, BranchInfo* bi)
357 {
358  Addr pc = branch_pc;
359  bool pred_taken = true;
360 
361  if (cond_branch) {
362  // TAGE prediction
363 
364  calculateIndicesAndTags(tid, pc, bi);
365 
366  bi->bimodalIndex = bindex(pc);
367 
368  bi->hitBank = 0;
369  bi->altBank = 0;
370  //Look for the bank with longest matching history
371  for (int i = nHistoryTables; i > 0; i--) {
372  if (noSkip[i] &&
373  gtable[i][tableIndices[i]].tag == tableTags[i]) {
374  bi->hitBank = i;
375  bi->hitBankIndex = tableIndices[bi->hitBank];
376  break;
377  }
378  }
379  //Look for the alternate bank
380  for (int i = bi->hitBank - 1; i > 0; i--) {
381  if (noSkip[i] &&
382  gtable[i][tableIndices[i]].tag == tableTags[i]) {
383  bi->altBank = i;
384  bi->altBankIndex = tableIndices[bi->altBank];
385  break;
386  }
387  }
388  //computes the prediction and the alternate prediction
389  if (bi->hitBank > 0) {
390  if (bi->altBank > 0) {
391  bi->altTaken =
392  gtable[bi->altBank][tableIndices[bi->altBank]].ctr >= 0;
393  extraAltCalc(bi);
394  }else {
395  bi->altTaken = getBimodePred(pc, bi);
396  }
397 
398  bi->longestMatchPred =
399  gtable[bi->hitBank][tableIndices[bi->hitBank]].ctr >= 0;
400  bi->pseudoNewAlloc =
401  abs(2 * gtable[bi->hitBank][bi->hitBankIndex].ctr + 1) <= 1;
402 
403  //if the entry is recognized as a newly allocated entry and
404  //useAltPredForNewlyAllocated is positive use the alternate
405  //prediction
406  if ((useAltPredForNewlyAllocated[getUseAltIdx(bi, branch_pc)] < 0)
407  || ! bi->pseudoNewAlloc) {
408  bi->tagePred = bi->longestMatchPred;
410  } else {
411  bi->tagePred = bi->altTaken;
412  bi->provider = bi->altBank ? TAGE_ALT_MATCH
414  }
415  } else {
416  bi->altTaken = getBimodePred(pc, bi);
417  bi->tagePred = bi->altTaken;
418  bi->longestMatchPred = bi->altTaken;
419  bi->provider = BIMODAL_ONLY;
420  }
421  //end TAGE prediction
422 
423  pred_taken = (bi->tagePred);
424  DPRINTF(Tage, "Predict for %lx: taken?:%d, tagePred:%d, altPred:%d\n",
425  branch_pc, pred_taken, bi->tagePred, bi->altTaken);
426  }
427  bi->branchPC = branch_pc;
428  bi->condBranch = cond_branch;
429  return pred_taken;
430 }
431 
432 void
433 TAGEBase::adjustAlloc(bool & alloc, bool taken, bool pred_taken)
434 {
435  // Nothing for this base class implementation
436 }
437 
438 void
440  int nrand)
441 {
442  if (alloc) {
443  // is there some "unuseful" entry to allocate
444  uint8_t min = 1;
445  for (int i = nHistoryTables; i > bi->hitBank; i--) {
446  if (gtable[i][bi->tableIndices[i]].u < min) {
447  min = gtable[i][bi->tableIndices[i]].u;
448  }
449  }
450 
451  // we allocate an entry with a longer history
452  // to avoid ping-pong, we do not choose systematically the next
453  // entry, but among the 3 next entries
454  int Y = nrand &
455  ((ULL(1) << (nHistoryTables - bi->hitBank - 1)) - 1);
456  int X = bi->hitBank + 1;
457  if (Y & 1) {
458  X++;
459  if (Y & 2)
460  X++;
461  }
462  // No entry available, forces one to be available
463  if (min > 0) {
464  gtable[X][bi->tableIndices[X]].u = 0;
465  }
466 
467 
468  //Allocate entries
469  unsigned numAllocated = 0;
470  for (int i = X; i <= nHistoryTables; i++) {
471  if ((gtable[i][bi->tableIndices[i]].u == 0)) {
472  gtable[i][bi->tableIndices[i]].tag = bi->tableTags[i];
473  gtable[i][bi->tableIndices[i]].ctr = (taken) ? 0 : -1;
474  ++numAllocated;
475  if (numAllocated == maxNumAlloc) {
476  break;
477  }
478  }
479  }
480  }
481 
482  tCounter++;
483 
484  handleUReset();
485 }
486 
487 void
489 {
490  //periodic reset of u: reset is not complete but bit by bit
491  if ((tCounter & ((ULL(1) << logUResetPeriod) - 1)) == 0) {
492  // reset least significant bit
493  // most significant bit becomes least significant bit
494  for (int i = 1; i <= nHistoryTables; i++) {
495  for (int j = 0; j < (ULL(1) << logTagTableSizes[i]); j++) {
496  resetUctr(gtable[i][j].u);
497  }
498  }
499  }
500 }
501 
502 void
504 {
505  u >>= 1;
506 }
507 
508 void
509 TAGEBase::condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken,
510  BranchInfo* bi, int nrand, Addr corrTarget, bool pred, bool preAdjustAlloc)
511 {
512  // TAGE UPDATE
513  // try to allocate a new entries only if prediction was wrong
514  bool alloc = (bi->tagePred != taken) && (bi->hitBank < nHistoryTables);
515 
516  if (preAdjustAlloc) {
517  adjustAlloc(alloc, taken, pred);
518  }
519 
520  if (bi->hitBank > 0) {
521  // Manage the selection between longest matching and alternate
522  // matching for "pseudo"-newly allocated longest matching entry
523  bool PseudoNewAlloc = bi->pseudoNewAlloc;
524  // an entry is considered as newly allocated if its prediction
525  // counter is weak
526  if (PseudoNewAlloc) {
527  if (bi->longestMatchPred == taken) {
528  alloc = false;
529  }
530  // if it was delivering the correct prediction, no need to
531  // allocate new entry even if the overall prediction was false
532  if (bi->longestMatchPred != bi->altTaken) {
533  ctrUpdate(
535  bi->altTaken == taken, useAltOnNaBits);
536  }
537  }
538  }
539 
540  if (!preAdjustAlloc) {
541  adjustAlloc(alloc, taken, pred);
542  }
543 
544  handleAllocAndUReset(alloc, taken, bi, nrand);
545 
546  handleTAGEUpdate(branch_pc, taken, bi);
547 }
548 
549 void
551 {
552  if (bi->hitBank > 0) {
553  DPRINTF(Tage, "Updating tag table entry (%d,%d) for branch %lx\n",
554  bi->hitBank, bi->hitBankIndex, branch_pc);
555  ctrUpdate(gtable[bi->hitBank][bi->hitBankIndex].ctr, taken,
557  // if the provider entry is not certified to be useful also update
558  // the alternate prediction
559  if (gtable[bi->hitBank][bi->hitBankIndex].u == 0) {
560  if (bi->altBank > 0) {
561  ctrUpdate(gtable[bi->altBank][bi->altBankIndex].ctr, taken,
563  DPRINTF(Tage, "Updating tag table entry (%d,%d) for"
564  " branch %lx\n", bi->hitBank, bi->hitBankIndex,
565  branch_pc);
566  }
567  if (bi->altBank == 0) {
568  baseUpdate(branch_pc, taken, bi);
569  }
570  }
571 
572  // update the u counter
573  if (bi->tagePred != bi->altTaken) {
575  bi->tagePred == taken, tagTableUBits);
576  }
577  } else {
578  baseUpdate(branch_pc, taken, bi);
579  }
580 }
581 
582 void
583 TAGEBase::updateHistories(ThreadID tid, Addr branch_pc, bool taken,
584  BranchInfo* bi, bool speculative,
585  const StaticInstPtr &inst, Addr target)
586 {
587  if (speculative != speculativeHistUpdate) {
588  return;
589  }
590  ThreadHistory& tHist = threadHistory[tid];
591  // UPDATE HISTORIES
592  bool pathbit = ((branch_pc >> instShiftAmt) & 1);
593  //on a squash, return pointers to this and recompute indices.
594  //update user history
595  updateGHist(tHist.gHist, taken, tHist.globalHistory, tHist.ptGhist);
596  tHist.pathHist = (tHist.pathHist << 1) + pathbit;
597  tHist.pathHist = (tHist.pathHist & ((ULL(1) << pathHistBits) - 1));
598 
599  if (speculative) {
600  bi->ptGhist = tHist.ptGhist;
601  bi->pathHist = tHist.pathHist;
602  }
603 
604  //prepare next index and tag computations for user branchs
605  for (int i = 1; i <= nHistoryTables; i++)
606  {
607  if (speculative) {
608  bi->ci[i] = tHist.computeIndices[i].comp;
609  bi->ct0[i] = tHist.computeTags[0][i].comp;
610  bi->ct1[i] = tHist.computeTags[1][i].comp;
611  }
612  tHist.computeIndices[i].update(tHist.gHist);
613  tHist.computeTags[0][i].update(tHist.gHist);
614  tHist.computeTags[1][i].update(tHist.gHist);
615  }
616  DPRINTF(Tage, "Updating global histories with branch:%lx; taken?:%d, "
617  "path Hist: %x; pointer:%d\n", branch_pc, taken, tHist.pathHist,
618  tHist.ptGhist);
619  assert(threadHistory[tid].gHist ==
620  &threadHistory[tid].globalHistory[threadHistory[tid].ptGhist]);
621 }
622 
623 void
625  Addr target)
626 {
627  if (!speculativeHistUpdate) {
628  /* If there are no speculative updates, no actions are needed */
629  return;
630  }
631 
632  ThreadHistory& tHist = threadHistory[tid];
633  DPRINTF(Tage, "Restoring branch info: %lx; taken? %d; PathHistory:%x, "
634  "pointer:%d\n", bi->branchPC,taken, bi->pathHist, bi->ptGhist);
635  tHist.pathHist = bi->pathHist;
636  tHist.ptGhist = bi->ptGhist;
637  tHist.gHist = &(tHist.globalHistory[tHist.ptGhist]);
638  tHist.gHist[0] = (taken ? 1 : 0);
639  for (int i = 1; i <= nHistoryTables; i++) {
640  tHist.computeIndices[i].comp = bi->ci[i];
641  tHist.computeTags[0][i].comp = bi->ct0[i];
642  tHist.computeTags[1][i].comp = bi->ct1[i];
643  tHist.computeIndices[i].update(tHist.gHist);
644  tHist.computeTags[0][i].update(tHist.gHist);
645  tHist.computeTags[1][i].update(tHist.gHist);
646  }
647 }
648 
649 void
651 {
652  // do nothing. This is only used in some derived classes
653  return;
654 }
655 
656 void
658 {
659  if (taken == bi->tagePred) {
660  // correct prediction
661  switch (bi->provider) {
666  }
667  } else {
668  // wrong prediction
669  switch (bi->provider) {
670  case BIMODAL_ONLY: tageBimodalProviderWrong++; break;
671  case TAGE_LONGEST_MATCH:
673  if (bi->altTaken == taken) {
675  }
676  break;
677  case BIMODAL_ALT_MATCH:
679  break;
680  case TAGE_ALT_MATCH:
682  break;
683  }
684 
685  switch (bi->provider) {
686  case BIMODAL_ALT_MATCH:
687  case TAGE_ALT_MATCH:
688  if (bi->longestMatchPred == taken) {
690  }
691  }
692  }
693 
694  switch (bi->provider) {
695  case TAGE_LONGEST_MATCH:
696  case TAGE_ALT_MATCH:
699  break;
700  }
701 }
702 
703 unsigned
705 {
706  unsigned val = 0;
707  for (unsigned i = 0; i < 32; i++) {
708  // Make sure we don't go out of bounds
709  int gh_offset = bi->ptGhist + i;
710  assert(&(threadHistory[tid].globalHistory[gh_offset]) <
711  threadHistory[tid].globalHistory + histBufferSize);
712  val |= ((threadHistory[tid].globalHistory[gh_offset] & 0x1) << i);
713  }
714 
715  return val;
716 }
717 
718 void
720 {
722  .name(name() + ".tageLongestMatchProviderCorrect")
723  .desc("Number of times TAGE Longest Match is the provider and "
724  "the prediction is correct");
725 
727  .name(name() + ".tageAltMatchProviderCorrect")
728  .desc("Number of times TAGE Alt Match is the provider and "
729  "the prediction is correct");
730 
732  .name(name() + ".bimodalAltMatchProviderCorrect")
733  .desc("Number of times TAGE Alt Match is the bimodal and it is the "
734  "provider and the prediction is correct");
735 
737  .name(name() + ".tageBimodalProviderCorrect")
738  .desc("Number of times there are no hits on the TAGE tables "
739  "and the bimodal prediction is correct");
740 
742  .name(name() + ".tageLongestMatchProviderWrong")
743  .desc("Number of times TAGE Longest Match is the provider and "
744  "the prediction is wrong");
745 
747  .name(name() + ".tageAltMatchProviderWrong")
748  .desc("Number of times TAGE Alt Match is the provider and "
749  "the prediction is wrong");
750 
752  .name(name() + ".bimodalAltMatchProviderWrong")
753  .desc("Number of times TAGE Alt Match is the bimodal and it is the "
754  "provider and the prediction is wrong");
755 
757  .name(name() + ".tageBimodalProviderWrong")
758  .desc("Number of times there are no hits on the TAGE tables "
759  "and the bimodal prediction is wrong");
760 
762  .name(name() + ".tageAltMatchProviderWouldHaveHit")
763  .desc("Number of times TAGE Longest Match is the provider, "
764  "the prediction is wrong and Alt Match prediction was correct");
765 
767  .name(name() + ".tageLongestMatchProviderWouldHaveHit")
768  .desc("Number of times TAGE Alt Match is the provider, the "
769  "prediction is wrong and Longest Match prediction was correct");
770 
772  .init(nHistoryTables + 1)
773  .name(name() + ".tageLongestMatchProvider")
774  .desc("TAGE provider for longest match");
775 
777  .init(nHistoryTables + 1)
778  .name(name() + ".tageAltMatchProvider")
779  .desc("TAGE provider for alt match");
780 }
781 
782 int8_t
783 TAGEBase::getCtr(int hitBank, int hitBankIndex) const
784 {
785  return gtable[hitBank][hitBankIndex].ctr;
786 }
787 
788 unsigned
790 {
791  return tagTableCounterBits;
792 }
793 
794 int
796 {
797  return threadHistory[tid].pathHist;
798 }
799 
800 bool
802 {
803  return speculativeHistUpdate;
804 }
805 
806 size_t
808  size_t bits = 0;
809  for (int i = 1; i <= nHistoryTables; i++) {
810  bits += (1 << logTagTableSizes[i]) *
812  }
813  uint64_t bimodalTableSize = ULL(1) << logTagTableSizes[0];
814  bits += numUseAltOnNa * useAltOnNaBits;
815  bits += bimodalTableSize;
816  bits += (bimodalTableSize >> logRatioBiModalHystEntries);
817  bits += histLengths[nHistoryTables];
818  bits += pathHistBits;
819  bits += logUResetPeriod;
820  return bits;
821 }
822 
823 TAGEBase*
824 TAGEBaseParams::create()
825 {
826  return new TAGEBase(this);
827 }
std::vector< bool > btablePrediction
Definition: tage_base.hh:432
#define DPRINTF(x,...)
Definition: trace.hh:229
const unsigned tagTableUBits
Definition: tage_base.hh:423
virtual void handleAllocAndUReset(bool alloc, bool taken, BranchInfo *bi, int nrand)
Handles Allocation and U bits reset on an update.
Definition: tage_base.cc:439
Bitfield< 30, 0 > index
virtual void calculateParameters()
Calculates the history lengths and some other paramters in derived classes.
Definition: tage_base.cc:169
std::vector< int > logTagTableSizes
Definition: tage_base.hh:430
Bitfield< 7 > i
unsigned useAltOnNaBits
Definition: tage_base.hh:475
bool isSpeculativeUpdateEnabled() const
Definition: tage_base.cc:801
virtual void extraAltCalc(BranchInfo *bi)
Extra steps for calculating altTaken For this base TAGE class it does nothing.
Definition: tage_base.cc:650
static void unsignedCtrUpdate(uint8_t &ctr, bool up, unsigned nbits)
Updates an unsigned counter based on up/down parameter.
Definition: tage_base.cc:274
virtual void updateStats(bool taken, BranchInfo *bi)
Update the stats.
Definition: tage_base.cc:657
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.
Definition: tage_base.cc:509
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: tage_base.cc:83
unsigned getGHR(ThreadID tid, BranchInfo *bi) const
Definition: tage_base.cc:704
const unsigned pathHistBits
Definition: tage_base.hh:427
void baseUpdate(Addr pc, bool taken, BranchInfo *bi)
Updates the bimodal predictor.
Definition: tage_base.cc:297
Stats::Scalar tageLongestMatchProviderCorrect
Definition: tage_base.hh:490
static void ctrUpdate(T &ctr, bool taken, int nbits)
Updates a direction counter based on the actual branch outcome.
Definition: tage_base.cc:256
virtual unsigned getUseAltIdx(BranchInfo *bi, Addr branch_pc)
Calculation of the index for useAltPredForNewlyAllocated On this base TAGE implementation it is alway...
Definition: tage_base.cc:348
virtual void resetUctr(uint8_t &u)
Algorithm for resetting a single U counter.
Definition: tage_base.cc:503
uint64_t logUResetPeriod
Definition: tage_base.hh:472
TageEntry ** gtable
Definition: tage_base.hh:434
virtual uint16_t gtag(ThreadID tid, Addr pc, int bank) const
Computes the partial tag of a tagged table.
Definition: tage_base.cc:243
int * tableIndices
Definition: tage_base.hh:467
const unsigned maxHist
Definition: tage_base.hh:426
void regStats() override
Callback to set stat parameters.
Definition: tage_base.cc:719
Bitfield< 20, 16 > bi
Definition: types.hh:65
Stats::Scalar tageBimodalProviderCorrect
Definition: tage_base.hh:493
Stats::Scalar tageAltMatchProviderWrong
Definition: tage_base.hh:495
FoldedHistory * computeTags[2]
Definition: tage_base.hh:456
bool initialized
Definition: tage_base.hh:487
Derived & init(size_type size)
Set this vector to have the given size.
Definition: statistics.hh:1152
Stats::Scalar tageAltMatchProviderWouldHaveHit
Definition: tage_base.hh:498
virtual BranchInfo * makeBranchInfo()
Definition: tage_base.cc:78
Bitfield< 63 > val
Definition: misc.hh:771
Stats::Vector tageLongestMatchProvider
Definition: tage_base.hh:501
std::vector< bool > btableHysteresis
Definition: tage_base.hh:433
const unsigned nHistoryTables
Definition: tage_base.hh:421
Bitfield< 15, 0 > X
Definition: int.hh:55
const unsigned instShiftAmt
Definition: tage_base.hh:485
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...
Definition: tage_base.cc:208
const int64_t initialTCounterValue
Definition: tage_base.hh:473
Bitfield< 4 > pc
unsigned numUseAltOnNa
Definition: tage_base.hh:474
virtual void squash(ThreadID tid, bool taken, BranchInfo *bi, Addr target)
Restores speculatively updated path and direction histories.
Definition: tage_base.cc:624
Bitfield< 22 > u
virtual int gindex(ThreadID tid, Addr pc, int bank) const
Computes the index used to access a partially tagged table.
Definition: tage_base.cc:225
Stats::Scalar bimodalAltMatchProviderWrong
Definition: tage_base.hh:496
Stats::Scalar bimodalAltMatchProviderCorrect
Definition: tage_base.hh:492
const unsigned histBufferSize
Definition: tage_base.hh:424
const unsigned minHist
Definition: tage_base.hh:425
const bool speculativeHistUpdate
Definition: tage_base.hh:483
virtual bool getBimodePred(Addr pc, BranchInfo *bi) const
Get a branch prediction from the bimodal predictor.
Definition: tage_base.cc:288
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 ...
Definition: tage_base.cc:433
Stats::Scalar tageLongestMatchProviderWouldHaveHit
Definition: tage_base.hh:499
int getPathHist(ThreadID tid) const
Definition: tage_base.cc:795
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Stats::Scalar tageBimodalProviderWrong
Definition: tage_base.hh:497
void updateGHist(uint8_t *&h, bool dir, uint8_t *tab, int &PT)
(Speculatively) updates the global branch history.
Definition: tage_base.cc:317
#define ULL(N)
uint64_t constant
Definition: types.hh:50
virtual const std::string name() const
Definition: sim_object.hh:120
void init(int original_length, int compressed_length)
Definition: tage_base.hh:96
bool tagePredict(ThreadID tid, Addr branch_pc, bool cond_branch, BranchInfo *bi)
TAGE prediction called from TAGE::predict.
Definition: tage_base.cc:355
void btbUpdate(ThreadID tid, Addr branch_addr, BranchInfo *&bi)
Definition: tage_base.cc:183
unsigned maxNumAlloc
Definition: tage_base.hh:476
Bitfield< 24 > j
std::vector< bool > noSkip
Definition: tage_base.hh:481
void update(uint8_t *h)
Definition: tage_base.hh:103
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Definition: statistics.hh:279
const unsigned logRatioBiModalHystEntries
Definition: tage_base.hh:420
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:227
Bitfield< 23 > up
Definition: types.hh:134
virtual void buildTageTables()
Instantiates the TAGE table entries.
Definition: tage_base.cc:161
unsigned getTageCtrBits() const
Definition: tage_base.cc:789
std::vector< ThreadHistory > threadHistory
Definition: tage_base.hh:459
int * tableTags
Definition: tage_base.hh:468
Stats::Scalar tageAltMatchProviderCorrect
Definition: tage_base.hh:491
virtual int bindex(Addr pc_in) const
Computes the index used to access the bimodal table.
Definition: tage_base.cc:202
int64_t tCounter
Definition: tage_base.hh:471
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
Definition: statistics.hh:312
Stats::Vector tageAltMatchProvider
Definition: tage_base.hh:502
TAGEBase(const TAGEBaseParams *p)
Definition: tage_base.cc:48
std::vector< int8_t > useAltPredForNewlyAllocated
Definition: tage_base.hh:470
virtual void handleTAGEUpdate(Addr branch_pc, bool taken, BranchInfo *bi)
Handles the update of the TAGE entries.
Definition: tage_base.cc:550
T bits(T val, int first, int last)
Extract the bitfield from position &#39;first&#39; to &#39;last&#39; (inclusive) from &#39;val&#39; and right justify it...
Definition: bitfield.hh:72
std::vector< unsigned > tagTableTagWidths
Definition: tage_base.hh:429
Stats::Scalar tageLongestMatchProviderWrong
Definition: tage_base.hh:494
FoldedHistory * computeIndices
Definition: tage_base.hh:455
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...
Definition: tage_base.cc:335
int * histLengths
Definition: tage_base.hh:466
virtual void initFoldedHistories(ThreadHistory &history)
Initialization of the folded histories.
Definition: tage_base.cc:146
Bitfield< 0 > p
virtual void updateHistories(ThreadID tid, Addr branch_pc, bool taken, BranchInfo *b, bool speculative, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr, Addr target=MaxAddr)
(Speculatively) updates global histories (path and direction).
Definition: tage_base.cc:583
Abstract superclass for simulation objects.
Definition: sim_object.hh:96
int8_t getCtr(int hitBank, int hitBankIndex) const
Definition: tage_base.cc:783
const unsigned tagTableCounterBits
Definition: tage_base.hh:422
virtual void handleUReset()
Handles the U bits reset.
Definition: tage_base.cc:488
size_t getSizeInBits() const
Definition: tage_base.cc:807

Generated on Fri Feb 28 2020 16:26:59 for gem5 by doxygen 1.8.13