47 #include "arch/pcstate.hh"
50 #include "config/the_isa.hh"
51 #include "debug/Branch.hh"
56 namespace branch_prediction
61 numThreads(params.numThreads),
63 BTB(params.BTBEntries,
68 iPred(params.indirectBranchPred),
70 instShiftAmt(params.instShiftAmt)
77 : statistics::
Group(parent),
78 ADD_STAT(lookups, statistics::units::Count::get(),
"Number of BP lookups"),
79 ADD_STAT(condPredicted, statistics::units::Count::get(),
80 "Number of conditional branches predicted"),
81 ADD_STAT(condIncorrect, statistics::units::Count::get(),
82 "Number of conditional branches incorrect"),
83 ADD_STAT(BTBLookups, statistics::units::Count::get(),
84 "Number of BTB lookups"),
85 ADD_STAT(BTBHits, statistics::units::Count::get(),
"Number of BTB hits"),
86 ADD_STAT(BTBHitRatio, statistics::units::Ratio::get(),
"BTB Hit Ratio",
87 BTBHits / BTBLookups),
88 ADD_STAT(RASUsed, statistics::units::Count::get(),
89 "Number of times the RAS was used to get a target."),
90 ADD_STAT(RASIncorrect, statistics::units::Count::get(),
91 "Number of incorrect RAS predictions."),
92 ADD_STAT(indirectLookups, statistics::units::Count::get(),
93 "Number of indirect predictor lookups."),
94 ADD_STAT(indirectHits, statistics::units::Count::get(),
95 "Number of indirect target hits."),
96 ADD_STAT(indirectMisses, statistics::units::Count::get(),
97 "Number of indirect misses."),
98 ADD_STAT(indirectMispredicted, statistics::units::Count::get(),
99 "Number of mispredicted indirect branches.")
125 for (GEM5_VAR_USED
const auto& ph :
predHist)
138 bool pred_taken =
false;
144 void *bp_history = NULL;
145 void *indirect_history = NULL;
149 "Unconditional control\n",
156 pred_taken =
lookup(tid,
pc.instAddr(), bp_history);
159 "Branch predictor predicted %i for PC %s\n",
160 tid, seqNum, pred_taken,
pc);
163 const bool orig_pred_taken = pred_taken;
169 "Creating prediction history "
170 "for PC %s\n", tid, seqNum,
pc);
173 bp_history, indirect_history, tid, inst);
192 DPRINTF(
Branch,
"[tid:%i] [sn:%llu] Instruction %s is a return, "
193 "RAS predicted target: %s, RAS index: %i\n",
194 tid, seqNum,
pc, target, predict_record.
RASIndex);
206 "[tid:%i] [sn:%llu] Instruction %s was a call, adding "
207 "%s to the RAS index: %i\n",
208 tid, seqNum,
pc,
pc,
RAS[tid].topIdx());
219 "[tid:%i] [sn:%llu] Instruction %s predicted "
221 tid, seqNum,
pc, target);
224 "valid entry\n",tid,seqNum);
233 "[tid:%i] [sn:%llu] btbUpdate "
250 "[tid:%i] [sn:%llu] "
251 "Instruction %s predicted "
252 "indirect target is %s\n",
253 tid, seqNum,
pc, target);
259 "[tid:%i] [sn:%llu] "
260 "Instruction %s no indirect "
281 predict_record.
target = target.instAddr();
294 predHist[tid].push_front(predict_record);
297 "[tid:%i] [sn:%llu] History entry added. "
298 "predHist.size(): %i\n",
308 "sn:%llu]\n", tid, done_sn);
311 predHist[tid].back().seqNum <= done_sn) {
315 predHist[tid].back().bpHistory,
false,
336 while (!pred_hist.empty() &&
337 pred_hist.front().seqNum > squashed_sn) {
338 if (pred_hist.front().usedRAS) {
340 " Restoring top of RAS to: %i,"
341 " target: %s\n", tid, squashed_sn,
342 pred_hist.front().RASIndex, pred_hist.front().RASTarget);
344 RAS[tid].restore(pred_hist.front().RASIndex,
345 pred_hist.front().RASTarget);
346 }
else if (pred_hist.front().wasCall && pred_hist.front().pushedRAS) {
349 " Call [sn:%llu] PC: %s Popping RAS\n", tid, squashed_sn,
350 pred_hist.front().seqNum, pred_hist.front().pc);
355 squash(tid, pred_hist.front().bpHistory);
361 "Removing history for [sn:%llu] "
362 "PC %#x\n", tid, squashed_sn, pred_hist.front().seqNum,
363 pred_hist.front().pc);
365 pred_hist.pop_front();
367 DPRINTF(
Branch,
"[tid:%i] [squash sn:%llu] predHist.size(): %i\n",
368 tid, squashed_sn,
predHist[tid].size());
393 DPRINTF(
Branch,
"[tid:%i] Squashing from sequence number %i, "
394 "setting target to %s\n", tid, squashed_sn, corrTarget);
402 if (!pred_hist.empty()) {
404 auto hist_it = pred_hist.begin();
409 if (pred_hist.front().seqNum != squashed_sn) {
411 pred_hist.front().seqNum, squashed_sn);
413 assert(pred_hist.front().seqNum == squashed_sn);
417 if ((*hist_it).usedRAS) {
420 "[tid:%i] [squash sn:%llu] Incorrect RAS [sn:%llu]\n",
421 tid, squashed_sn, hist_it->seqNum);
434 pred_hist.front().predTaken = actually_taken;
435 pred_hist.front().target = corrTarget.instAddr();
437 update(tid, (*hist_it).pc, actually_taken,
438 pred_hist.front().bpHistory,
true, pred_hist.front().inst,
439 corrTarget.instAddr());
443 pred_hist.front().indirectHistory, actually_taken);
446 if (actually_taken) {
447 if (hist_it->wasReturn && !hist_it->usedRAS) {
449 "Incorrectly predicted "
450 "return [sn:%llu] PC: %#x\n", tid, squashed_sn,
454 hist_it->usedRAS =
true;
456 if (hist_it->wasIndirect) {
460 hist_it->seqNum, pred_hist.front().indirectHistory,
465 "BTB Update called for [sn:%llu] "
466 "PC %#x\n", tid, squashed_sn,
467 hist_it->seqNum, hist_it->pc);
469 BTB.
update((*hist_it).pc, corrTarget, tid);
473 if (hist_it->usedRAS) {
475 "[tid:%i] [squash sn:%llu] Incorrectly predicted "
476 "return [sn:%llu] PC: %#x Restoring RAS\n", tid,
478 hist_it->seqNum, hist_it->pc);
480 "[tid:%i] [squash sn:%llu] Restoring top of RAS "
481 "to: %i, target: %s\n", tid, squashed_sn,
482 hist_it->RASIndex, hist_it->RASTarget);
483 RAS[tid].restore(hist_it->RASIndex, hist_it->RASTarget);
484 hist_it->usedRAS =
false;
485 }
else if (hist_it->wasCall && hist_it->pushedRAS) {
488 "[tid:%i] [squash sn:%llu] "
489 "Incorrectly predicted "
490 "Call [sn:%llu] PC: %s Popping RAS\n",
492 hist_it->seqNum, hist_it->pc);
494 hist_it->pushedRAS =
false;
499 "update\n", tid, squashed_sn);
509 auto pred_hist_it = ph.begin();
511 cprintf(
"predHist[%i].size(): %i\n",
i++, ph.size());
513 while (pred_hist_it != ph.end()) {
514 cprintf(
"sn:%llu], PC:%#x, tid:%i, predTaken:%i, "
516 pred_hist_it->seqNum, pred_hist_it->pc,
517 pred_hist_it->tid, pred_hist_it->predTaken,
518 pred_hist_it->bpHistory);