49 #include "arch/isa_traits.hh"
50 #include "arch/types.hh"
51 #include "arch/utility.hh"
53 #include "config/the_isa.hh"
54 #include "debug/Branch.hh"
58 numThreads(params->numThreads),
60 BTB(params->BTBEntries,
65 useIndirect(params->useIndirect),
66 iPred(params->indirectHashGHR,
67 params->indirectHashTargets,
70 params->indirectTagSize,
71 params->indirectPathLength,
74 instShiftAmt(params->instShiftAmt)
77 r.init(params->RASSize);
87 .
desc(
"Number of BP lookups")
92 .
desc(
"Number of conditional branches predicted")
97 .
desc(
"Number of conditional branches incorrect")
102 .
desc(
"Number of BTB lookups")
107 .
desc(
"Number of BTB hits")
112 .
desc(
"Number of correct BTB predictions (this stat may not "
118 .
desc(
"BTB Hit Percentage")
124 .
desc(
"Number of times the RAS was used to get a target.")
129 .
desc(
"Number of incorrect RAS predictions.")
134 .
desc(
"Number of indirect predictor lookups.")
139 .
desc(
"Number of indirect target hits.")
144 .
desc(
"Number of indirect misses.")
148 .
name(
name() +
"indirectMispredicted")
149 .
desc(
"Number of mispredicted indirect branches.")
188 bool pred_taken =
false;
194 void *bp_history = NULL;
197 DPRINTF(Branch,
"[tid:%i]: Unconditional control.\n", tid);
203 pred_taken =
lookup(tid, pc.instAddr(), bp_history);
205 DPRINTF(Branch,
"[tid:%i]: [sn:%i] Branch predictor"
206 " predicted %i for PC %s\n", tid, seqNum, pred_taken, pc);
209 DPRINTF(Branch,
"[tid:%i]: [sn:%i] Creating prediction history "
210 "for PC %s\n", tid, seqNum, pc);
213 pred_taken, bp_history, tid);
219 predict_record.wasReturn =
true;
226 predict_record.usedRAS =
true;
227 predict_record.RASIndex =
RAS[tid].topIdx();
228 predict_record.RASTarget = rasTop;
232 DPRINTF(Branch,
"[tid:%i]: Instruction %s is a return, "
233 "RAS predicted target: %s, RAS index: %i.\n",
234 tid, pc, target, predict_record.RASIndex);
240 predict_record.pushedRAS =
true;
244 predict_record.wasCall =
true;
246 DPRINTF(Branch,
"[tid:%i]: Instruction %s was a "
247 "call, adding %s to the RAS index: %i.\n",
248 tid, pc, pc,
RAS[tid].topIdx());
253 if (
BTB.
valid(pc.instAddr(), tid)) {
259 DPRINTF(Branch,
"[tid:%i]: Instruction %s predicted"
260 " target is %s.\n", tid, pc, target);
263 DPRINTF(Branch,
"[tid:%i]: BTB doesn't have a "
264 "valid entry.\n",tid);
270 btbUpdate(tid, pc.instAddr(), bp_history);
271 DPRINTF(Branch,
"[tid:%i]:[sn:%i] btbUpdate"
272 " called for %s\n", tid, seqNum, pc);
275 predict_record.pushedRAS =
false;
280 predict_record.wasIndirect =
true;
287 DPRINTF(Branch,
"[tid:%i]: Instruction %s predicted "
288 "indirect target is %s.\n", tid, pc, target);
292 DPRINTF(Branch,
"[tid:%i]: Instruction %s no indirect "
293 "target.\n", tid, pc);
298 predict_record.pushedRAS =
false;
308 predict_record.wasReturn =
true;
315 predHist[tid].push_front(predict_record);
317 DPRINTF(Branch,
"[tid:%i]: [sn:%i]: History entry added."
318 "predHist.size(): %i\n", tid, seqNum,
predHist[tid].
size());
326 DPRINTF(Branch,
"[tid:%i]: Committing branches until "
327 "[sn:%lli].\n", tid, done_sn);
331 predHist[tid].back().seqNum <= done_sn) {
335 predHist[tid].back().bpHistory,
false);
347 while (!pred_hist.empty() &&
348 pred_hist.front().seqNum > squashed_sn) {
349 if (pred_hist.front().usedRAS) {
350 DPRINTF(Branch,
"[tid:%i]: Restoring top of RAS to: %i,"
351 " target: %s.\n", tid,
352 pred_hist.front().RASIndex, pred_hist.front().RASTarget);
354 RAS[tid].restore(pred_hist.front().RASIndex,
355 pred_hist.front().RASTarget);
356 }
else if (pred_hist.front().wasCall && pred_hist.front().pushedRAS) {
358 DPRINTF(Branch,
"[tid: %i] Squashing"
359 " Call [sn:%i] PC: %s Popping RAS\n", tid,
360 pred_hist.front().seqNum, pred_hist.front().pc);
365 squash(tid, pred_hist.front().bpHistory);
367 DPRINTF(Branch,
"[tid:%i]: Removing history for [sn:%i] "
368 "PC %s.\n", tid, pred_hist.front().seqNum,
369 pred_hist.front().pc);
371 pred_hist.pop_front();
373 DPRINTF(Branch,
"[tid:%i]: predHist.size(): %i\n",
399 DPRINTF(Branch,
"[tid:%i]: Squashing from sequence number %i, "
400 "setting target to %s.\n", tid, squashed_sn, corrTarget);
408 if (!pred_hist.empty()) {
410 auto hist_it = pred_hist.begin();
415 if (pred_hist.front().seqNum != squashed_sn) {
416 DPRINTF(Branch,
"Front sn %i != Squash sn %i\n",
417 pred_hist.front().seqNum, squashed_sn);
419 assert(pred_hist.front().seqNum == squashed_sn);
423 if ((*hist_it).usedRAS) {
425 DPRINTF(Branch,
"[tid:%i]: Incorrect RAS [sn:%i]\n",
426 tid, hist_it->seqNum);
430 unsigned ghr =
getGHR(tid, hist_it->bpHistory);
442 pred_hist.front().predTaken = actually_taken;
444 update(tid, (*hist_it).pc, actually_taken,
445 pred_hist.front().bpHistory,
true);
447 if (actually_taken) {
448 if (hist_it->wasReturn && !hist_it->usedRAS) {
449 DPRINTF(Branch,
"[tid: %i] Incorrectly predicted"
450 " return [sn:%i] PC: %s\n", tid, hist_it->seqNum,
453 hist_it->usedRAS =
true;
455 if (hist_it->wasIndirect) {
459 DPRINTF(Branch,
"[tid: %i] BTB Update called for [sn:%i]"
460 " PC: %s\n", tid,hist_it->seqNum, hist_it->pc);
462 BTB.
update((*hist_it).pc, corrTarget, tid);
466 if (hist_it->usedRAS) {
467 DPRINTF(Branch,
"[tid: %i] Incorrectly predicted"
468 " return [sn:%i] PC: %s Restoring RAS\n", tid,
469 hist_it->seqNum, hist_it->pc);
470 DPRINTF(Branch,
"[tid:%i]: Restoring top of RAS"
471 " to: %i, target: %s.\n", tid,
472 hist_it->RASIndex, hist_it->RASTarget);
473 RAS[tid].restore(hist_it->RASIndex, hist_it->RASTarget);
474 hist_it->usedRAS =
false;
475 }
else if (hist_it->wasCall && hist_it->pushedRAS) {
477 DPRINTF(Branch,
"[tid: %i] Incorrectly predicted"
478 " Call [sn:%i] PC: %s Popping RAS\n", tid,
479 hist_it->seqNum, hist_it->pc);
481 hist_it->pushedRAS =
false;
485 DPRINTF(Branch,
"[tid:%i]: [sn:%i] pred_hist empty, can't "
486 "update.\n", tid, squashed_sn);
496 auto pred_hist_it = ph.begin();
498 cprintf(
"predHist[%i].size(): %i\n", i++, ph.size());
500 while (pred_hist_it != ph.end()) {
501 cprintf(
"[sn:%lli], PC:%#x, tid:%i, predTaken:%i, "
503 pred_hist_it->seqNum, pred_hist_it->pc,
504 pred_hist_it->tid, pred_hist_it->predTaken,
505 pred_hist_it->bpHistory);
IndirectPredictor iPred
The indirect target predictor.
Stats::Scalar indirectHits
Stat for the number of indirect target hits.
const std::string & name()
Stats::Scalar BTBHits
Stat for number of BTB hits.
Stats::Scalar usedRAS
Stat for number of times the RAS is used to get a target.
BranchPredictorParams Params
std::vector< History > predHist
The per-thread predictor history.
void update(const InstSeqNum &done_sn, ThreadID tid)
Tells the branch predictor to commit any updates until the given sequence number. ...
bool isUncondCtrl() const
virtual void regStats()
Register statistics for this object.
Stats::Scalar condIncorrect
Stat for number of conditional branches predicted incorrectly.
Stats::Scalar BTBCorrect
Stat for number of times the BTB is correct.
const bool useIndirect
Option to disable indirect predictor.
void regProbePoints() override
Register probe points for this object.
void drainSanityCheck() const
Perform sanity checks after a drain.
void commit(InstSeqNum seq_num, ThreadID tid)
Stats::Formula BTBHitPct
Stat for percent times an entry in BTB found.
Stats::Scalar indirectMisses
Stat for the number of indirect target misses.
std::unique_ptr< PMU > PMUUPtr
virtual void uncondBranch(ThreadID tid, Addr pc, void *&bp_history)=0
Stats::Scalar condPredicted
Stat for number of conditional branches predicted.
virtual void btbUpdate(ThreadID tid, Addr instPC, void *&bp_history)=0
If a branch is not taken, because the BTB address is invalid or missing, this function sets the appro...
Stats::Scalar BTBLookups
Stat for number of BTB lookups.
bool predict(const StaticInstPtr &inst, const InstSeqNum &seqNum, TheISA::PCState &pc, ThreadID tid)
Predicts whether or not the instruction is a taken branch, and the target of the branch if it is take...
ProbePoints::PMUUPtr pmuProbePoint(const char *name)
Helper method to instantiate probe points belonging to this object.
void update(Addr instPC, const TheISA::PCState &targetPC, ThreadID tid)
Updates the BTB with the target of a branch.
TheISA::PCState lookup(Addr instPC, ThreadID tid)
Looks up an address in the BTB.
Derived & precision(int _precision)
Set the precision and marks this stat to print at the end of simulation.
ProbePoints::PMUUPtr ppMisses
Miss-predicted branches.
void advancePC(PCState &pc, const StaticInstPtr &inst)
void regStats() override
Registers statistics.
PCState buildRetPC(const PCState &curPC, const PCState &callPC)
virtual bool lookup(ThreadID tid, Addr instPC, void *&bp_history)=0
Looks up a given PC in the BP to see if it is taken or not taken.
std::vector< ReturnAddrStack > RAS
The per-thread return address stack.
Stats::Scalar RASIncorrect
Stat for number of times the RAS is incorrect.
static const int NumArgumentRegs M5_VAR_USED
bool isDirectCtrl() const
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
int16_t ThreadID
Thread index/ID type.
ProbePointArg generates a point for the class of Arg.
virtual const std::string name() const
void recordIndirect(Addr br_addr, Addr tgt_addr, InstSeqNum seq_num, ThreadID tid)
bool valid(Addr instPC, ThreadID tid)
Checks if a branch is in the BTB.
GenericISA::SimplePCState< MachInst > PCState
ProbeManager * getProbeManager()
Get the probe manager for this object.
void recordTarget(InstSeqNum seq_num, unsigned ghr, const TheISA::PCState &target, ThreadID tid)
Stats::Scalar indirectMispredicted
Stat for the number of indirect target mispredictions.
BPredUnit(const Params *p)
bool lookup(Addr br_addr, unsigned ghr, TheISA::PCState &br_target, ThreadID tid)
void squash(const InstSeqNum &squashed_sn, ThreadID tid)
Squashes all outstanding updates until a given sequence number.
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
void squash(InstSeqNum seq_num, ThreadID tid)
Stats::Scalar indirectLookups
Stat for the number of indirect target lookups.
virtual unsigned getGHR(ThreadID tid, void *bp_history) const
ProbePoints::PMUUPtr ppBranches
Branches seen by the branch predictor.
Abstract superclass for simulation objects.
Stats::Scalar lookups
Stat for number of BP lookups.
void cprintf(const char *format, const Args &...args)