42#include "debug/Indirect.hh"
47namespace branch_prediction
51 const SimpleIndirectPredictorParams ¶ms)
53 hashGHR(params.indirectHashGHR),
54 hashTargets(params.indirectHashTargets),
55 numSets(params.indirectSets),
56 numWays(params.indirectWays),
57 tagBits(params.indirectTagSize),
58 pathLength(params.indirectPathLength),
59 speculativePathLength(params.speculativePathLength),
60 instShift(params.instShiftAmt),
61 ghrNumBits(params.indirectGHRBits),
62 ghrMask((1 << params.indirectGHRBits)-1),
66 panic(
"Indirect predictor requires power of 2 number of sets");
83 DPRINTF(Indirect,
"Reset Indirect predictor\n");
91 for (
unsigned j = 0; j <
numWays; j++) {
106 i_history =
static_cast<void*
>(history);
124 Addr pc,
void * &i_history)
126 assert(i_history==
nullptr);
151 DPRINTF(Indirect,
"Looking up PC:%#x, (set:%d, tag:%d), "
152 "ghr:%#x, pathHist sz:%#x\n",
157 for (
auto way = iset.begin(); way != iset.end(); ++way) {
160 if (way->tag == history->
tag && way->target) {
161 DPRINTF(Indirect,
"Hit %x (target:%s)\n", br_addr, *way->target);
162 set(target, *way->target);
168 DPRINTF(Indirect,
"Miss %x\n", br_addr);
169 history->
hit =
false;
178 if (i_history ==
nullptr)
return;
182 DPRINTF(Indirect,
"Committing seq:%d, PC:%#x, ghr:%#x, pathHist sz:%lu\n",
199 bool squash,
bool taken,
const PCStateBase& target,
204 if (i_history==
nullptr) {
208 assert(history!=
nullptr);
210 DPRINTF(Indirect,
"Update sn:%i PC:%#x, squash:%i, ghr:%#x,path sz:%i\n",
233 DPRINTF(Indirect,
"Record Target seq:%d, PC:%#x, TGT:%#x, "
234 "ghr:%#x, (set:%x, tag:%x)\n",
235 sn, history->
pcAddr, target, history->
ghr,
243 DPRINTF(Indirect,
"Recording %x seq:%d\n", history->
pcAddr, sn);
265 if (i_history ==
nullptr)
return;
270 DPRINTF(Indirect,
"Squashing seq:%d, PC:%#x, indirect:%i, "
271 "ghr:%#x, pathHist sz:%#x\n",
316 DPRINTF(Indirect,
"History seems to be corrupted. %#x != %#x\n",
321 DPRINTF(Indirect,
"Record Target seq:%d, PC:%#x, TGT:%#x, "
322 "ghr:%#x, (set:%x, tag:%x)\n",
331 for (
auto way = iset.begin(); way != iset.end(); ++way) {
332 if (way->tag == history->
tag) {
334 "Updating Target (seq: %d br:%x set:%d target:%s)\n",
336 set(way->target, target);
341 DPRINTF(Indirect,
"Allocating Target (seq: %d br:%x set:%d target:%s)\n",
345 auto &way = iset[rand() %
numWays];
346 way.tag = history->
tag;
347 set(way.target, target);
380 : statistics::
Group(parent),
381 ADD_STAT(lookups, statistics::units::Count::get(),
382 "Number of lookups"),
383 ADD_STAT(hits, statistics::units::Count::get(),
384 "Number of hits of a tag"),
385 ADD_STAT(misses, statistics::units::Count::get(),
387 ADD_STAT(targetRecords, statistics::units::Count::get(),
388 "Number of targets that where recorded/installed in the cache"),
389 ADD_STAT(indirectRecords, statistics::units::Count::get(),
390 "Number of indirect branches/calls recorded in the"
392 ADD_STAT(speculativeOverflows, statistics::units::Count::get(),
393 "Number of times more than the allowed capacity for speculative "
394 "branches/calls where in flight and destroy the path history")
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
void reset() override
Indirect predictor interface.
const unsigned pathLength
std::vector< std::vector< IPredEntry > > targetCache
std::vector< ThreadInfo > threadInfo
const unsigned ghrNumBits
void genIndirectInfo(ThreadID tid, void *&iHistory)
const PCStateBase * lookup(ThreadID tid, InstSeqNum sn, Addr pc, void *&iHistory) override
Predicts the indirect target of an indirect branch.
void recordTarget(ThreadID tid, InstSeqNum sn, const PCStateBase &target, IndirectHistory *&history)
void update(ThreadID tid, InstSeqNum sn, Addr pc, bool squash, bool taken, const PCStateBase &target, BranchType br_type, void *&iHistory) override
Updates the indirect predictor with history information of a branch.
gem5::branch_prediction::SimpleIndirectPredictor::IndirectStats stats
void commit(ThreadID tid, InstSeqNum sn, void *&iHistory) override
A branch gets finally commited.
void squash(ThreadID tid, InstSeqNum sn, void *&iHistory) override
Squashes a branch.
SimpleIndirectPredictor(const SimpleIndirectPredictorParams ¶ms)
const unsigned speculativePathLength
void updateDirectionInfo(ThreadID tid, bool taken, Addr pc, Addr target)
Addr getSetIndex(Addr br_addr, ThreadID tid)
Addr getTag(Addr br_addr)
bool isIndirectNoReturn(BranchType type)
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
static constexpr std::enable_if_t< std::is_integral_v< T >, int > floorLog2(T x)
static constexpr bool isPowerOf2(const T &n)
#define panic(...)
This implements a cprintf based panic() function.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
const Params & params() const
enums::BranchType BranchType
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
int16_t ThreadID
Thread index/ID type.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Indirect branch history information Used for prediction, update and recovery.
IndirectStats(statistics::Group *parent)
statistics::Scalar lookups
statistics::Scalar speculativeOverflows
statistics::Scalar misses
statistics::Scalar targetRecords
statistics::Scalar indirectRecords