2 * Copyright (c) 2018 Metempsy Technology Consulting
5 * Copyright (c) 2006 INRIA (Institut National de Recherche en
6 * Informatique et en Automatique / French National Research Institute
7 * for Computer Science and Applied Mathematics)
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are
13 * met: redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer;
15 * redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution;
18 * neither the name of the copyright holders nor the names of its
19 * contributors may be used to endorse or promote products derived from
20 * this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * Author: André Seznec, Pau Cabre, Javier Bueno
39 * TAGE-SC-L branch predictor base class (devised by Andre Seznec)
40 * It consits of a TAGE + a statistical corrector (SC) + a loop predictor (L)
43 #include "cpu/pred/tage_sc_l.hh"
45 #include "base/random.hh"
46 #include "debug/TageSCL.hh"
49 TAGE_SC_L_LoopPredictor::calcConf(int index
) const
51 return LoopPredictor::calcConf(index
) ||
52 (ltable
[index
].confidence
* ltable
[index
].numIter
> 128);
56 TAGE_SC_L_LoopPredictor::optionalAgeInc() const
58 return (random_mt
.random
<int>() & 7) == 0;
61 TAGE_SC_L::TAGE_SC_L(const TAGE_SC_LParams
&p
)
62 : LTAGE(p
), statisticalCorrector(p
.statistical_corrector
)
67 TAGE_SC_L_TAGE::makeBranchInfo()
69 return new BranchInfo(*this);
72 TAGE_SC_L_TAGE::calculateParameters()
74 unsigned numHistLengths
= nHistoryTables
/2;
75 histLengths
[1] = minHist
;
76 histLengths
[numHistLengths
] = maxHist
;
78 // This calculates the different history lenghts
79 // there are only numHistLengths different lengths
80 // They are initially set to the lower half of histLengths
81 for (int i
= 2; i
<= numHistLengths
; i
++) {
82 histLengths
[i
] = (int) (((double) minHist
*
83 pow ((double) (maxHist
) / (double) minHist
,
84 (double) (i
- 1) / (double) ((numHistLengths
- 1))))
88 // This copies and duplicates the values from the lower half of the table
89 // Ex: 4, 6, 9, 13 would get exanded to 4, 4, 6, 6, 9, 9, 13, 13
90 for (int i
= nHistoryTables
; i
> 1; i
--)
92 histLengths
[i
] = histLengths
[(i
+ 1) / 2];
95 for (int i
= 1; i
<= nHistoryTables
; i
++)
97 tagTableTagWidths
.push_back(
98 (i
< firstLongTagTable
) ? shortTagsSize
: longTagsSize
);
100 logTagTableSizes
.push_back(logTagTableSize
);
105 TAGE_SC_L_TAGE::buildTageTables()
107 // Trick! We only allocate entries for tables 1 and firstLongTagTable and
108 // make the other tables point to these allocated entries
110 gtable
[1] = new TageEntry
[shortTagsTageFactor
* (1 << logTagTableSize
)];
111 gtable
[firstLongTagTable
] =
112 new TageEntry
[longTagsTageFactor
* (1 << logTagTableSize
)];
113 for (int i
= 2; i
< firstLongTagTable
; ++i
) {
114 gtable
[i
] = gtable
[1];
116 for (int i
= firstLongTagTable
+ 1; i
<= nHistoryTables
; ++i
) {
117 gtable
[i
] = gtable
[firstLongTagTable
];
122 TAGE_SC_L_TAGE::calculateIndicesAndTags(
123 ThreadID tid
, Addr pc
, TAGEBase::BranchInfo
* bi
)
125 // computes the table addresses and the partial tags
127 for (int i
= 1; i
<= nHistoryTables
; i
+= 2) {
128 tableIndices
[i
] = gindex(tid
, pc
, i
);
129 tableTags
[i
] = gtag(tid
, pc
, i
);
130 tableTags
[i
+ 1] = tableTags
[i
];
131 tableIndices
[i
+ 1] = tableIndices
[i
] ^
132 (tableTags
[i
] & ((1 << logTagTableSizes
[i
]) - 1));
134 bi
->tableTags
[i
] = tableTags
[i
];
135 bi
->tableTags
[i
+1] = tableTags
[i
+1];
138 Addr t
= (pc
^ (threadHistory
[tid
].pathHist
&
139 ((1 << histLengths
[firstLongTagTable
]) - 1)))
140 % longTagsTageFactor
;
142 for (int i
= firstLongTagTable
; i
<= nHistoryTables
; i
++) {
144 tableIndices
[i
] += (t
<< logTagTableSizes
[i
]);
145 bi
->tableIndices
[i
] = tableIndices
[i
];
147 t
= t
% longTagsTageFactor
;
151 t
= (pc
^ (threadHistory
[tid
].pathHist
& ((1 << histLengths
[1]) - 1)))
152 % shortTagsTageFactor
;
154 for (int i
= 1; i
<= firstLongTagTable
- 1; i
++) {
156 tableIndices
[i
] += (t
<< logTagTableSizes
[i
]);
157 bi
->tableIndices
[i
] = tableIndices
[i
];
159 t
= t
% shortTagsTageFactor
;
165 TAGE_SC_L_TAGE::getUseAltIdx(TAGEBase::BranchInfo
* bi
, Addr branch_pc
)
167 BranchInfo
*tbi
= static_cast<BranchInfo
*>(bi
);
169 idx
= ((((bi
->hitBank
-1)/8)<<1)+tbi
->altConf
) % (numUseAltOnNa
-1);
174 TAGE_SC_L_TAGE::gindex(ThreadID tid
, Addr pc
, int bank
) const
177 int hlen
= (histLengths
[bank
] > pathHistBits
) ? pathHistBits
:
179 unsigned int shortPc
= pc
;
181 // pc is not shifted by instShiftAmt in this implementation
183 (shortPc
>> ((int) abs(logTagTableSizes
[bank
] - bank
) + 1)) ^
184 threadHistory
[tid
].computeIndices
[bank
].comp
^
185 F(threadHistory
[tid
].pathHist
, hlen
, bank
);
187 index
= gindex_ext(index
, bank
);
189 return (index
& ((ULL(1) << (logTagTableSizes
[bank
])) - 1));
193 TAGE_SC_L_TAGE::F(int a
, int size
, int bank
) const
197 a
= a
& ((ULL(1) << size
) - 1);
198 a1
= (a
& ((ULL(1) << logTagTableSizes
[bank
]) - 1));
199 a2
= (a
>> logTagTableSizes
[bank
]);
201 if (bank
< logTagTableSizes
[bank
]) {
202 a2
= ((a2
<< bank
) & ((ULL(1) << logTagTableSizes
[bank
]) - 1))
203 + (a2
>> (logTagTableSizes
[bank
] - bank
));
208 if (bank
< logTagTableSizes
[bank
]) {
209 a
= ((a
<< bank
) & ((ULL(1) << logTagTableSizes
[bank
]) - 1))
210 + (a
>> (logTagTableSizes
[bank
] - bank
));
217 TAGE_SC_L_TAGE::bindex(Addr pc
) const
219 return ((pc
^ (pc
>> instShiftAmt
)) &
220 ((ULL(1) << (logTagTableSizes
[0])) - 1));
224 TAGE_SC_L_TAGE::updatePathAndGlobalHistory(
225 ThreadHistory
& tHist
, int brtype
, bool taken
, Addr branch_pc
, Addr target
)
228 int tmp
= ((branch_pc
^ (branch_pc
>> instShiftAmt
))) ^ taken
;
229 int path
= branch_pc
^ (branch_pc
>> instShiftAmt
)
230 ^ (branch_pc
>> (instShiftAmt
+2));
231 if ((brtype
== 3) & taken
) {
232 tmp
= (tmp
^ (target
>> instShiftAmt
));
233 path
= path
^ (target
>> instShiftAmt
) ^ (target
>> (instShiftAmt
+2));
236 // some branch types use 3 bits in global history, the others just 2
237 int maxt
= (brtype
== 2) ? 3 : 2;
239 for (int t
= 0; t
< maxt
; t
++) {
240 bool dir
= (tmp
& 1);
242 int pathbit
= (path
& 127);
244 updateGHist(tHist
.gHist
, dir
, tHist
.globalHistory
, tHist
.ptGhist
);
245 tHist
.pathHist
= (tHist
.pathHist
<< 1) ^ pathbit
;
246 if (truncatePathHist
) {
247 // The 8KB implementation does not do this truncation
248 tHist
.pathHist
= (tHist
.pathHist
& ((ULL(1) << pathHistBits
) - 1));
250 for (int i
= 1; i
<= nHistoryTables
; i
++) {
251 tHist
.computeIndices
[i
].update(tHist
.gHist
);
252 tHist
.computeTags
[0][i
].update(tHist
.gHist
);
253 tHist
.computeTags
[1][i
].update(tHist
.gHist
);
259 TAGE_SC_L_TAGE::updateHistories(
260 ThreadID tid
, Addr branch_pc
, bool taken
, TAGEBase::BranchInfo
* b
,
261 bool speculative
, const StaticInstPtr
&inst
, Addr target
)
263 if (speculative
!= speculativeHistUpdate
) {
266 // speculation is not implemented
267 assert(! speculative
);
269 ThreadHistory
& tHist
= threadHistory
[tid
];
271 int brtype
= inst
->isDirectCtrl() ? 0 : 2;
272 if (! inst
->isUncondCtrl()) {
275 updatePathAndGlobalHistory(tHist
, brtype
, taken
, branch_pc
, target
);
277 DPRINTF(TageSCL
, "Updating global histories with branch:%lx; taken?:%d, "
278 "path Hist: %x; pointer:%d\n", branch_pc
, taken
, tHist
.pathHist
,
283 TAGE_SC_L_TAGE::squash(ThreadID tid
, bool taken
, TAGEBase::BranchInfo
*bi
,
286 fatal("Speculation is not implemented");
290 TAGE_SC_L_TAGE::adjustAlloc(bool & alloc
, bool taken
, bool pred_taken
)
292 // Do not allocate too often if the prediction is ok
293 if ((taken
== pred_taken
) && ((random_mt
.random
<int>() & 31) != 0)) {
299 TAGE_SC_L_TAGE::calcDep(TAGEBase::BranchInfo
* bi
)
302 if ((random_mt
.random
<int>() & 127) < 32) {
305 return ((((bi
->hitBank
- 1 + 2 * a
) & 0xffe)) ^
306 (random_mt
.random
<int>() & 1));
310 TAGE_SC_L_TAGE::handleUReset()
312 //just the best formula for the Championship:
313 //In practice when one out of two entries are useful
318 if (tCounter
>= ((ULL(1) << logUResetPeriod
))) {
319 // Update the u bits for the short tags table
320 for (int j
= 0; j
< (shortTagsTageFactor
*(1<<logTagTableSize
)); j
++) {
321 resetUctr(gtable
[1][j
].u
);
324 // Update the u bits for the long tags table
325 for (int j
= 0; j
< (longTagsTageFactor
*(1<<logTagTableSize
)); j
++) {
326 resetUctr(gtable
[firstLongTagTable
][j
].u
);
334 TAGE_SC_L_TAGE::getBimodePred(Addr pc
, TAGEBase::BranchInfo
* tage_bi
) const
336 TAGE_SC_L_TAGE::BranchInfo
*bi
=
337 static_cast<TAGE_SC_L_TAGE::BranchInfo
*>(tage_bi
);
339 int bim
= (btablePrediction
[bi
->bimodalIndex
] << 1)
340 + btableHysteresis
[bi
->bimodalIndex
>> logRatioBiModalHystEntries
];
342 bi
->highConf
= (bim
== 0) || (bim
== 3);
343 bi
->lowConf
= ! bi
->highConf
;
344 bi
->altConf
= bi
->highConf
;
346 return TAGEBase::getBimodePred(pc
, tage_bi
);
350 TAGE_SC_L_TAGE::extraAltCalc(TAGEBase::BranchInfo
* bi
)
352 TAGE_SC_L_TAGE::BranchInfo
*tage_scl_bi
=
353 static_cast<TAGE_SC_L_TAGE::BranchInfo
*>(bi
);
354 int8_t ctr
= gtable
[bi
->altBank
][bi
->altBankIndex
].ctr
;
355 tage_scl_bi
->altConf
= (abs(2*ctr
+ 1) > 1);
359 TAGE_SC_L::predict(ThreadID tid
, Addr branch_pc
, bool cond_branch
, void* &b
)
361 TageSCLBranchInfo
*bi
= new TageSCLBranchInfo(*tage
,
362 *statisticalCorrector
,
366 bool pred_taken
= tage
->tagePredict(tid
, branch_pc
, cond_branch
,
368 pred_taken
= loopPredictor
->loopPredict(tid
, branch_pc
, cond_branch
,
369 bi
->lpBranchInfo
, pred_taken
,
372 if (bi
->lpBranchInfo
->loopPredUsed
) {
373 bi
->tageBranchInfo
->provider
= LOOP
;
376 TAGE_SC_L_TAGE::BranchInfo
* tage_scl_bi
=
377 static_cast<TAGE_SC_L_TAGE::BranchInfo
*>(bi
->tageBranchInfo
);
379 // Copy the confidences computed by TAGE
380 bi
->scBranchInfo
->lowConf
= tage_scl_bi
->lowConf
;
381 bi
->scBranchInfo
->highConf
= tage_scl_bi
->highConf
;
382 bi
->scBranchInfo
->altConf
= tage_scl_bi
->altConf
;
383 bi
->scBranchInfo
->medConf
= tage_scl_bi
->medConf
;
385 bool use_tage_ctr
= bi
->tageBranchInfo
->hitBank
> 0;
386 int8_t tage_ctr
= use_tage_ctr
?
387 tage
->getCtr(tage_scl_bi
->hitBank
, tage_scl_bi
->hitBankIndex
) : 0;
388 bool bias
= (bi
->tageBranchInfo
->longestMatchPred
!=
389 bi
->tageBranchInfo
->altTaken
);
391 pred_taken
= statisticalCorrector
->scPredict(tid
, branch_pc
, cond_branch
,
392 bi
->scBranchInfo
, pred_taken
, bias
, use_tage_ctr
, tage_ctr
,
393 tage
->getTageCtrBits(), bi
->tageBranchInfo
->hitBank
,
394 bi
->tageBranchInfo
->altBank
, tage
->getPathHist(tid
));
396 if (bi
->scBranchInfo
->usedScPred
) {
397 bi
->tageBranchInfo
->provider
= SC
;
400 // record final prediction
401 bi
->lpBranchInfo
->predTaken
= pred_taken
;
407 TAGE_SC_L::update(ThreadID tid
, Addr branch_pc
, bool taken
, void *bp_history
,
408 bool squashed
, const StaticInstPtr
& inst
, Addr corrTarget
)
412 TageSCLBranchInfo
* bi
= static_cast<TageSCLBranchInfo
*>(bp_history
);
413 TAGE_SC_L_TAGE::BranchInfo
* tage_bi
=
414 static_cast<TAGE_SC_L_TAGE::BranchInfo
*>(bi
->tageBranchInfo
);
417 if (tage
->isSpeculativeUpdateEnabled()) {
418 // This restores the global history, then update it
419 // and recomputes the folded histories.
420 tage
->squash(tid
, taken
, tage_bi
, corrTarget
);
421 if (bi
->tageBranchInfo
->condBranch
) {
422 loopPredictor
->squashLoop(bi
->lpBranchInfo
);
428 int nrand
= random_mt
.random
<int>() & 3;
429 if (tage_bi
->condBranch
) {
430 DPRINTF(TageSCL
, "Updating tables for branch:%lx; taken?:%d\n",
432 tage
->updateStats(taken
, bi
->tageBranchInfo
);
434 loopPredictor
->updateStats(taken
, bi
->lpBranchInfo
);
436 statisticalCorrector
->updateStats(taken
, bi
->scBranchInfo
);
438 bool bias
= (bi
->tageBranchInfo
->longestMatchPred
!=
439 bi
->tageBranchInfo
->altTaken
);
440 statisticalCorrector
->condBranchUpdate(tid
, branch_pc
, taken
,
441 bi
->scBranchInfo
, corrTarget
, bias
, bi
->tageBranchInfo
->hitBank
,
442 bi
->tageBranchInfo
->altBank
, tage
->getPathHist(tid
));
444 loopPredictor
->condBranchUpdate(tid
, branch_pc
, taken
,
445 bi
->tageBranchInfo
->tagePred
, bi
->lpBranchInfo
, instShiftAmt
);
447 tage
->condBranchUpdate(tid
, branch_pc
, taken
, bi
->tageBranchInfo
,
448 nrand
, corrTarget
, bi
->lpBranchInfo
->predTaken
);
451 if (!tage
->isSpeculativeUpdateEnabled()) {
452 statisticalCorrector
->scHistoryUpdate(branch_pc
, inst
, taken
,
453 bi
->scBranchInfo
, corrTarget
);
455 tage
->updateHistories(tid
, branch_pc
, taken
, bi
->tageBranchInfo
, false,
463 TAGE_SC_L::regStats()