Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/cpu/minor/BaseMinorCPU.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,10 @@ def support_take_over(cls):
)

branchPred = Param.BranchPredictor(
TournamentBP(numThreads=Parent.numThreads), "Branch Predictor"
BranchPredictor(
conditionalBranchPred=TournamentBP(numThreads=Parent.numThreads)
),
"Branch Predictor",
)

def addCheckerCpu(self):
Expand Down
6 changes: 5 additions & 1 deletion src/cpu/o3/BaseO3CPU.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ def support_take_over(cls):

# Forward pipeline delays
bacToFetchDelay = Param.Cycles(1, "Branch address calc. to fetch delay")
bacBranchPredictDelay = Param.Cycles(0, "BAC Branch Predictor delay")
fetchToDecodeDelay = Param.Cycles(1, "Fetch to decode delay")
decodeWidth = Param.Unsigned(8, "Decode width")

Expand Down Expand Up @@ -209,7 +210,10 @@ def support_take_over(cls):
smtCommitPolicy = Param.CommitPolicy("RoundRobin", "SMT Commit Policy")

branchPred = Param.BranchPredictor(
TournamentBP(numThreads=Parent.numThreads), "Branch Predictor"
BranchPredictor(
conditionalBranchPred=TournamentBP(numThreads=Parent.numThreads)
),
"Branch Predictor",
)
needsTSO = Param.Bool(False, "Enable TSO Memory model")

Expand Down
15 changes: 15 additions & 0 deletions src/cpu/o3/bac.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ BAC::BAC(CPU *_cpu, const BaseO3CPUParams &params)
decodeToFetchDelay(params.decodeToFetchDelay),
commitToFetchDelay(params.commitToFetchDelay),
bacToFetchDelay(params.bacToFetchDelay),
bacBranchPredictDelay(params.bacBranchPredictDelay),
fetchTargetWidth(params.fetchTargetWidth),
minInstSize(params.minInstSize),
numThreads(params.numThreads),
Expand All @@ -83,6 +84,7 @@ BAC::BAC(CPU *_cpu, const BaseO3CPUParams &params)
for (int i = 0; i < MaxThreads; i++) {
bacPC[i].reset(params.isa[0]->newPCState());
stalls[i] = {false, false, false};
branchPredictRemaining[i] = Cycles(0);
}

assert(bpu!=nullptr);
Expand Down Expand Up @@ -401,12 +403,24 @@ BAC::checkSignalsAndUpdate(ThreadID tid)
return true;
}

if (branchPredictRemaining[tid] > Cycles(0)) {
--branchPredictRemaining[tid];
DPRINTF(BAC,
"[global] Stalling for Branch Predictor for %i more cycles.\n",
branchPredictRemaining
);
stalls[tid].bpu = true;
} else {
stalls[tid].bpu = false;
}

if (checkStall(tid)) {
// return block(tid);
bacStatus[tid] = Blocked;
return false;
}


// If at this point the FTQ is still invalid we need to wait for
// A resteer/squash signal.
if (!ftq->isValid(tid) && bacStatus[tid] != Idle) {
Expand Down Expand Up @@ -679,6 +693,7 @@ BAC::generateFetchTargets(ThreadID tid, bool &status_change)
// Now make the actual prediction. Note the BPU will advance
// the PC to the next instruction.
predict_taken = predict(tid, staticInst, curFT, *next_pc);
branchPredictRemaining[tid] = Cycles(bacBranchPredictDelay);

DPRINTF(BAC, "[tid:%i, ftn:%llu] Branch found at PC %#x "
"taken?:%i, target:%#x\n",
Expand Down
6 changes: 6 additions & 0 deletions src/cpu/o3/bac.hh
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,9 @@ class BAC
*/
bool wroteToTimeBuffer;

/** Tracks remaining cycles that the branch predictor stalls BAC */
Cycles branchPredictRemaining[MaxThreads];

/** Source of possible stalls. */
struct Stalls
{
Expand All @@ -399,6 +402,9 @@ class BAC
/** BAC to fetch delay. */
const Cycles bacToFetchDelay;

/** BAC branch predict delay. */
const Cycles bacBranchPredictDelay;

/** The maximum width of a fetch target. This also determines the
* maximum addresses searched in one cycle. (FT width / minInstSize) */
const unsigned fetchTargetWidth;
Expand Down
8 changes: 7 additions & 1 deletion src/cpu/pred/2bit_local.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ namespace branch_prediction
{

LocalBP::LocalBP(const LocalBPParams &params)
: BPredUnit(params),
: ConditionalPredictor(params),
localPredictorSize(params.localPredictorSize),
localCtrBits(params.localCtrBits),
localPredictorSets(localPredictorSize / localCtrBits),
Expand All @@ -78,6 +78,12 @@ LocalBP::LocalBP(const LocalBPParams &params)
instShiftAmt);
}

void LocalBP::branchPlaceholder(ThreadID tid, Addr pc,
bool uncond, void * &bpHistory)
{
// Placeholder for a function that only returns history items
}

void
LocalBP::updateHistories(ThreadID tid, Addr pc, bool uncond, bool taken,
Addr target, const StaticInstPtr &inst,
Expand Down
7 changes: 5 additions & 2 deletions src/cpu/pred/2bit_local.hh
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@

#include "base/sat_counter.hh"
#include "base/types.hh"
#include "cpu/pred/bpred_unit.hh"
#include "cpu/pred/conditional.hh"
#include "params/LocalBP.hh"

namespace gem5
Expand All @@ -62,7 +62,7 @@ namespace branch_prediction
* predictor state that needs to be recorded or updated; the update can be
* determined solely by the branch being taken or not taken.
*/
class LocalBP : public BPredUnit
class LocalBP : public ConditionalPredictor
{
public:
/**
Expand All @@ -73,6 +73,9 @@ class LocalBP : public BPredUnit
// Overriding interface functions
bool lookup(ThreadID tid, Addr pc, void * &bp_history) override;

void branchPlaceholder(ThreadID tid, Addr pc, bool uncond,
void * &bpHistory) override;

void updateHistories(ThreadID tid, Addr pc, bool uncond, bool taken,
Addr target, const StaticInstPtr &inst,
void * &bp_history) override;
Expand Down
28 changes: 21 additions & 7 deletions src/cpu/pred/BranchPredictor.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,18 @@ class SimpleBTB(BranchTargetBuffer):
)


class ConditionalPredictor(SimObject):
type = "ConditionalPredictor"
cxx_class = "gem5::branch_prediction::ConditionalPredictor"
cxx_header = "cpu/pred/conditional.hh"
abstract = True

numThreads = Param.Unsigned(Parent.numThreads, "Number of threads")
instShiftAmt = Param.Unsigned(
Parent.instShiftAmt, "Number of bits to shift instructions by"
)


class IndirectPredictor(SimObject):
type = "IndirectPredictor"
cxx_class = "gem5::branch_prediction::IndirectPredictor"
Expand Down Expand Up @@ -179,7 +191,6 @@ class BranchPredictor(SimObject):
type = "BranchPredictor"
cxx_class = "gem5::branch_prediction::BPredUnit"
cxx_header = "cpu/pred/bpred_unit.hh"
abstract = True

numThreads = Param.Unsigned(Parent.numThreads, "Number of threads")
instShiftAmt = Param.Unsigned(2, "Number of bits to shift instructions by")
Expand All @@ -197,6 +208,9 @@ class BranchPredictor(SimObject):
ras = Param.ReturnAddrStack(
ReturnAddrStack(), "Return address stack, set to NULL to disable RAS."
)
conditionalBranchPred = Param.ConditionalPredictor(
"Conditional branch predictor"
)
indirectBranchPred = Param.IndirectPredictor(
SimpleIndirectPredictor(),
"Indirect branch predictor, set to NULL to disable "
Expand All @@ -212,7 +226,7 @@ class BranchPredictor(SimObject):
)


class LocalBP(BranchPredictor):
class LocalBP(ConditionalPredictor):
type = "LocalBP"
cxx_class = "gem5::branch_prediction::LocalBP"
cxx_header = "cpu/pred/2bit_local.hh"
Expand All @@ -221,7 +235,7 @@ class LocalBP(BranchPredictor):
localCtrBits = Param.Unsigned(2, "Bits per counter")


class TournamentBP(BranchPredictor):
class TournamentBP(ConditionalPredictor):
type = "TournamentBP"
cxx_class = "gem5::branch_prediction::TournamentBP"
cxx_header = "cpu/pred/tournament.hh"
Expand All @@ -235,7 +249,7 @@ class TournamentBP(BranchPredictor):
choiceCtrBits = Param.Unsigned(2, "Bits of choice counters")


class BiModeBP(BranchPredictor):
class BiModeBP(ConditionalPredictor):
type = "BiModeBP"
cxx_class = "gem5::branch_prediction::BiModeBP"
cxx_header = "cpu/pred/bi_mode.hh"
Expand Down Expand Up @@ -310,7 +324,7 @@ class TAGEBase(SimObject):

# TAGE branch predictor as described in https://www.jilp.org/vol8/v8paper1.pdf
# The default sizes below are for the 8C-TAGE configuration (63.5 Kbits)
class TAGE(BranchPredictor):
class TAGE(ConditionalPredictor):
type = "TAGE"
cxx_class = "gem5::branch_prediction::TAGE"
cxx_header = "cpu/pred/tage.hh"
Expand Down Expand Up @@ -776,7 +790,7 @@ class TAGE_SC_L_8KB(TAGE_SC_L):
statistical_corrector = TAGE_SC_L_8KB_StatisticalCorrector()


class MultiperspectivePerceptron(BranchPredictor):
class MultiperspectivePerceptron(ConditionalPredictor):
type = "MultiperspectivePerceptron"
cxx_class = "gem5::branch_prediction::MultiperspectivePerceptron"
cxx_header = "cpu/pred/multiperspective_perceptron.hh"
Expand Down Expand Up @@ -1117,7 +1131,7 @@ class MultiperspectivePerceptronTAGE8KB(MultiperspectivePerceptronTAGE):
statistical_corrector = MPP_StatisticalCorrector_8KB()


class TageSCLRef(BranchPredictor):
class TageSCLRef(ConditionalPredictor):
type = "TageSCLRef"
cxx_class = "gem5::branch_prediction::TageSCLRef"
cxx_header = "cpu/pred/tagescl_ref.hh"
Expand Down
2 changes: 2 additions & 0 deletions src/cpu/pred/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Import('*')
SimObject('BranchPredictor.py',
sim_objects=[
'BranchPredictor',
'ConditionalPredictor',
'IndirectPredictor', 'SimpleIndirectPredictor',
'BranchTargetBuffer', 'SimpleBTB', 'BTBIndexingPolicy', 'BTBSetAssociative',
'ReturnAddrStack',
Expand All @@ -68,6 +69,7 @@ Source('bpred_unit.cc')
Source('2bit_local.cc')
Source('simple_indirect.cc')
Source('it_tage.cc')
Source('conditional.cc')
Source('indirect.cc')
Source('ras.cc')
Source('tournament.cc')
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/pred/bi_mode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ namespace branch_prediction
{

BiModeBP::BiModeBP(const BiModeBPParams &params)
: BPredUnit(params),
: ConditionalPredictor(params),
globalHistoryReg(params.numThreads, 0),
globalHistoryBits(ceilLog2(params.globalPredictorSize)),
choicePredictorSize(params.choicePredictorSize),
Expand Down
4 changes: 2 additions & 2 deletions src/cpu/pred/bi_mode.hh
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
#define __CPU_PRED_BI_MODE_PRED_HH__

#include "base/sat_counter.hh"
#include "cpu/pred/bpred_unit.hh"
#include "cpu/pred/conditional.hh"
#include "params/BiModeBP.hh"

namespace gem5
Expand All @@ -69,7 +69,7 @@ namespace branch_prediction
* the branch's PC to choose between the two, destructive aliasing is reduced.
*/

class BiModeBP : public BPredUnit
class BiModeBP : public ConditionalPredictor
{
public:
BiModeBP(const BiModeBPParams &params);
Expand Down
24 changes: 13 additions & 11 deletions src/cpu/pred/bpred_unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ BPredUnit::BPredUnit(const Params &params)
predHist(numThreads),
btb(params.btb),
ras(params.ras),
cPred(params.conditionalBranchPred),
iPred(params.indirectBranchPred),
stats(this)
{
Expand Down Expand Up @@ -94,12 +95,6 @@ BPredUnit::drainSanityCheck() const
assert(ph.empty());
}

void
BPredUnit::branchPlaceholder(ThreadID tid, Addr pc,
bool uncond, void * &bp_history)
{
panic("BPredUnit::branchPlaceholder() not implemented for this BP.\n");
}

bool
BPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum,
Expand Down Expand Up @@ -156,7 +151,7 @@ BPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum,
} else {
// Conditional branches -------
++stats.condPredicted;
hist->condPred = lookup(tid, pc.instAddr(), hist->bpHistory);
hist->condPred = cPred->lookup(tid, pc.instAddr(), hist->bpHistory);

if (hist->condPred) {
++stats.condPredictedTaken;
Expand Down Expand Up @@ -326,7 +321,7 @@ BPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum,
* The actual prediction tables will updated once
* we know the correct direction.
**/
updateHistories(tid, hist->pc, hist->uncond, hist->predTaken,
cPred->updateHistories(tid, hist->pc, hist->uncond, hist->predTaken,
hist->target->instAddr(), hist->inst, hist->bpHistory);


Expand Down Expand Up @@ -383,7 +378,7 @@ BPredUnit::commitBranch(ThreadID tid, PredictorHistory* &hist)
hist->target->instAddr());

// Update the branch predictor with the correct results.
update(tid, hist->pc,
cPred->update(tid, hist->pc,
hist->actuallyTaken,
hist->bpHistory, false,
hist->inst,
Expand Down Expand Up @@ -469,7 +464,7 @@ BPredUnit::squashHistory(ThreadID tid, PredictorHistory* &history)
}

// This call will delete the bpHistory.
squash(tid, history->bpHistory);
cPred->squash(tid, history->bpHistory);

delete history;
history = nullptr;
Expand Down Expand Up @@ -548,7 +543,7 @@ BPredUnit::squash(const InstSeqNum &squashed_sn,
set(hist->target, corr_target);

// Correct Direction predictor ------------------
update(tid, hist->pc, actually_taken, hist->bpHistory,
cPred->update(tid, hist->pc, actually_taken, hist->bpHistory,
true, hist->inst, corr_target.instAddr());


Expand Down Expand Up @@ -633,6 +628,13 @@ BPredUnit::squash(const InstSeqNum &squashed_sn,
}
}

void
BPredUnit::branchPlaceholder(ThreadID tid, Addr pc,
bool uncond, void * &bp_history)
{
// Delegate to conditional predictor
cPred->branchPlaceholder(tid, pc, uncond, bp_history);
}

void
BPredUnit::dump()
Expand Down
Loading
Loading