bpred_unit.cc (11432:4209ec56e923) bpred_unit.cc (11433:72b075cdc336)
1/*
2 * Copyright (c) 2011-2012, 2014 ARM Limited
3 * Copyright (c) 2010 The University of Edinburgh
4 * Copyright (c) 2012 Mark D. Hill and David A. Wood
5 * All rights reserved
6 *
7 * The license below extends only to copyright in the software and shall
8 * not be construed as granting a license to any other intellectual

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

57 : SimObject(params),
58 numThreads(params->numThreads),
59 predHist(numThreads),
60 BTB(params->BTBEntries,
61 params->BTBTagSize,
62 params->instShiftAmt,
63 params->numThreads),
64 RAS(numThreads),
1/*
2 * Copyright (c) 2011-2012, 2014 ARM Limited
3 * Copyright (c) 2010 The University of Edinburgh
4 * Copyright (c) 2012 Mark D. Hill and David A. Wood
5 * All rights reserved
6 *
7 * The license below extends only to copyright in the software and shall
8 * not be construed as granting a license to any other intellectual

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

57 : SimObject(params),
58 numThreads(params->numThreads),
59 predHist(numThreads),
60 BTB(params->BTBEntries,
61 params->BTBTagSize,
62 params->instShiftAmt,
63 params->numThreads),
64 RAS(numThreads),
65 useIndirect(params->useIndirect),
66 iPred(params->indirectHashGHR,
67 params->indirectHashTargets,
68 params->indirectSets,
69 params->indirectWays,
70 params->indirectTagSize,
71 params->indirectPathLength,
72 params->instShiftAmt,
73 params->numThreads),
65 instShiftAmt(params->instShiftAmt)
66{
67 for (auto& r : RAS)
68 r.init(params->RASSize);
69}
70
71void
72BPredUnit::regStats()

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

112 .name(name() + ".usedRAS")
113 .desc("Number of times the RAS was used to get a target.")
114 ;
115
116 RASIncorrect
117 .name(name() + ".RASInCorrect")
118 .desc("Number of incorrect RAS predictions.")
119 ;
74 instShiftAmt(params->instShiftAmt)
75{
76 for (auto& r : RAS)
77 r.init(params->RASSize);
78}
79
80void
81BPredUnit::regStats()

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

121 .name(name() + ".usedRAS")
122 .desc("Number of times the RAS was used to get a target.")
123 ;
124
125 RASIncorrect
126 .name(name() + ".RASInCorrect")
127 .desc("Number of incorrect RAS predictions.")
128 ;
129
130 indirectLookups
131 .name(name() + ".indirectLookups")
132 .desc("Number of indirect predictor lookups.")
133 ;
134
135 indirectHits
136 .name(name() + ".indirectHits")
137 .desc("Number of indirect target hits.")
138 ;
139
140 indirectMisses
141 .name(name() + ".indirectMisses")
142 .desc("Number of indirect misses.")
143 ;
144
145 indirectMispredicted
146 .name(name() + "indirectMispredicted")
147 .desc("Number of mispredicted indirect branches.")
148 ;
149
120}
121
122ProbePoints::PMUUPtr
123BPredUnit::pmuProbePoint(const char *name)
124{
125 ProbePoints::PMUUPtr ptr;
126 ptr.reset(new ProbePoints::PMU(getProbeManager(), name));
127

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

211 // be popped off if the speculation is incorrect.
212 predict_record.wasCall = true;
213
214 DPRINTF(Branch, "[tid:%i]: Instruction %s was a "
215 "call, adding %s to the RAS index: %i.\n",
216 tid, pc, pc, RAS[tid].topIdx());
217 }
218
150}
151
152ProbePoints::PMUUPtr
153BPredUnit::pmuProbePoint(const char *name)
154{
155 ProbePoints::PMUUPtr ptr;
156 ptr.reset(new ProbePoints::PMU(getProbeManager(), name));
157

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

241 // be popped off if the speculation is incorrect.
242 predict_record.wasCall = true;
243
244 DPRINTF(Branch, "[tid:%i]: Instruction %s was a "
245 "call, adding %s to the RAS index: %i.\n",
246 tid, pc, pc, RAS[tid].topIdx());
247 }
248
219 if (BTB.valid(pc.instAddr(), tid)) {
220 ++BTBHits;
249 if (inst->isDirectCtrl() || !useIndirect) {
250 // Check BTB on direct branches
251 if (BTB.valid(pc.instAddr(), tid)) {
252 ++BTBHits;
221
253
222 // If it's not a return, use the BTB to get the target addr.
223 target = BTB.lookup(pc.instAddr(), tid);
254 // If it's not a return, use the BTB to get target addr.
255 target = BTB.lookup(pc.instAddr(), tid);
224
256
225 DPRINTF(Branch, "[tid:%i]: Instruction %s predicted"
226 " target is %s.\n", tid, pc, target);
257 DPRINTF(Branch, "[tid:%i]: Instruction %s predicted"
258 " target is %s.\n", tid, pc, target);
227
259
260 } else {
261 DPRINTF(Branch, "[tid:%i]: BTB doesn't have a "
262 "valid entry.\n",tid);
263 pred_taken = false;
264 // The Direction of the branch predictor is altered
265 // because the BTB did not have an entry
266 // The predictor needs to be updated accordingly
267 if (!inst->isCall() && !inst->isReturn()) {
268 btbUpdate(pc.instAddr(), bp_history);
269 DPRINTF(Branch, "[tid:%i]:[sn:%i] btbUpdate"
270 " called for %s\n", tid, seqNum, pc);
271 } else if (inst->isCall() && !inst->isUncondCtrl()) {
272 RAS[tid].pop();
273 predict_record.pushedRAS = false;
274 }
275 TheISA::advancePC(target, inst);
276 }
228 } else {
277 } else {
229 DPRINTF(Branch, "[tid:%i]: BTB doesn't have a "
230 "valid entry.\n",tid);
231 pred_taken = false;
232 // The Direction of the branch predictor is altered because the
233 // BTB did not have an entry
234 // The predictor needs to be updated accordingly
235 if (!inst->isCall() && !inst->isReturn()) {
236 btbUpdate(pc.instAddr(), bp_history);
237 DPRINTF(Branch, "[tid:%i]:[sn:%i] btbUpdate"
238 " called for %s\n", tid, seqNum, pc);
239 } else if (inst->isCall() && !inst->isUncondCtrl()) {
240 RAS[tid].pop();
241 predict_record.pushedRAS = false;
278 predict_record.wasIndirect = true;
279 ++indirectLookups;
280 //Consult indirect predictor on indirect control
281 if (iPred.lookup(pc.instAddr(), getGHR(bp_history), target,
282 tid)) {
283 // Indirect predictor hit
284 ++indirectHits;
285 DPRINTF(Branch, "[tid:%i]: Instruction %s predicted "
286 "indirect target is %s.\n", tid, pc, target);
287 } else {
288 ++indirectMisses;
289 pred_taken = false;
290 DPRINTF(Branch, "[tid:%i]: Instruction %s no indirect "
291 "target.\n", tid, pc);
292 if (!inst->isCall() && !inst->isReturn()) {
293
294 } else if (inst->isCall() && !inst->isUncondCtrl()) {
295 RAS[tid].pop();
296 predict_record.pushedRAS = false;
297 }
298 TheISA::advancePC(target, inst);
242 }
299 }
243 TheISA::advancePC(target, inst);
300 iPred.recordIndirect(pc.instAddr(), target.instAddr(), seqNum,
301 tid);
244 }
245 }
246 } else {
247 if (inst->isReturn()) {
248 predict_record.wasReturn = true;
249 }
250 TheISA::advancePC(target, inst);
251 }

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

383}
384
385void
386BPredUnit::update(const InstSeqNum &done_sn, ThreadID tid)
387{
388 DPRINTF(Branch, "[tid:%i]: Committing branches until "
389 "[sn:%lli].\n", tid, done_sn);
390
302 }
303 }
304 } else {
305 if (inst->isReturn()) {
306 predict_record.wasReturn = true;
307 }
308 TheISA::advancePC(target, inst);
309 }

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

441}
442
443void
444BPredUnit::update(const InstSeqNum &done_sn, ThreadID tid)
445{
446 DPRINTF(Branch, "[tid:%i]: Committing branches until "
447 "[sn:%lli].\n", tid, done_sn);
448
449 iPred.commit(done_sn, tid);
391 while (!predHist[tid].empty() &&
392 predHist[tid].back().seqNum <= done_sn) {
393 // Update the branch predictor with the correct results.
394 if (!predHist[tid].back().wasSquashed) {
395 update(predHist[tid].back().pc, predHist[tid].back().predTaken,
396 predHist[tid].back().bpHistory, false);
397 } else {
398 retireSquashed(predHist[tid].back().bpHistory);
399 }
400
401 predHist[tid].pop_back();
402 }
403}
404
405void
406BPredUnit::squash(const InstSeqNum &squashed_sn, ThreadID tid)
407{
408 History &pred_hist = predHist[tid];
409
450 while (!predHist[tid].empty() &&
451 predHist[tid].back().seqNum <= done_sn) {
452 // Update the branch predictor with the correct results.
453 if (!predHist[tid].back().wasSquashed) {
454 update(predHist[tid].back().pc, predHist[tid].back().predTaken,
455 predHist[tid].back().bpHistory, false);
456 } else {
457 retireSquashed(predHist[tid].back().bpHistory);
458 }
459
460 predHist[tid].pop_back();
461 }
462}
463
464void
465BPredUnit::squash(const InstSeqNum &squashed_sn, ThreadID tid)
466{
467 History &pred_hist = predHist[tid];
468
469 iPred.squash(squashed_sn, tid);
410 while (!pred_hist.empty() &&
411 pred_hist.front().seqNum > squashed_sn) {
412 if (pred_hist.front().usedRAS) {
413 DPRINTF(Branch, "[tid:%i]: Restoring top of RAS to: %i,"
414 " target: %s.\n", tid,
415 pred_hist.front().RASIndex, pred_hist.front().RASTarget);
416
417 RAS[tid].restore(pred_hist.front().RASIndex,

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

480 pred_hist.front().seqNum, squashed_sn);
481
482 assert(pred_hist.front().seqNum == squashed_sn);
483 }
484
485
486 if ((*hist_it).usedRAS) {
487 ++RASIncorrect;
470 while (!pred_hist.empty() &&
471 pred_hist.front().seqNum > squashed_sn) {
472 if (pred_hist.front().usedRAS) {
473 DPRINTF(Branch, "[tid:%i]: Restoring top of RAS to: %i,"
474 " target: %s.\n", tid,
475 pred_hist.front().RASIndex, pred_hist.front().RASTarget);
476
477 RAS[tid].restore(pred_hist.front().RASIndex,

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

540 pred_hist.front().seqNum, squashed_sn);
541
542 assert(pred_hist.front().seqNum == squashed_sn);
543 }
544
545
546 if ((*hist_it).usedRAS) {
547 ++RASIncorrect;
548 DPRINTF(Branch, "[tid:%i]: Incorrect RAS [sn:%i]\n",
549 tid, hist_it->seqNum);
488 }
489
550 }
551
552 // Have to get GHR here because the update deletes bpHistory
553 unsigned ghr = getGHR(hist_it->bpHistory);
554
490 update((*hist_it).pc, actually_taken,
491 pred_hist.front().bpHistory, true);
492 hist_it->wasSquashed = true;
493
494 if (actually_taken) {
495 if (hist_it->wasReturn && !hist_it->usedRAS) {
496 DPRINTF(Branch, "[tid: %i] Incorrectly predicted"
497 " return [sn:%i] PC: %s\n", tid, hist_it->seqNum,
498 hist_it->pc);
499 RAS[tid].pop();
500 hist_it->usedRAS = true;
501 }
555 update((*hist_it).pc, actually_taken,
556 pred_hist.front().bpHistory, true);
557 hist_it->wasSquashed = true;
558
559 if (actually_taken) {
560 if (hist_it->wasReturn && !hist_it->usedRAS) {
561 DPRINTF(Branch, "[tid: %i] Incorrectly predicted"
562 " return [sn:%i] PC: %s\n", tid, hist_it->seqNum,
563 hist_it->pc);
564 RAS[tid].pop();
565 hist_it->usedRAS = true;
566 }
567 if (hist_it->wasIndirect) {
568 ++indirectMispredicted;
569 iPred.recordTarget(hist_it->seqNum, ghr, corrTarget, tid);
570 } else {
571 DPRINTF(Branch,"[tid: %i] BTB Update called for [sn:%i]"
572 " PC: %s\n", tid,hist_it->seqNum, hist_it->pc);
502
573
503 DPRINTF(Branch,"[tid: %i] BTB Update called for [sn:%i]"
504 " PC: %s\n", tid,hist_it->seqNum, hist_it->pc);
505
506 BTB.update((*hist_it).pc, corrTarget, tid);
507
574 BTB.update((*hist_it).pc, corrTarget, tid);
575 }
508 } else {
509 //Actually not Taken
510 if (hist_it->usedRAS) {
511 DPRINTF(Branch,"[tid: %i] Incorrectly predicted"
512 " return [sn:%i] PC: %s Restoring RAS\n", tid,
513 hist_it->seqNum, hist_it->pc);
514 DPRINTF(Branch, "[tid:%i]: Restoring top of RAS"
515 " to: %i, target: %s.\n", tid,

--- 42 unchanged lines hidden ---
576 } else {
577 //Actually not Taken
578 if (hist_it->usedRAS) {
579 DPRINTF(Branch,"[tid: %i] Incorrectly predicted"
580 " return [sn:%i] PC: %s Restoring RAS\n", tid,
581 hist_it->seqNum, hist_it->pc);
582 DPRINTF(Branch, "[tid:%i]: Restoring top of RAS"
583 " to: %i, target: %s.\n", tid,

--- 42 unchanged lines hidden ---