Deleted Added
sdiff udiff text old ( 13444:26f81be73cb7 ) new ( 13454:19a5b4fb1f1f )
full compact
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.

--- 34 unchanged lines hidden (view full) ---

43#include "base/intmath.hh"
44#include "base/logging.hh"
45#include "base/random.hh"
46#include "base/trace.hh"
47#include "debug/Fetch.hh"
48#include "debug/LTage.hh"
49
50LTAGE::LTAGE(const LTAGEParams *params)
51 : TAGE(params),
52 logSizeLoopPred(params->logSizeLoopPred),
53 loopTableAgeBits(params->loopTableAgeBits),
54 loopTableConfidenceBits(params->loopTableConfidenceBits),
55 loopTableTagBits(params->loopTableTagBits),
56 loopTableIterBits(params->loopTableIterBits),
57 logLoopTableAssoc(params->logLoopTableAssoc),
58 confidenceThreshold((1 << loopTableConfidenceBits) - 1),
59 loopTagMask((1 << loopTableTagBits) - 1),
60 loopNumIterMask((1 << loopTableIterBits) - 1),
61 loopUseCounter(0),
62 withLoopBits(params->withLoopBits)
63{
64 // we use uint16_t type for these vales, so they cannot be more than
65 // 16 bits
66 assert(loopTableTagBits <= 16);
67 assert(loopTableIterBits <= 16);
68
69 assert(logSizeLoopPred >= logLoopTableAssoc);
70
71 ltable = new LoopEntry[ULL(1) << logSizeLoopPred];
72}
73
74int
75LTAGE::lindex(Addr pc_in) const
76{
77 // The loop table is implemented as a linear table
78 // If associativity is N (N being 1 << logLoopTableAssoc),
79 // the first N entries are for set 0, the next N entries are for set 1,
80 // and so on.
81 // Thus, this function calculates the set and then it gets left shifted
82 // by logLoopTableAssoc in order to return the index of the first of the
83 // N entries of the set
84 Addr mask = (ULL(1) << (logSizeLoopPred - logLoopTableAssoc)) - 1;
85 return (((pc_in >> instShiftAmt) & mask) << logLoopTableAssoc);
86}
87
88//loop prediction: only used if high confidence
89bool
90LTAGE::getLoop(Addr pc, LTageBranchInfo* bi) const
91{
92 bi->loopHit = -1;
93 bi->loopPredValid = false;
94 bi->loopIndex = lindex(pc);
95 unsigned pcShift = instShiftAmt + logSizeLoopPred - logLoopTableAssoc;
96 bi->loopTag = ((pc) >> pcShift) & loopTagMask;
97
98 for (int i = 0; i < (1 << logLoopTableAssoc); i++) {

--- 9 unchanged lines hidden (view full) ---

108 return (ltable[bi->loopIndex + i].dir);
109 }
110 }
111 }
112 return false;
113}
114
115void
116LTAGE::specLoopUpdate(Addr pc, bool taken, LTageBranchInfo* bi)
117{
118 if (bi->loopHit>=0) {
119 int index = lindex(pc);
120 if (taken != ltable[index].dir) {
121 ltable[index].currentIterSpec = 0;
122 } else {
123 ltable[index].currentIterSpec =
124 (ltable[index].currentIterSpec + 1) & loopNumIterMask;
125 }
126 }
127}
128
129void
130LTAGE::loopUpdate(Addr pc, bool taken, LTageBranchInfo* bi)
131{
132 int idx = bi->loopIndex + bi->loopHit;
133 if (bi->loopHit >= 0) {
134 //already a hit
135 if (bi->loopPredValid) {
136 if (taken != bi->loopPred) {
137 // free the entry
138 ltable[idx].numIter = 0;

--- 70 unchanged lines hidden (view full) ---

209 }
210 else
211 ltable[idx].age--;
212 }
213 }
214
215}
216
217//prediction
218bool
219LTAGE::predict(ThreadID tid, Addr branch_pc, bool cond_branch, void* &b)
220{
221 LTageBranchInfo *bi = new LTageBranchInfo(nHistoryTables+1);
222 b = (void*)(bi);
223
224 bool pred_taken = tagePredict(tid, branch_pc, cond_branch, bi);
225
226 if (cond_branch) {
227 bi->loopPred = getLoop(branch_pc, bi); // loop prediction
228
229 if ((loopUseCounter >= 0) && bi->loopPredValid) {
230 pred_taken = bi->loopPred;
231 }
232 DPRINTF(LTage, "Predict for %lx: taken?:%d, loopTaken?:%d, "
233 "loopValid?:%d, loopUseCounter:%d, tagePred:%d, altPred:%d\n",
234 branch_pc, pred_taken, bi->loopPred, bi->loopPredValid,
235 loopUseCounter, bi->tagePred, bi->altTaken);
236 }
237
238 specLoopUpdate(branch_pc, pred_taken, bi);
239 return pred_taken;
240}
241
242void
243LTAGE::condBranchUpdate(Addr branch_pc, bool taken,
244 TageBranchInfo* tage_bi, int nrand)
245{
246 LTageBranchInfo* bi = static_cast<LTageBranchInfo*>(tage_bi);
247
248 // first update the loop predictor
249 loopUpdate(branch_pc, taken, bi);
250
251 if (bi->loopPredValid) {
252 if (bi->tagePred != bi->loopPred) {
253 ctrUpdate(loopUseCounter,
254 (bi->loopPred == taken),
255 withLoopBits);
256 }
257 }
258
259 TAGE::condBranchUpdate(branch_pc, taken, bi, nrand);
260}
261
262void
263LTAGE::squash(ThreadID tid, bool taken, void *bp_history)
264{
265 TAGE::squash(tid, taken, bp_history);
266
267 LTageBranchInfo* bi = (LTageBranchInfo*)(bp_history);
268
269 if (bi->condBranch) {
270 if (bi->loopHit >= 0) {
271 int idx = bi->loopIndex + bi->loopHit;
272 ltable[idx].currentIterSpec = bi->currentIter;
273 }
274 }
275}
276
277void
278LTAGE::squash(ThreadID tid, void *bp_history)
279{
280 LTageBranchInfo* bi = (LTageBranchInfo*)(bp_history);
281 if (bi->condBranch) {
282 if (bi->loopHit >= 0) {
283 int idx = bi->loopIndex + bi->loopHit;
284 ltable[idx].currentIterSpec = bi->currentIter;
285 }
286 }
287
288 TAGE::squash(tid, bp_history);
289}
290
291LTAGE*
292LTAGEParams::create()
293{
294 return new LTAGE(this);
295}