50#include "debug/Branch.hh"
55namespace branch_prediction
60 numThreads(params.numThreads),
61 requiresBTBHit(params.requiresBTBHit),
62 instShiftAmt(params.instShiftAmt),
66 iPred(params.indirectBranchPred),
93 for ([[maybe_unused]]
const auto& ph :
predHist)
104 bool taken =
predict(inst, seqNum,
pc, tid, bpu_history);
106 assert(bpu_history!=
nullptr);
109 predHist[tid].push_front(bpu_history);
112 "predHist.size(): %i\n", tid, seqNum,
predHist[tid].size());
124 assert(hist ==
nullptr);
162 "[tid:%i, sn:%llu] Branch predictor predicted %i for PC:%#x %s\n",
192 tid, seqNum, hist->
pc, (hist->
btbHit) ?
"hit" :
"miss");
211 if (
ras && branch_detected) {
219 "a call, push return address %s onto the RAS\n",
220 tid, seqNum,
pc, *return_addr);
235 "return, RAS poped return addr: %s\n",
270 "[tid:%i, sn:%llu] Instruction %s predicted "
271 "indirect target is %s\n",
276 "[tid:%i, sn:%llu] PC:%#x no indirect target\n",
277 tid, seqNum,
pc.instAddr());
304 DPRINTF(
Branch,
"%s(tid:%i, sn:%i, PC:%#x, %s) -> taken:%i, target:%s "
305 "provider:%s\n", __func__, tid, seqNum, hist->
pc,
338 "[sn:%llu]\n", tid, done_sn);
341 predHist[tid].back()->seqNum <= done_sn) {
349 DPRINTF(
Branch,
"[tid:%i] [commit sn:%llu] pred_hist.size(): %i\n",
350 tid, done_sn,
predHist[tid].size());
365 "pred:%i, taken:%i, target:%#x\n",
368 hist->
target->instAddr());
375 hist->
target->instAddr());
397 predHist[tid].front()->seqNum > squashed_sn) {
403 DPRINTF(
Branch,
"[tid:%i, squash sn:%llu] Removing history for "
404 "sn:%llu, PC:%#x\n", tid, squashed_sn, hist->seqNum,
411 DPRINTF(
Branch,
"[tid:%i] [squash sn:%llu] pred_hist.size(): %i\n",
412 tid, squashed_sn,
predHist[tid].size());
431 DPRINTF(
Branch,
"[tid:%i] [squash sn:%llu] Incorrect call/return "
432 "PC %#x. Fix RAS.\n", tid, history->
seqNum,
451 bool actually_taken,
ThreadID tid,
bool from_commit)
470 DPRINTF(
Branch,
"[tid:%i] Squash from %s start from sequence number %i, "
471 "setting target to %s\n", tid, from_commit ?
"commit" :
"decode",
472 squashed_sn, corr_target);
483 if (!pred_hist.empty()) {
487 DPRINTF(
Branch,
"[tid:%i] [squash sn:%llu] Mispredicted: %s, PC:%#x\n",
504 if (actually_taken) {
533 true, actually_taken, corr_target,
541 if (actually_taken && (hist->
rasHistory ==
nullptr)) {
544 if (hist->
type == BranchType::Return) {
546 "Incorrectly predicted return [sn:%llu] PC: %#x\n",
547 tid, squashed_sn, hist->
seqNum, hist->
pc);
557 corr_target, corr_target);
560 "Incorrectly predicted call: [sn:%llu,PC:%#x] "
561 " Push return address %s onto RAS\n", tid,
562 squashed_sn, hist->
seqNum, hist->
pc,
568 }
else if (!actually_taken && (hist->
rasHistory !=
nullptr)) {
579 if (actually_taken &&
590 "PC %#x -> T: %#x\n", tid,
603 "update\n", tid, squashed_sn);
614 auto hist = ph.begin();
616 cprintf(
"predHist[%i].size(): %i\n",
i++, ph.size());
618 while (hist != ph.end()) {
619 cprintf(
"sn:%llu], PC:%#x, tid:%i, predTaken:%i, "
620 "bpHistory:%#x, rasHistory:%#x\n",
621 (*hist)->seqNum, (*hist)->pc,
622 (*hist)->tid, (*hist)->predTaken,
623 (*hist)->bpHistory, (*hist)->rasHistory);
634 : statistics::
Group(bp),
635 ADD_STAT(lookups, statistics::units::Count::get(),
636 "Number of BP lookups"),
637 ADD_STAT(squashes, statistics::units::Count::get(),
638 "Number of branches that got squashed (completely removed) as "
639 "an earlier branch was mispredicted."),
640 ADD_STAT(corrected, statistics::units::Count::get(),
641 "Number of branches that got corrected but not yet commited. "
642 "Branches get corrected by decode or after execute. Also a "
643 "branch misprediction can be detected out-of-order. Therefore, "
644 "a corrected branch might not end up beeing committed in case "
645 "an even earlier branch was mispredicted"),
646 ADD_STAT(earlyResteers, statistics::units::Count::get(),
647 "Number of branches that got redirected after decode."),
648 ADD_STAT(committed, statistics::units::Count::get(),
649 "Number of branches finally committed "),
650 ADD_STAT(mispredicted, statistics::units::Count::get(),
651 "Number of committed branches that were mispredicted."),
652 ADD_STAT(targetProvider, statistics::units::Count::get(),
653 "The component providing the target for taken branches"),
654 ADD_STAT(targetWrong, statistics::units::Count::get(),
655 "Number of branches where the target was incorrect or not "
656 "available at prediction time."),
657 ADD_STAT(condPredicted, statistics::units::Count::get(),
658 "Number of conditional branches predicted"),
659 ADD_STAT(condPredictedTaken, statistics::units::Count::get(),
660 "Number of conditional branches predicted as taken"),
661 ADD_STAT(condIncorrect, statistics::units::Count::get(),
662 "Number of conditional branches incorrect"),
663 ADD_STAT(predTakenBTBMiss, statistics::units::Count::get(),
664 "Number of branches predicted taken but missed in BTB"),
665 ADD_STAT(NotTakenMispredicted, statistics::units::Count::get(),
666 "Number branches predicted 'not taken' but turned out "
668 ADD_STAT(TakenMispredicted, statistics::units::Count::get(),
669 "Number branches predicted taken but are actually not taken"),
670 ADD_STAT(BTBLookups, statistics::units::Count::get(),
671 "Number of BTB lookups"),
672 ADD_STAT(BTBUpdates, statistics::units::Count::get(),
673 "Number of BTB updates"),
674 ADD_STAT(BTBHits, statistics::units::Count::get(),
675 "Number of BTB hits"),
676 ADD_STAT(BTBHitRatio, statistics::units::Ratio::get(),
"BTB Hit Ratio",
677 BTBHits / BTBLookups),
678 ADD_STAT(BTBMispredicted, statistics::units::Count::get(),
679 "Number BTB mispredictions. No target found or target wrong"),
680 ADD_STAT(indirectLookups, statistics::units::Count::get(),
681 "Number of indirect predictor lookups."),
682 ADD_STAT(indirectHits, statistics::units::Count::get(),
683 "Number of indirect target hits."),
684 ADD_STAT(indirectMisses, statistics::units::Count::get(),
685 "Number of indirect misses."),
686 ADD_STAT(indirectMispredicted, statistics::units::Count::get(),
687 "Number of mispredicted indirect branches.")
690 using namespace statistics;
virtual std::string name() const
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
ProbePointArg generates a point for the class of Arg.
Abstract superclass for simulation objects.
Base class for branch operations.
virtual std::unique_ptr< PCStateBase > buildRetPC(const PCStateBase &cur_pc, const PCStateBase &call_pc) const
bool isDirectCtrl() const
bool isUncondCtrl() const
virtual void advancePC(PCStateBase &pc_state) const =0
bool isIndirectCtrl() const
Basically a wrapper class to hold both the branch predictor and the BTB.
std::vector< History > predHist
The per-thread predictor history.
probing::PMUUPtr pmuProbePoint(const char *name)
Helper method to instantiate probe points belonging to this object.
void update(const InstSeqNum &done_sn, ThreadID tid)
Tells the branch predictor to commit any updates until the given sequence number.
BPredUnit(const Params &p)
Branch Predictor Unit (BPU) interface functions.
bool predict(const StaticInstPtr &inst, const InstSeqNum &seqNum, PCStateBase &pc, ThreadID tid)
Predicts whether or not the instruction is a taken branch, and the target of the branch if it is take...
probing::PMUUPtr ppMisses
Miss-predicted branches.
const bool requiresBTBHit
Requires the BTB to hit for returns and indirect branches.
void drainSanityCheck() const
Perform sanity checks after a drain.
IndirectPredictor * iPred
The indirect target predictor.
void commitBranch(ThreadID tid, PredictorHistory *&bpu_history)
Commit a particular branch.
probing::PMUUPtr ppBranches
Branches seen by the branch predictor.
void regProbePoints() override
Register probe points for this object.
const unsigned numThreads
Number of the threads for which the branch history is maintained.
virtual bool lookup(ThreadID tid, Addr pc, void *&bp_history)=0
Looks up a given conditional branch PC of in the BP to see if it is taken or not taken.
virtual void updateHistories(ThreadID tid, Addr pc, bool uncond, bool taken, Addr target, void *&bp_history)=0
Ones done with the prediction this function updates the path and global history.
BranchPredictorParams Params
void squashHistory(ThreadID tid, PredictorHistory *&bpu_history)
Squashes a particular branch instance.
ReturnAddrStack * ras
The return address stack.
void squash(const InstSeqNum &squashed_sn, ThreadID tid)
Squashes all outstanding updates until a given sequence number.
gem5::branch_prediction::BPredUnit::BPredUnitStats stats
BranchTargetBuffer * btb
The BTB.
virtual const PCStateBase * lookup(ThreadID tid, Addr instPC, BranchType type=BranchType::NoBranch)=0
Looks up an address in the BTB to get the target of the branch.
virtual void incorrectTarget(Addr inst_pc, BranchType type=BranchType::NoBranch)
Update BTB statistics.
virtual void update(ThreadID tid, Addr inst_pc, const PCStateBase &target_pc, BranchType type=BranchType::NoBranch, StaticInstPtr inst=nullptr)=0
Updates the BTB with the target of a branch.
virtual void commit(ThreadID tid, InstSeqNum sn, void *&i_history)=0
A branch gets finally commited.
virtual void update(ThreadID tid, InstSeqNum sn, Addr pc, bool squash, bool taken, const PCStateBase &target, BranchType br_type, void *&i_history)=0
Updates the indirect predictor with history information of a branch.
virtual const PCStateBase * lookup(ThreadID tid, InstSeqNum sn, Addr pc, void *&i_history)=0
Predicts the indirect target of an indirect branch.
virtual void squash(ThreadID tid, InstSeqNum sn, void *&i_history)=0
Squashes a branch.
const PCStateBase * pop(ThreadID tid, void *&ras_history)
Pops the top address from the RAS.
void squash(ThreadID tid, void *&ras_history)
The branch (call/return) got squashed.
void commit(ThreadID tid, bool misp, const BranchType brType, void *&ras_history)
A branch got finally got finally commited.
void push(ThreadID tid, const PCStateBase &pc, void *&ras_history)
Pushes an address onto the RAS.
Derived & ysubnames(const char **names)
Derived & precision(int _precision)
Set the precision and marks this stat to print at the end of simulation.
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Derived & init(size_type _x, size_type _y)
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
ProbeManager * getProbeManager()
Get the probe manager for this object.
std::string toString(BranchType type)
BranchType getBranchType(StaticInstPtr inst)
enums::BranchType BranchType
std::unique_ptr< PMU > PMUUPtr
const FlagsType pdf
Print the percent of the total that this entry represents.
const FlagsType total
Print the total.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
int16_t ThreadID
Thread index/ID type.
void cprintf(const char *format, const Args &...args)
statistics::Vector2d corrected
statistics::Scalar BTBUpdates
statistics::Scalar BTBLookups
BTB stats.
statistics::Scalar condIncorrect
statistics::Vector2d squashes
statistics::Vector2d committed
statistics::Scalar BTBMispredicted
statistics::Scalar indirectLookups
Indirect stats.
statistics::Vector2d lookups
Stats per branch type.
statistics::Scalar indirectHits
statistics::Scalar NotTakenMispredicted
statistics::Scalar TakenMispredicted
statistics::Vector2d targetProvider
Target prediction per branch type.
statistics::Scalar condPredictedTaken
statistics::Scalar condPredicted
Additional scalar stats for conditional branches.
statistics::Vector2d mispredicted
statistics::Vector2d earlyResteers
BPredUnitStats(BPredUnit *bp)
statistics::Formula BTBHitRatio
statistics::Scalar predTakenBTBMiss
statistics::Scalar indirectMisses
statistics::Vector2d targetWrong
statistics::Scalar BTBHits
bool predTaken
Whether or not it was predicted taken.
const InstSeqNum seqNum
The sequence number for the predictor history entry.
bool condPred
The prediction of the conditional predictor.
void * bpHistory
Pointer to the history objects passed back from the branch predictor subcomponents.
const Addr pc
The PC associated with the sequence number.
const bool call
Whether or not the instruction was a call.
const StaticInstPtr inst
The branch instrction.
bool actuallyTaken
To record the actual outcome of the branch.
bool mispredict
The branch was corrected hence was mispredicted.
const bool uncond
Was unconditional control.
const BranchType type
The type of the branch.
bool btbHit
Was BTB hit at prediction time.
std::unique_ptr< PCStateBase > target
The predicted target.
TargetProvider targetProvider
Which component provided the target.
const std::string & name()