2 * Copyright (c) 2014 The University of Wisconsin
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)
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.
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.
33 * Authors: Vignyan Reddy, Dibakar Gope and Arthur Perais,
34 * from André Seznec's code.
38 * Implementation of a TAGE branch predictor
41 #include "cpu/pred/tage_base.hh"
43 #include "base/intmath.hh"
44 #include "base/logging.hh"
45 #include "debug/Fetch.hh"
46 #include "debug/Tage.hh"
48 TAGEBase::TAGEBase(const TAGEBaseParams
*p
)
50 logRatioBiModalHystEntries(p
->logRatioBiModalHystEntries
),
51 nHistoryTables(p
->nHistoryTables
),
52 tagTableCounterBits(p
->tagTableCounterBits
),
53 tagTableUBits(p
->tagTableUBits
),
54 histBufferSize(p
->histBufferSize
),
57 pathHistBits(p
->pathHistBits
),
58 tagTableTagWidths(p
->tagTableTagWidths
),
59 logTagTableSizes(p
->logTagTableSizes
),
60 threadHistory(p
->numThreads
),
61 logUResetPeriod(p
->logUResetPeriod
),
62 numUseAltOnNa(p
->numUseAltOnNa
),
63 useAltOnNaBits(p
->useAltOnNaBits
),
64 maxNumAlloc(p
->maxNumAlloc
),
66 speculativeHistUpdate(p
->speculativeHistUpdate
),
67 instShiftAmt(p
->instShiftAmt
)
70 // Set all the table to enabled by default
71 noSkip
.resize(nHistoryTables
+ 1, true);
76 TAGEBase::makeBranchInfo() {
77 return new BranchInfo(*this);
83 // Current method for periodically resetting the u counter bits only
84 // works for 1 or 2 bits
85 // Also make sure that it is not 0
86 assert(tagTableUBits
<= 2 && (tagTableUBits
> 0));
88 // we use int type for the path history, so it cannot be more than
90 assert(pathHistBits
<= (sizeof(int)*8));
92 // initialize the counter to half of the period
93 assert(logUResetPeriod
!= 0);
94 tCounter
= ULL(1) << (logUResetPeriod
- 1);
96 assert(histBufferSize
> maxHist
* 2);
98 useAltPredForNewlyAllocated
.resize(numUseAltOnNa
, 0);
100 for (auto& history
: threadHistory
) {
101 history
.pathHist
= 0;
102 history
.globalHistory
= new uint8_t[histBufferSize
];
103 history
.gHist
= history
.globalHistory
;
104 memset(history
.gHist
, 0, histBufferSize
);
108 histLengths
= new int [nHistoryTables
+1];
110 calculateParameters();
112 assert(tagTableTagWidths
.size() == (nHistoryTables
+1));
113 assert(logTagTableSizes
.size() == (nHistoryTables
+1));
115 // First entry is for the Bimodal table and it is untagged in this
117 assert(tagTableTagWidths
[0] == 0);
119 for (auto& history
: threadHistory
) {
120 history
.computeIndices
= new FoldedHistory
[nHistoryTables
+1];
121 history
.computeTags
[0] = new FoldedHistory
[nHistoryTables
+1];
122 history
.computeTags
[1] = new FoldedHistory
[nHistoryTables
+1];
124 initFoldedHistories(history
);
127 const uint64_t bimodalTableSize
= ULL(1) << logTagTableSizes
[0];
128 btablePrediction
.resize(bimodalTableSize
, false);
129 btableHysteresis
.resize(bimodalTableSize
>> logRatioBiModalHystEntries
,
132 gtable
= new TageEntry
*[nHistoryTables
+ 1];
135 tableIndices
= new int [nHistoryTables
+1];
136 tableTags
= new int [nHistoryTables
+1];
140 TAGEBase::initFoldedHistories(ThreadHistory
& history
)
142 for (int i
= 1; i
<= nHistoryTables
; i
++) {
143 history
.computeIndices
[i
].init(
144 histLengths
[i
], (logTagTableSizes
[i
]));
145 history
.computeTags
[0][i
].init(
146 history
.computeIndices
[i
].origLength
, tagTableTagWidths
[i
]);
147 history
.computeTags
[1][i
].init(
148 history
.computeIndices
[i
].origLength
, tagTableTagWidths
[i
]-1);
149 DPRINTF(Tage
, "HistLength:%d, TTSize:%d, TTTWidth:%d\n",
150 histLengths
[i
], logTagTableSizes
[i
], tagTableTagWidths
[i
]);
155 TAGEBase::buildTageTables()
157 for (int i
= 1; i
<= nHistoryTables
; i
++) {
158 gtable
[i
] = new TageEntry
[1<<(logTagTableSizes
[i
])];
163 TAGEBase::calculateParameters()
165 histLengths
[1] = minHist
;
166 histLengths
[nHistoryTables
] = maxHist
;
168 for (int i
= 2; i
<= nHistoryTables
; i
++) {
169 histLengths
[i
] = (int) (((double) minHist
*
170 pow ((double) (maxHist
) / (double) minHist
,
171 (double) (i
- 1) / (double) ((nHistoryTables
- 1))))
177 TAGEBase::btbUpdate(ThreadID tid
, Addr branch_pc
, BranchInfo
* &bi
)
179 if (speculativeHistUpdate
) {
180 ThreadHistory
& tHist
= threadHistory
[tid
];
181 DPRINTF(Tage
, "BTB miss resets prediction: %lx\n", branch_pc
);
182 assert(tHist
.gHist
== &tHist
.globalHistory
[tHist
.ptGhist
]);
184 for (int i
= 1; i
<= nHistoryTables
; i
++) {
185 tHist
.computeIndices
[i
].comp
= bi
->ci
[i
];
186 tHist
.computeTags
[0][i
].comp
= bi
->ct0
[i
];
187 tHist
.computeTags
[1][i
].comp
= bi
->ct1
[i
];
188 tHist
.computeIndices
[i
].update(tHist
.gHist
);
189 tHist
.computeTags
[0][i
].update(tHist
.gHist
);
190 tHist
.computeTags
[1][i
].update(tHist
.gHist
);
196 TAGEBase::bindex(Addr pc_in
) const
198 return ((pc_in
>> instShiftAmt
) & ((ULL(1) << (logTagTableSizes
[0])) - 1));
202 TAGEBase::F(int A
, int size
, int bank
) const
206 A
= A
& ((ULL(1) << size
) - 1);
207 A1
= (A
& ((ULL(1) << logTagTableSizes
[bank
]) - 1));
208 A2
= (A
>> logTagTableSizes
[bank
]);
209 A2
= ((A2
<< bank
) & ((ULL(1) << logTagTableSizes
[bank
]) - 1))
210 + (A2
>> (logTagTableSizes
[bank
] - bank
));
212 A
= ((A
<< bank
) & ((ULL(1) << logTagTableSizes
[bank
]) - 1))
213 + (A
>> (logTagTableSizes
[bank
] - bank
));
217 // gindex computes a full hash of pc, ghist and pathHist
219 TAGEBase::gindex(ThreadID tid
, Addr pc
, int bank
) const
222 int hlen
= (histLengths
[bank
] > pathHistBits
) ? pathHistBits
:
224 const unsigned int shiftedPc
= pc
>> instShiftAmt
;
227 (shiftedPc
>> ((int) abs(logTagTableSizes
[bank
] - bank
) + 1)) ^
228 threadHistory
[tid
].computeIndices
[bank
].comp
^
229 F(threadHistory
[tid
].pathHist
, hlen
, bank
);
231 return (index
& ((ULL(1) << (logTagTableSizes
[bank
])) - 1));
237 TAGEBase::gtag(ThreadID tid
, Addr pc
, int bank
) const
239 int tag
= (pc
>> instShiftAmt
) ^
240 threadHistory
[tid
].computeTags
[0][bank
].comp
^
241 (threadHistory
[tid
].computeTags
[1][bank
].comp
<< 1);
243 return (tag
& ((ULL(1) << tagTableTagWidths
[bank
]) - 1));
247 // Up-down saturating counter
250 TAGEBase::ctrUpdate(T
& ctr
, bool taken
, int nbits
)
252 assert(nbits
<= sizeof(T
) << 3);
254 if (ctr
< ((1 << (nbits
- 1)) - 1))
257 if (ctr
> -(1 << (nbits
- 1)))
262 // int8_t and int versions of this function may be needed
263 template void TAGEBase::ctrUpdate(int8_t & ctr
, bool taken
, int nbits
);
264 template void TAGEBase::ctrUpdate(int & ctr
, bool taken
, int nbits
);
266 // Up-down unsigned saturating counter
268 TAGEBase::unsignedCtrUpdate(uint8_t & ctr
, bool up
, unsigned nbits
)
270 assert(nbits
<= sizeof(uint8_t) << 3);
272 if (ctr
< ((1 << nbits
) - 1))
280 // Bimodal prediction
282 TAGEBase::getBimodePred(Addr pc
, BranchInfo
* bi
) const
284 return btablePrediction
[bi
->bimodalIndex
];
288 // Update the bimodal predictor: a hysteresis bit is shared among N prediction
289 // bits (N = 2 ^ logRatioBiModalHystEntries)
291 TAGEBase::baseUpdate(Addr pc
, bool taken
, BranchInfo
* bi
)
293 int inter
= (btablePrediction
[bi
->bimodalIndex
] << 1)
294 + btableHysteresis
[bi
->bimodalIndex
>> logRatioBiModalHystEntries
];
298 } else if (inter
> 0) {
301 const bool pred
= inter
>> 1;
302 const bool hyst
= inter
& 1;
303 btablePrediction
[bi
->bimodalIndex
] = pred
;
304 btableHysteresis
[bi
->bimodalIndex
>> logRatioBiModalHystEntries
] = hyst
;
305 DPRINTF(Tage
, "Updating branch %lx, pred:%d, hyst:%d\n", pc
, pred
, hyst
);
308 // shifting the global history: we manage the history in a big table in order
309 // to reduce simulation time
311 TAGEBase::updateGHist(uint8_t * &h
, bool dir
, uint8_t * tab
, int &pt
)
314 DPRINTF(Tage
, "Rolling over the histories\n");
315 // Copy beginning of globalHistoryBuffer to end, such that
316 // the last maxHist outcomes are still reachable
317 // through pt[0 .. maxHist - 1].
318 for (int i
= 0; i
< maxHist
; i
++)
319 tab
[histBufferSize
- maxHist
+ i
] = tab
[i
];
320 pt
= histBufferSize
- maxHist
;
325 h
[0] = (dir
) ? 1 : 0;
329 TAGEBase::calculateIndicesAndTags(ThreadID tid
, Addr branch_pc
,
332 // computes the table addresses and the partial tags
333 for (int i
= 1; i
<= nHistoryTables
; i
++) {
334 tableIndices
[i
] = gindex(tid
, branch_pc
, i
);
335 bi
->tableIndices
[i
] = tableIndices
[i
];
336 tableTags
[i
] = gtag(tid
, branch_pc
, i
);
337 bi
->tableTags
[i
] = tableTags
[i
];
342 TAGEBase::getUseAltIdx(BranchInfo
* bi
)
344 // There is only 1 counter on the base TAGE implementation
349 TAGEBase::tagePredict(ThreadID tid
, Addr branch_pc
,
350 bool cond_branch
, BranchInfo
* bi
)
353 bool pred_taken
= true;
358 calculateIndicesAndTags(tid
, pc
, bi
);
360 bi
->bimodalIndex
= bindex(pc
);
364 //Look for the bank with longest matching history
365 for (int i
= nHistoryTables
; i
> 0; i
--) {
367 gtable
[i
][tableIndices
[i
]].tag
== tableTags
[i
]) {
369 bi
->hitBankIndex
= tableIndices
[bi
->hitBank
];
373 //Look for the alternate bank
374 for (int i
= bi
->hitBank
- 1; i
> 0; i
--) {
376 gtable
[i
][tableIndices
[i
]].tag
== tableTags
[i
]) {
378 bi
->altBankIndex
= tableIndices
[bi
->altBank
];
382 //computes the prediction and the alternate prediction
383 if (bi
->hitBank
> 0) {
384 if (bi
->altBank
> 0) {
386 gtable
[bi
->altBank
][tableIndices
[bi
->altBank
]].ctr
>= 0;
389 bi
->altTaken
= getBimodePred(pc
, bi
);
392 bi
->longestMatchPred
=
393 gtable
[bi
->hitBank
][tableIndices
[bi
->hitBank
]].ctr
>= 0;
395 abs(2 * gtable
[bi
->hitBank
][bi
->hitBankIndex
].ctr
+ 1) <= 1;
397 //if the entry is recognized as a newly allocated entry and
398 //useAltPredForNewlyAllocated is positive use the alternate
400 if ((useAltPredForNewlyAllocated
[getUseAltIdx(bi
)] < 0) ||
401 ! bi
->pseudoNewAlloc
) {
402 bi
->tagePred
= bi
->longestMatchPred
;
403 bi
->provider
= TAGE_LONGEST_MATCH
;
405 bi
->tagePred
= bi
->altTaken
;
406 bi
->provider
= bi
->altBank
? TAGE_ALT_MATCH
410 bi
->altTaken
= getBimodePred(pc
, bi
);
411 bi
->tagePred
= bi
->altTaken
;
412 bi
->longestMatchPred
= bi
->altTaken
;
413 bi
->provider
= BIMODAL_ONLY
;
415 //end TAGE prediction
417 pred_taken
= (bi
->tagePred
);
418 DPRINTF(Tage
, "Predict for %lx: taken?:%d, tagePred:%d, altPred:%d\n",
419 branch_pc
, pred_taken
, bi
->tagePred
, bi
->altTaken
);
421 bi
->branchPC
= branch_pc
;
422 bi
->condBranch
= cond_branch
;
427 TAGEBase::adjustAlloc(bool & alloc
, bool taken
, bool pred_taken
)
429 // Nothing for this base class implementation
433 TAGEBase::handleAllocAndUReset(bool alloc
, bool taken
, BranchInfo
* bi
,
437 // is there some "unuseful" entry to allocate
439 for (int i
= nHistoryTables
; i
> bi
->hitBank
; i
--) {
440 if (gtable
[i
][bi
->tableIndices
[i
]].u
< min
) {
441 min
= gtable
[i
][bi
->tableIndices
[i
]].u
;
445 // we allocate an entry with a longer history
446 // to avoid ping-pong, we do not choose systematically the next
447 // entry, but among the 3 next entries
449 ((ULL(1) << (nHistoryTables
- bi
->hitBank
- 1)) - 1);
450 int X
= bi
->hitBank
+ 1;
456 // No entry available, forces one to be available
458 gtable
[X
][bi
->tableIndices
[X
]].u
= 0;
463 unsigned numAllocated
= 0;
464 for (int i
= X
; i
<= nHistoryTables
; i
++) {
465 if ((gtable
[i
][bi
->tableIndices
[i
]].u
== 0)) {
466 gtable
[i
][bi
->tableIndices
[i
]].tag
= bi
->tableTags
[i
];
467 gtable
[i
][bi
->tableIndices
[i
]].ctr
= (taken
) ? 0 : -1;
469 if (numAllocated
== maxNumAlloc
) {
482 TAGEBase::handleUReset()
484 //periodic reset of u: reset is not complete but bit by bit
485 if ((tCounter
& ((ULL(1) << logUResetPeriod
) - 1)) == 0) {
486 // reset least significant bit
487 // most significant bit becomes least significant bit
488 for (int i
= 1; i
<= nHistoryTables
; i
++) {
489 for (int j
= 0; j
< (ULL(1) << logTagTableSizes
[i
]); j
++) {
490 resetUctr(gtable
[i
][j
].u
);
497 TAGEBase::resetUctr(uint8_t & u
)
503 TAGEBase::condBranchUpdate(ThreadID tid
, Addr branch_pc
, bool taken
,
504 BranchInfo
* bi
, int nrand
, Addr corrTarget
, bool pred
)
507 // try to allocate a new entries only if prediction was wrong
508 bool alloc
= (bi
->tagePred
!= taken
) && (bi
->hitBank
< nHistoryTables
);
509 if (bi
->hitBank
> 0) {
510 // Manage the selection between longest matching and alternate
511 // matching for "pseudo"-newly allocated longest matching entry
512 bool PseudoNewAlloc
= bi
->pseudoNewAlloc
;
513 // an entry is considered as newly allocated if its prediction
515 if (PseudoNewAlloc
) {
516 if (bi
->longestMatchPred
== taken
) {
519 // if it was delivering the correct prediction, no need to
520 // allocate new entry even if the overall prediction was false
521 if (bi
->longestMatchPred
!= bi
->altTaken
) {
522 ctrUpdate(useAltPredForNewlyAllocated
[getUseAltIdx(bi
)],
523 bi
->altTaken
== taken
, useAltOnNaBits
);
528 adjustAlloc(alloc
, taken
, pred
);
530 handleAllocAndUReset(alloc
, taken
, bi
, nrand
);
532 handleTAGEUpdate(branch_pc
, taken
, bi
);
536 TAGEBase::handleTAGEUpdate(Addr branch_pc
, bool taken
, BranchInfo
* bi
)
538 if (bi
->hitBank
> 0) {
539 DPRINTF(Tage
, "Updating tag table entry (%d,%d) for branch %lx\n",
540 bi
->hitBank
, bi
->hitBankIndex
, branch_pc
);
541 ctrUpdate(gtable
[bi
->hitBank
][bi
->hitBankIndex
].ctr
, taken
,
542 tagTableCounterBits
);
543 // if the provider entry is not certified to be useful also update
544 // the alternate prediction
545 if (gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
== 0) {
546 if (bi
->altBank
> 0) {
547 ctrUpdate(gtable
[bi
->altBank
][bi
->altBankIndex
].ctr
, taken
,
548 tagTableCounterBits
);
549 DPRINTF(Tage
, "Updating tag table entry (%d,%d) for"
550 " branch %lx\n", bi
->hitBank
, bi
->hitBankIndex
,
553 if (bi
->altBank
== 0) {
554 baseUpdate(branch_pc
, taken
, bi
);
558 // update the u counter
559 if (bi
->tagePred
!= bi
->altTaken
) {
560 unsignedCtrUpdate(gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
,
561 bi
->tagePred
== taken
, tagTableUBits
);
564 baseUpdate(branch_pc
, taken
, bi
);
569 TAGEBase::updateHistories(ThreadID tid
, Addr branch_pc
, bool taken
,
570 BranchInfo
* bi
, bool speculative
,
571 const StaticInstPtr
&inst
, Addr target
)
573 if (speculative
!= speculativeHistUpdate
) {
576 ThreadHistory
& tHist
= threadHistory
[tid
];
578 bool pathbit
= ((branch_pc
>> instShiftAmt
) & 1);
579 //on a squash, return pointers to this and recompute indices.
580 //update user history
581 updateGHist(tHist
.gHist
, taken
, tHist
.globalHistory
, tHist
.ptGhist
);
582 tHist
.pathHist
= (tHist
.pathHist
<< 1) + pathbit
;
583 tHist
.pathHist
= (tHist
.pathHist
& ((ULL(1) << pathHistBits
) - 1));
586 bi
->ptGhist
= tHist
.ptGhist
;
587 bi
->pathHist
= tHist
.pathHist
;
590 //prepare next index and tag computations for user branchs
591 for (int i
= 1; i
<= nHistoryTables
; i
++)
594 bi
->ci
[i
] = tHist
.computeIndices
[i
].comp
;
595 bi
->ct0
[i
] = tHist
.computeTags
[0][i
].comp
;
596 bi
->ct1
[i
] = tHist
.computeTags
[1][i
].comp
;
598 tHist
.computeIndices
[i
].update(tHist
.gHist
);
599 tHist
.computeTags
[0][i
].update(tHist
.gHist
);
600 tHist
.computeTags
[1][i
].update(tHist
.gHist
);
602 DPRINTF(Tage
, "Updating global histories with branch:%lx; taken?:%d, "
603 "path Hist: %x; pointer:%d\n", branch_pc
, taken
, tHist
.pathHist
,
605 assert(threadHistory
[tid
].gHist
==
606 &threadHistory
[tid
].globalHistory
[threadHistory
[tid
].ptGhist
]);
610 TAGEBase::squash(ThreadID tid
, bool taken
, TAGEBase::BranchInfo
*bi
,
613 if (!speculativeHistUpdate
) {
614 /* If there are no speculative updates, no actions are needed */
618 ThreadHistory
& tHist
= threadHistory
[tid
];
619 DPRINTF(Tage
, "Restoring branch info: %lx; taken? %d; PathHistory:%x, "
620 "pointer:%d\n", bi
->branchPC
,taken
, bi
->pathHist
, bi
->ptGhist
);
621 tHist
.pathHist
= bi
->pathHist
;
622 tHist
.ptGhist
= bi
->ptGhist
;
623 tHist
.gHist
= &(tHist
.globalHistory
[tHist
.ptGhist
]);
624 tHist
.gHist
[0] = (taken
? 1 : 0);
625 for (int i
= 1; i
<= nHistoryTables
; i
++) {
626 tHist
.computeIndices
[i
].comp
= bi
->ci
[i
];
627 tHist
.computeTags
[0][i
].comp
= bi
->ct0
[i
];
628 tHist
.computeTags
[1][i
].comp
= bi
->ct1
[i
];
629 tHist
.computeIndices
[i
].update(tHist
.gHist
);
630 tHist
.computeTags
[0][i
].update(tHist
.gHist
);
631 tHist
.computeTags
[1][i
].update(tHist
.gHist
);
636 TAGEBase::extraAltCalc(BranchInfo
* bi
)
638 // do nothing. This is only used in some derived classes
643 TAGEBase::updateStats(bool taken
, BranchInfo
* bi
)
645 if (taken
== bi
->tagePred
) {
646 // correct prediction
647 switch (bi
->provider
) {
648 case BIMODAL_ONLY
: tageBimodalProviderCorrect
++; break;
649 case TAGE_LONGEST_MATCH
: tageLongestMatchProviderCorrect
++; break;
650 case BIMODAL_ALT_MATCH
: bimodalAltMatchProviderCorrect
++; break;
651 case TAGE_ALT_MATCH
: tageAltMatchProviderCorrect
++; break;
655 switch (bi
->provider
) {
656 case BIMODAL_ONLY
: tageBimodalProviderWrong
++; break;
657 case TAGE_LONGEST_MATCH
:
658 tageLongestMatchProviderWrong
++;
659 if (bi
->altTaken
== taken
) {
660 tageAltMatchProviderWouldHaveHit
++;
663 case BIMODAL_ALT_MATCH
:
664 bimodalAltMatchProviderWrong
++;
667 tageAltMatchProviderWrong
++;
671 switch (bi
->provider
) {
672 case BIMODAL_ALT_MATCH
:
674 if (bi
->longestMatchPred
== taken
) {
675 tageLongestMatchProviderWouldHaveHit
++;
680 switch (bi
->provider
) {
681 case TAGE_LONGEST_MATCH
:
683 tageLongestMatchProvider
[bi
->hitBank
]++;
684 tageAltMatchProvider
[bi
->altBank
]++;
690 TAGEBase::getGHR(ThreadID tid
, BranchInfo
*bi
) const
693 for (unsigned i
= 0; i
< 32; i
++) {
694 // Make sure we don't go out of bounds
695 int gh_offset
= bi
->ptGhist
+ i
;
696 assert(&(threadHistory
[tid
].globalHistory
[gh_offset
]) <
697 threadHistory
[tid
].globalHistory
+ histBufferSize
);
698 val
|= ((threadHistory
[tid
].globalHistory
[gh_offset
] & 0x1) << i
);
707 tageLongestMatchProviderCorrect
708 .name(name() + ".tageLongestMatchProviderCorrect")
709 .desc("Number of times TAGE Longest Match is the provider and "
710 "the prediction is correct");
712 tageAltMatchProviderCorrect
713 .name(name() + ".tageAltMatchProviderCorrect")
714 .desc("Number of times TAGE Alt Match is the provider and "
715 "the prediction is correct");
717 bimodalAltMatchProviderCorrect
718 .name(name() + ".bimodalAltMatchProviderCorrect")
719 .desc("Number of times TAGE Alt Match is the bimodal and it is the "
720 "provider and the prediction is correct");
722 tageBimodalProviderCorrect
723 .name(name() + ".tageBimodalProviderCorrect")
724 .desc("Number of times there are no hits on the TAGE tables "
725 "and the bimodal prediction is correct");
727 tageLongestMatchProviderWrong
728 .name(name() + ".tageLongestMatchProviderWrong")
729 .desc("Number of times TAGE Longest Match is the provider and "
730 "the prediction is wrong");
732 tageAltMatchProviderWrong
733 .name(name() + ".tageAltMatchProviderWrong")
734 .desc("Number of times TAGE Alt Match is the provider and "
735 "the prediction is wrong");
737 bimodalAltMatchProviderWrong
738 .name(name() + ".bimodalAltMatchProviderWrong")
739 .desc("Number of times TAGE Alt Match is the bimodal and it is the "
740 "provider and the prediction is wrong");
742 tageBimodalProviderWrong
743 .name(name() + ".tageBimodalProviderWrong")
744 .desc("Number of times there are no hits on the TAGE tables "
745 "and the bimodal prediction is wrong");
747 tageAltMatchProviderWouldHaveHit
748 .name(name() + ".tageAltMatchProviderWouldHaveHit")
749 .desc("Number of times TAGE Longest Match is the provider, "
750 "the prediction is wrong and Alt Match prediction was correct");
752 tageLongestMatchProviderWouldHaveHit
753 .name(name() + ".tageLongestMatchProviderWouldHaveHit")
754 .desc("Number of times TAGE Alt Match is the provider, the "
755 "prediction is wrong and Longest Match prediction was correct");
757 tageLongestMatchProvider
758 .init(nHistoryTables
+ 1)
759 .name(name() + ".tageLongestMatchProvider")
760 .desc("TAGE provider for longest match");
763 .init(nHistoryTables
+ 1)
764 .name(name() + ".tageAltMatchProvider")
765 .desc("TAGE provider for alt match");
769 TAGEBase::getCtr(int hitBank
, int hitBankIndex
) const
771 return gtable
[hitBank
][hitBankIndex
].ctr
;
775 TAGEBase::getTageCtrBits() const
777 return tagTableCounterBits
;
781 TAGEBase::getPathHist(ThreadID tid
) const
783 return threadHistory
[tid
].pathHist
;
787 TAGEBase::isSpeculativeUpdateEnabled() const
789 return speculativeHistUpdate
;
793 TAGEBaseParams::create()
795 return new TAGEBase(this);