Go to the documentation of this file.
47 #include "arch/types.hh"
48 #include "arch/utility.hh"
50 #include "config/the_isa.hh"
51 #include "debug/Branch.hh"
55 numThreads(params->numThreads),
57 BTB(params->BTBEntries,
62 iPred(params->indirectBranchPred),
64 instShiftAmt(params->instShiftAmt)
71 :
Stats::Group(parent),
72 ADD_STAT(lookups,
"Number of BP lookups"),
73 ADD_STAT(condPredicted,
"Number of conditional branches predicted"),
74 ADD_STAT(condIncorrect,
"Number of conditional branches incorrect"),
75 ADD_STAT(BTBLookups,
"Number of BTB lookups"),
76 ADD_STAT(BTBHits,
"Number of BTB hits"),
77 ADD_STAT(BTBHitPct,
"BTB Hit Percentage",
78 (BTBHits / BTBLookups) * 100),
79 ADD_STAT(RASUsed,
"Number of times the RAS was used to get a target."),
80 ADD_STAT(RASIncorrect,
"Number of incorrect RAS predictions."),
81 ADD_STAT(indirectLookups,
"Number of indirect predictor lookups."),
82 ADD_STAT(indirectHits,
"Number of indirect target hits."),
83 ADD_STAT(indirectMisses,
"Number of indirect misses."),
84 ADD_STAT(indirectMispredicted,
"Number of mispredicted indirect"
111 for (
const auto& ph M5_VAR_USED :
predHist)
124 bool pred_taken =
false;
130 void *bp_history = NULL;
131 void *indirect_history = NULL;
134 DPRINTF(Branch,
"[tid:%i] [sn:%llu] "
135 "Unconditional control\n",
142 pred_taken =
lookup(tid,
pc.instAddr(), bp_history);
144 DPRINTF(Branch,
"[tid:%i] [sn:%llu] "
145 "Branch predictor predicted %i for PC %s\n",
146 tid, seqNum, pred_taken,
pc);
149 const bool orig_pred_taken = pred_taken;
154 DPRINTF(Branch,
"[tid:%i] [sn:%llu] "
155 "Creating prediction history "
156 "for PC %s\n", tid, seqNum,
pc);
159 bp_history, indirect_history, tid, inst);
178 DPRINTF(Branch,
"[tid:%i] [sn:%llu] Instruction %s is a return, "
179 "RAS predicted target: %s, RAS index: %i\n",
180 tid, seqNum,
pc, target, predict_record.
RASIndex);
192 "[tid:%i] [sn:%llu] Instruction %s was a call, adding "
193 "%s to the RAS index: %i\n",
194 tid, seqNum,
pc,
pc,
RAS[tid].topIdx());
205 "[tid:%i] [sn:%llu] Instruction %s predicted "
207 tid, seqNum,
pc, target);
209 DPRINTF(Branch,
"[tid:%i] [sn:%llu] BTB doesn't have a "
210 "valid entry\n",tid,seqNum);
219 "[tid:%i] [sn:%llu] btbUpdate "
236 "[tid:%i] [sn:%llu] "
237 "Instruction %s predicted "
238 "indirect target is %s\n",
239 tid, seqNum,
pc, target);
245 "[tid:%i] [sn:%llu] "
246 "Instruction %s no indirect "
267 predict_record.
target = target.instAddr();
280 predHist[tid].push_front(predict_record);
283 "[tid:%i] [sn:%llu] History entry added. "
284 "predHist.size(): %i\n",
293 DPRINTF(Branch,
"[tid:%i] Committing branches until "
294 "sn:%llu]\n", tid, done_sn);
297 predHist[tid].back().seqNum <= done_sn) {
301 predHist[tid].back().bpHistory,
false,
322 while (!pred_hist.empty() &&
323 pred_hist.front().seqNum > squashed_sn) {
324 if (pred_hist.front().usedRAS) {
325 DPRINTF(Branch,
"[tid:%i] [squash sn:%llu]"
326 " Restoring top of RAS to: %i,"
327 " target: %s\n", tid, squashed_sn,
328 pred_hist.front().RASIndex, pred_hist.front().RASTarget);
330 RAS[tid].restore(pred_hist.front().RASIndex,
331 pred_hist.front().RASTarget);
332 }
else if (pred_hist.front().wasCall && pred_hist.front().pushedRAS) {
334 DPRINTF(Branch,
"[tid:%i] [squash sn:%llu] Squashing"
335 " Call [sn:%llu] PC: %s Popping RAS\n", tid, squashed_sn,
336 pred_hist.front().seqNum, pred_hist.front().pc);
341 squash(tid, pred_hist.front().bpHistory);
346 DPRINTF(Branch,
"[tid:%i] [squash sn:%llu] "
347 "Removing history for [sn:%llu] "
348 "PC %#x\n", tid, squashed_sn, pred_hist.front().seqNum,
349 pred_hist.front().pc);
351 pred_hist.pop_front();
353 DPRINTF(Branch,
"[tid:%i] [squash sn:%llu] predHist.size(): %i\n",
354 tid, squashed_sn,
predHist[tid].size());
379 DPRINTF(Branch,
"[tid:%i] Squashing from sequence number %i, "
380 "setting target to %s\n", tid, squashed_sn, corrTarget);
388 if (!pred_hist.empty()) {
390 auto hist_it = pred_hist.begin();
395 if (pred_hist.front().seqNum != squashed_sn) {
396 DPRINTF(Branch,
"Front sn %i != Squash sn %i\n",
397 pred_hist.front().seqNum, squashed_sn);
399 assert(pred_hist.front().seqNum == squashed_sn);
403 if ((*hist_it).usedRAS) {
406 "[tid:%i] [squash sn:%llu] Incorrect RAS [sn:%llu]\n",
407 tid, squashed_sn, hist_it->seqNum);
420 pred_hist.front().predTaken = actually_taken;
421 pred_hist.front().target = corrTarget.instAddr();
423 update(tid, (*hist_it).pc, actually_taken,
424 pred_hist.front().bpHistory,
true, pred_hist.front().inst,
425 corrTarget.instAddr());
429 pred_hist.front().indirectHistory, actually_taken);
432 if (actually_taken) {
433 if (hist_it->wasReturn && !hist_it->usedRAS) {
434 DPRINTF(Branch,
"[tid:%i] [squash sn:%llu] "
435 "Incorrectly predicted "
436 "return [sn:%llu] PC: %#x\n", tid, squashed_sn,
440 hist_it->usedRAS =
true;
442 if (hist_it->wasIndirect) {
446 hist_it->seqNum, pred_hist.front().indirectHistory,
450 DPRINTF(Branch,
"[tid:%i] [squash sn:%llu] "
451 "BTB Update called for [sn:%llu] "
452 "PC %#x\n", tid, squashed_sn,
453 hist_it->seqNum, hist_it->pc);
455 BTB.
update((*hist_it).pc, corrTarget, tid);
459 if (hist_it->usedRAS) {
461 "[tid:%i] [squash sn:%llu] Incorrectly predicted "
462 "return [sn:%llu] PC: %#x Restoring RAS\n", tid,
464 hist_it->seqNum, hist_it->pc);
466 "[tid:%i] [squash sn:%llu] Restoring top of RAS "
467 "to: %i, target: %s\n", tid, squashed_sn,
468 hist_it->RASIndex, hist_it->RASTarget);
469 RAS[tid].restore(hist_it->RASIndex, hist_it->RASTarget);
470 hist_it->usedRAS =
false;
471 }
else if (hist_it->wasCall && hist_it->pushedRAS) {
474 "[tid:%i] [squash sn:%llu] "
475 "Incorrectly predicted "
476 "Call [sn:%llu] PC: %s Popping RAS\n",
478 hist_it->seqNum, hist_it->pc);
480 hist_it->pushedRAS =
false;
484 DPRINTF(Branch,
"[tid:%i] [sn:%llu] pred_hist empty, can't "
485 "update\n", tid, squashed_sn);
495 auto pred_hist_it = ph.begin();
497 cprintf(
"predHist[%i].size(): %i\n",
i++, ph.size());
499 while (pred_hist_it != ph.end()) {
500 cprintf(
"sn:%llu], PC:%#x, tid:%i, predTaken:%i, "
502 pred_hist_it->seqNum, pred_hist_it->pc,
503 pred_hist_it->tid, pred_hist_it->predTaken,
504 pred_hist_it->bpHistory);
virtual void updateDirectionInfo(ThreadID tid, bool actually_taken)=0
bool wasReturn
Whether or not the instruction was a return.
void regProbePoints() override
Register probe points for this object.
bool isDirectCtrl() const
virtual void genIndirectInfo(ThreadID tid, void *&indirect_history)=0
Stats::Formula BTBHitPct
Stat for percent times an entry in BTB found.
PCState buildRetPC(const PCState &curPC, const PCState &callPC)
ProbePoints::PMUUPtr ppMisses
Miss-predicted branches.
virtual void recordTarget(InstSeqNum seq_num, void *indirect_history, const TheISA::PCState &target, ThreadID tid)=0
std::vector< ReturnAddrStack > RAS
The per-thread return address stack.
int16_t ThreadID
Thread index/ID type.
virtual void recordIndirect(Addr br_addr, Addr tgt_addr, InstSeqNum seq_num, ThreadID tid)=0
Stats::Scalar lookups
Stat for number of BP lookups.
Stats::Scalar indirectMisses
Stat for the number of indirect target misses.
TheISA::PCState RASTarget
The RAS target (only valid if a return).
IndirectPredictor * iPred
The indirect target predictor.
ProbePointArg generates a point for the class of Arg.
Addr target
Target of the branch.
void drainSanityCheck() const
Perform sanity checks after a drain.
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 condPredicted
Stat for number of conditional branches predicted.
virtual void commit(InstSeqNum seq_num, ThreadID tid, void *indirect_history)=0
ProbePoints::PMUUPtr pmuProbePoint(const char *name)
Helper method to instantiate probe points belonging to this object.
BPredUnitStats(Stats::Group *parent)
void update(const InstSeqNum &done_sn, ThreadID tid)
Tells the branch predictor to commit any updates until the given sequence number.
void advancePC(PCState &pc, const StaticInstPtr &inst)
BPredUnit(const Params *p)
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.
virtual void changeDirectionPrediction(ThreadID tid, void *indirect_history, bool actually_taken)=0
Stats::Scalar indirectHits
Stat for the number of indirect target hits.
Stats::Scalar condIncorrect
Stat for number of conditional branches predicted incorrectly.
void update(Addr instPC, const TheISA::PCState &targetPC, ThreadID tid)
Updates the BTB with the target of a branch.
Stats::Scalar BTBHits
Stat for number of BTB hits.
void cprintf(const char *format, const Args &...args)
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Stats::Scalar RASUsed
Stat for number of times the RAS is used to get a target.
Stats::Scalar indirectMispredicted
Stat for the number of indirect target mispredictions.
Stats::Scalar indirectLookups
Stat for the number of indirect target lookups.
bool valid(Addr instPC, ThreadID tid)
Checks if a branch is in the BTB.
Stats::Scalar RASIncorrect
Stat for number of times the RAS is incorrect.
virtual bool lookup(Addr br_addr, TheISA::PCState &br_target, ThreadID tid)=0
virtual void uncondBranch(ThreadID tid, Addr pc, void *&bp_history)=0
BPredUnit::BPredUnitStats stats
std::vector< History > predHist
The per-thread predictor history.
bool usedRAS
Whether or not the RAS was used.
const Params * params() const
virtual void squash(InstSeqNum seq_num, ThreadID tid)=0
bool wasIndirect
Wether this instruction was an indirect branch.
ProbeManager * getProbeManager()
Get the probe manager for this object.
std::unique_ptr< PMU > PMUUPtr
virtual const std::string name() const
unsigned RASIndex
The RAS index of the instruction (only valid if a call).
bool wasCall
Whether or not the instruction was a call.
BranchPredictorParams Params
Derived & precision(int _precision)
Set the precision and marks this stat to print at the end of simulation.
GenericISA::DelaySlotPCState< MachInst > PCState
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...
TheISA::PCState lookup(Addr instPC, ThreadID tid)
Looks up an address in the BTB.
ProbePoints::PMUUPtr ppBranches
Branches seen by the branch predictor.
virtual void deleteIndirectInfo(ThreadID tid, void *indirect_history)=0
void squash(const InstSeqNum &squashed_sn, ThreadID tid)
Squashes all outstanding updates until a given sequence number.
bool predTaken
Whether or not it was predicted taken.
bool isUncondCtrl() const
Abstract superclass for simulation objects.
Generated on Wed Sep 30 2020 14:02:09 for gem5 by doxygen 1.8.17