cpu: Use PCStateBase in the branch predictors.
Use PCStateBase instead of TheISA::PCState in the branch predictors.
Change-Id: I0b0867bc09b6191a54d7658813c0b9656c436811
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/52055
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Reviewed-by: Earl Ou <shunhsingou@google.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/cpu/minor/fetch2.cc b/src/cpu/minor/fetch2.cc
index 3c9659c..58b68de 100644
--- a/src/cpu/minor/fetch2.cc
+++ b/src/cpu/minor/fetch2.cc
@@ -156,7 +156,7 @@
/* Unpredicted branch or barrier */
DPRINTF(Branch, "Unpredicted branch seen inst: %s\n", *inst);
branchPredictor.squash(inst->id.fetchSeqNum,
- branch.target->as<TheISA::PCState>(), true, inst->id.threadId);
+ *branch.target, true, inst->id.threadId);
// Update after squashing to accomodate O3CPU
// using the branch prediction code.
branchPredictor.update(inst->id.fetchSeqNum,
@@ -172,8 +172,7 @@
/* Predicted taken, not taken */
DPRINTF(Branch, "Branch mis-predicted inst: %s\n", *inst);
branchPredictor.squash(inst->id.fetchSeqNum,
- branch.target->as<TheISA::PCState>() /* Not used */,
- false, inst->id.threadId);
+ *branch.target /* Not used */, false, inst->id.threadId);
// Update after squashing to accomodate O3CPU
// using the branch prediction code.
branchPredictor.update(inst->id.fetchSeqNum,
@@ -184,7 +183,7 @@
DPRINTF(Branch, "Branch mis-predicted target inst: %s target: %s\n",
*inst, *branch.target);
branchPredictor.squash(inst->id.fetchSeqNum,
- branch.target->as<TheISA::PCState>(), true, inst->id.threadId);
+ *branch.target, true, inst->id.threadId);
break;
}
}
@@ -206,8 +205,7 @@
DPRINTF(Branch, "Trying to predict for inst: %s\n", *inst);
if (branchPredictor.predict(inst->staticInst,
- inst->id.fetchSeqNum, inst_pc->as<TheISA::PCState>(),
- inst->id.threadId)) {
+ inst->id.fetchSeqNum, *inst_pc, inst->id.threadId)) {
set(branch.target, *inst_pc);
inst->predictedTaken = true;
set(inst->predictedTarget, inst_pc);
diff --git a/src/cpu/o3/fetch.cc b/src/cpu/o3/fetch.cc
index 3b93160..34e00d4 100644
--- a/src/cpu/o3/fetch.cc
+++ b/src/cpu/o3/fetch.cc
@@ -524,7 +524,7 @@
ThreadID tid = inst->threadNumber;
predict_taken = branchPred->predict(inst->staticInst, inst->seqNum,
- next_pc.as<TheISA::PCState>(), tid);
+ next_pc, tid);
if (predict_taken) {
DPRINTF(Fetch, "[tid:%i] [sn:%llu] Branch at PC %#x "
@@ -968,7 +968,7 @@
if (fromCommit->commitInfo[tid].mispredictInst &&
fromCommit->commitInfo[tid].mispredictInst->isControl()) {
branchPred->squash(fromCommit->commitInfo[tid].doneSeqNum,
- fromCommit->commitInfo[tid].pc->as<TheISA::PCState>(),
+ *fromCommit->commitInfo[tid].pc,
fromCommit->commitInfo[tid].branchTaken, tid);
} else {
branchPred->squash(fromCommit->commitInfo[tid].doneSeqNum,
@@ -990,7 +990,7 @@
// Update the branch predictor.
if (fromDecode->decodeInfo[tid].branchMispredict) {
branchPred->squash(fromDecode->decodeInfo[tid].doneSeqNum,
- fromDecode->decodeInfo[tid].nextPC->as<TheISA::PCState>(),
+ *fromDecode->decodeInfo[tid].nextPC,
fromDecode->decodeInfo[tid].branchTaken, tid);
} else {
branchPred->squash(fromDecode->decodeInfo[tid].doneSeqNum,
diff --git a/src/cpu/pred/bpred_unit.cc b/src/cpu/pred/bpred_unit.cc
index 502b345..b1b4503 100644
--- a/src/cpu/pred/bpred_unit.cc
+++ b/src/cpu/pred/bpred_unit.cc
@@ -129,7 +129,7 @@
bool
BPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum,
- TheISA::PCState &pc, ThreadID tid)
+ PCStateBase &pc, ThreadID tid)
{
// See if branch predictor predicts taken.
// If so, get its target addr either from the BTB or the RAS.
@@ -137,7 +137,7 @@
// up once it's done.
bool pred_taken = false;
- TheISA::PCState target = pc;
+ std::unique_ptr<PCStateBase> target(pc.clone());
++stats.lookups;
ppBranches->notify(1);
@@ -179,19 +179,20 @@
predict_record.wasReturn = true;
// If it's a function return call, then look up the address
// in the RAS.
- TheISA::PCState rasTop = RAS[tid].top();
- target = inst->buildRetPC(pc, rasTop)->as<TheISA::PCState>();
+ const PCStateBase *ras_top = RAS[tid].top();
+ if (ras_top)
+ set(target, inst->buildRetPC(pc, *ras_top));
// Record the top entry of the RAS, and its index.
predict_record.usedRAS = true;
predict_record.RASIndex = RAS[tid].topIdx();
- predict_record.RASTarget = rasTop;
+ set(predict_record.RASTarget, ras_top);
RAS[tid].pop();
DPRINTF(Branch, "[tid:%i] [sn:%llu] Instruction %s is a return, "
"RAS predicted target: %s, RAS index: %i\n",
- tid, seqNum, pc, target, predict_record.RASIndex);
+ tid, seqNum, pc, *target, predict_record.RASIndex);
} else {
if (inst->isCall()) {
@@ -214,14 +215,14 @@
if (BTB.valid(pc.instAddr(), tid)) {
++stats.BTBHits;
// If it's not a return, use the BTB to get target addr.
- target = BTB.lookup(pc.instAddr(), tid);
+ set(target, BTB.lookup(pc.instAddr(), tid));
DPRINTF(Branch,
"[tid:%i] [sn:%llu] Instruction %s predicted "
"target is %s\n",
- tid, seqNum, pc, target);
+ tid, seqNum, pc, *target);
} else {
DPRINTF(Branch, "[tid:%i] [sn:%llu] BTB doesn't have a "
- "valid entry\n",tid,seqNum);
+ "valid entry\n", tid, seqNum);
pred_taken = false;
predict_record.predTaken = pred_taken;
// The Direction of the branch predictor is altered
@@ -237,27 +238,25 @@
RAS[tid].pop();
predict_record.pushedRAS = false;
}
- inst->advancePC(target);
+ inst->advancePC(*target);
}
} else {
predict_record.wasIndirect = true;
++stats.indirectLookups;
//Consult indirect predictor on indirect control
- if (iPred->lookup(pc.instAddr(), target, tid)) {
+ if (iPred->lookup(pc.instAddr(), *target, tid)) {
// Indirect predictor hit
++stats.indirectHits;
DPRINTF(Branch,
- "[tid:%i] [sn:%llu] "
- "Instruction %s predicted "
+ "[tid:%i] [sn:%llu] Instruction %s predicted "
"indirect target is %s\n",
- tid, seqNum, pc, target);
+ tid, seqNum, pc, *target);
} else {
++stats.indirectMisses;
pred_taken = false;
predict_record.predTaken = pred_taken;
DPRINTF(Branch,
- "[tid:%i] [sn:%llu] "
- "Instruction %s no indirect "
+ "[tid:%i] [sn:%llu] Instruction %s no indirect "
"target\n",
tid, seqNum, pc);
if (!inst->isCall() && !inst->isReturn()) {
@@ -266,21 +265,21 @@
RAS[tid].pop();
predict_record.pushedRAS = false;
}
- inst->advancePC(target);
+ inst->advancePC(*target);
}
- iPred->recordIndirect(pc.instAddr(), target.instAddr(), seqNum,
- tid);
+ iPred->recordIndirect(pc.instAddr(), target->instAddr(),
+ seqNum, tid);
}
}
} else {
if (inst->isReturn()) {
predict_record.wasReturn = true;
}
- inst->advancePC(target);
+ inst->advancePC(*target);
}
- predict_record.target = target.instAddr();
+ predict_record.target = target->instAddr();
- pc = target;
+ set(pc, *target);
if (iPred) {
// Update the indirect predictor with the direction prediction
@@ -339,10 +338,10 @@
DPRINTF(Branch, "[tid:%i] [squash sn:%llu]"
" Restoring top of RAS to: %i,"
" target: %s\n", tid, squashed_sn,
- pred_hist.front().RASIndex, pred_hist.front().RASTarget);
+ pred_hist.front().RASIndex, *pred_hist.front().RASTarget);
RAS[tid].restore(pred_hist.front().RASIndex,
- pred_hist.front().RASTarget);
+ pred_hist.front().RASTarget.get());
} else if (pred_hist.front().wasCall && pred_hist.front().pushedRAS) {
// Was a call but predicated false. Pop RAS here
DPRINTF(Branch, "[tid:%i] [squash sn:%llu] Squashing"
@@ -371,7 +370,7 @@
void
BPredUnit::squash(const InstSeqNum &squashed_sn,
- const TheISA::PCState &corrTarget,
+ const PCStateBase &corr_target,
bool actually_taken, ThreadID tid)
{
// Now that we know that a branch was mispredicted, we need to undo
@@ -391,7 +390,7 @@
ppMisses->notify(1);
DPRINTF(Branch, "[tid:%i] Squashing from sequence number %i, "
- "setting target to %s\n", tid, squashed_sn, corrTarget);
+ "setting target to %s\n", tid, squashed_sn, corr_target);
// Squash All Branches AFTER this mispredicted branch
squash(squashed_sn, tid);
@@ -432,11 +431,11 @@
// Remember the correct direction for the update at commit.
pred_hist.front().predTaken = actually_taken;
- pred_hist.front().target = corrTarget.instAddr();
+ pred_hist.front().target = corr_target.instAddr();
update(tid, (*hist_it).pc, actually_taken,
pred_hist.front().bpHistory, true, pred_hist.front().inst,
- corrTarget.instAddr());
+ corr_target.instAddr());
if (iPred) {
iPred->changeDirectionPrediction(tid,
@@ -458,7 +457,7 @@
if (iPred) {
iPred->recordTarget(
hist_it->seqNum, pred_hist.front().indirectHistory,
- corrTarget, tid);
+ corr_target, tid);
}
} else {
DPRINTF(Branch,"[tid:%i] [squash sn:%llu] "
@@ -466,7 +465,7 @@
"PC %#x\n", tid, squashed_sn,
hist_it->seqNum, hist_it->pc);
- BTB.update((*hist_it).pc, corrTarget, tid);
+ BTB.update(hist_it->pc, corr_target, tid);
}
} else {
//Actually not Taken
@@ -479,8 +478,8 @@
DPRINTF(Branch,
"[tid:%i] [squash sn:%llu] Restoring top of RAS "
"to: %i, target: %s\n", tid, squashed_sn,
- hist_it->RASIndex, hist_it->RASTarget);
- RAS[tid].restore(hist_it->RASIndex, hist_it->RASTarget);
+ hist_it->RASIndex, *hist_it->RASTarget);
+ RAS[tid].restore(hist_it->RASIndex, hist_it->RASTarget.get());
hist_it->usedRAS = false;
} else if (hist_it->wasCall && hist_it->pushedRAS) {
//Was a Call but predicated false. Pop RAS here
diff --git a/src/cpu/pred/bpred_unit.hh b/src/cpu/pred/bpred_unit.hh
index 0e1f5d3..e57f8e4 100644
--- a/src/cpu/pred/bpred_unit.hh
+++ b/src/cpu/pred/bpred_unit.hh
@@ -88,7 +88,7 @@
* @return Returns if the branch is taken or not.
*/
bool predict(const StaticInstPtr &inst, const InstSeqNum &seqNum,
- TheISA::PCState &pc, ThreadID tid);
+ PCStateBase &pc, ThreadID tid);
// @todo: Rename this function.
virtual void uncondBranch(ThreadID tid, Addr pc, void * &bp_history) = 0;
@@ -119,7 +119,7 @@
* @param tid The thread id.
*/
void squash(const InstSeqNum &squashed_sn,
- const TheISA::PCState &corr_target,
+ const PCStateBase &corr_target,
bool actually_taken, ThreadID tid);
/**
@@ -155,11 +155,17 @@
bool BTBValid(Addr instPC) { return BTB.valid(instPC, 0); }
/**
- * Looks up a given PC in the BTB to get the predicted target.
+ * Looks up a given PC in the BTB to get the predicted target. The PC may
+ * be changed or deleted in the future, so it needs to be used immediately,
+ * and/or copied for use later.
* @param inst_PC The PC to look up.
* @return The address of the target of the branch.
*/
- TheISA::PCState BTBLookup(Addr instPC) { return BTB.lookup(instPC, 0); }
+ const PCStateBase *
+ BTBLookup(Addr inst_pc)
+ {
+ return BTB.lookup(inst_pc, 0);
+ }
/**
* Updates the BP with taken/not taken information.
@@ -183,7 +189,7 @@
* @param target_PC The branch's target that will be added to the BTB.
*/
void
- BTBUpdate(Addr instPC, const TheISA::PCState &target)
+ BTBUpdate(Addr instPC, const PCStateBase &target)
{
BTB.update(instPC, target, 0);
}
@@ -203,12 +209,21 @@
void *indirect_history, ThreadID _tid,
const StaticInstPtr & inst)
: seqNum(seq_num), pc(instPC), bpHistory(bp_history),
- indirectHistory(indirect_history), RASTarget(0), RASIndex(0),
- tid(_tid), predTaken(pred_taken), usedRAS(0), pushedRAS(0),
- wasCall(0), wasReturn(0), wasIndirect(0), target(MaxAddr),
- inst(inst)
+ indirectHistory(indirect_history), tid(_tid),
+ predTaken(pred_taken), inst(inst)
{}
+ PredictorHistory(const PredictorHistory &other) :
+ seqNum(other.seqNum), pc(other.pc), bpHistory(other.bpHistory),
+ indirectHistory(other.indirectHistory), RASIndex(other.RASIndex),
+ tid(other.tid), predTaken(other.predTaken), usedRAS(other.usedRAS),
+ pushedRAS(other.pushedRAS), wasCall(other.wasCall),
+ wasReturn(other.wasReturn), wasIndirect(other.wasIndirect),
+ target(other.target), inst(other.inst)
+ {
+ set(RASTarget, other.RASTarget);
+ }
+
bool
operator==(const PredictorHistory &entry) const
{
@@ -225,15 +240,15 @@
* predictor. It is used to update or restore state of the
* branch predictor.
*/
- void *bpHistory;
+ void *bpHistory = nullptr;
- void *indirectHistory;
+ void *indirectHistory = nullptr;
/** The RAS target (only valid if a return). */
- TheISA::PCState RASTarget;
+ std::unique_ptr<PCStateBase> RASTarget;
/** The RAS index of the instruction (only valid if a call). */
- unsigned RASIndex;
+ unsigned RASIndex = 0;
/** The thread id. */
ThreadID tid;
@@ -242,24 +257,24 @@
bool predTaken;
/** Whether or not the RAS was used. */
- bool usedRAS;
+ bool usedRAS = false;
/* Whether or not the RAS was pushed */
- bool pushedRAS;
+ bool pushedRAS = false;
/** Whether or not the instruction was a call. */
- bool wasCall;
+ bool wasCall = false;
/** Whether or not the instruction was a return. */
- bool wasReturn;
+ bool wasReturn = false;
/** Wether this instruction was an indirect branch */
- bool wasIndirect;
+ bool wasIndirect = false;
/** Target of the branch. First it is predicted, and fixed later
* if necessary
*/
- Addr target;
+ Addr target = MaxAddr;
/** The branch instrction */
const StaticInstPtr inst;
diff --git a/src/cpu/pred/btb.cc b/src/cpu/pred/btb.cc
index a3950cd..71afd45 100644
--- a/src/cpu/pred/btb.cc
+++ b/src/cpu/pred/btb.cc
@@ -112,35 +112,35 @@
// @todo Create some sort of return struct that has both whether or not the
// address is valid, and also the address. For now will just use addr = 0 to
// represent invalid entry.
-TheISA::PCState
-DefaultBTB::lookup(Addr instPC, ThreadID tid)
+const PCStateBase *
+DefaultBTB::lookup(Addr inst_pc, ThreadID tid)
{
- unsigned btb_idx = getIndex(instPC, tid);
+ unsigned btb_idx = getIndex(inst_pc, tid);
- Addr inst_tag = getTag(instPC);
+ Addr inst_tag = getTag(inst_pc);
assert(btb_idx < numEntries);
if (btb[btb_idx].valid
&& inst_tag == btb[btb_idx].tag
&& btb[btb_idx].tid == tid) {
- return btb[btb_idx].target;
+ return btb[btb_idx].target.get();
} else {
- return TheISA::PCState(0);
+ return nullptr;
}
}
void
-DefaultBTB::update(Addr instPC, const TheISA::PCState &target, ThreadID tid)
+DefaultBTB::update(Addr inst_pc, const PCStateBase &target, ThreadID tid)
{
- unsigned btb_idx = getIndex(instPC, tid);
+ unsigned btb_idx = getIndex(inst_pc, tid);
assert(btb_idx < numEntries);
btb[btb_idx].tid = tid;
btb[btb_idx].valid = true;
- btb[btb_idx].target = target;
- btb[btb_idx].tag = getTag(instPC);
+ set(btb[btb_idx].target, target);
+ btb[btb_idx].tag = getTag(inst_pc);
}
} // namespace branch_prediction
diff --git a/src/cpu/pred/btb.hh b/src/cpu/pred/btb.hh
index e3c2f5f..ce1cb21 100644
--- a/src/cpu/pred/btb.hh
+++ b/src/cpu/pred/btb.hh
@@ -45,21 +45,17 @@
private:
struct BTBEntry
{
- BTBEntry()
- : tag(0), target(0), valid(false)
- {}
-
/** The entry's tag. */
- Addr tag;
+ Addr tag = 0;
/** The entry's target. */
- TheISA::PCState target;
+ std::unique_ptr<PCStateBase> target;
/** The entry's thread id. */
ThreadID tid;
/** Whether or not the entry is valid. */
- bool valid;
+ bool valid = false;
};
public:
@@ -79,7 +75,7 @@
* @param tid The thread id.
* @return Returns the target of the branch.
*/
- TheISA::PCState lookup(Addr instPC, ThreadID tid);
+ const PCStateBase *lookup(Addr instPC, ThreadID tid);
/** Checks if a branch is in the BTB.
* @param inst_PC The address of the branch to look up.
@@ -89,12 +85,11 @@
bool valid(Addr instPC, ThreadID tid);
/** Updates the BTB with the target of a branch.
- * @param inst_PC The address of the branch being updated.
- * @param target_PC The target address of the branch.
+ * @param inst_pc The address of the branch being updated.
+ * @param target_pc The target address of the branch.
* @param tid The thread id.
*/
- void update(Addr instPC, const TheISA::PCState &targetPC,
- ThreadID tid);
+ void update(Addr inst_pc, const PCStateBase &target_pc, ThreadID tid);
private:
/** Returns the index into the BTB, based on the branch's PC.
diff --git a/src/cpu/pred/indirect.hh b/src/cpu/pred/indirect.hh
index e744a1b..ee17d2c 100644
--- a/src/cpu/pred/indirect.hh
+++ b/src/cpu/pred/indirect.hh
@@ -52,7 +52,7 @@
{
}
- virtual bool lookup(Addr br_addr, TheISA::PCState& br_target,
+ virtual bool lookup(Addr br_addr, PCStateBase& br_target,
ThreadID tid) = 0;
virtual void recordIndirect(Addr br_addr, Addr tgt_addr,
InstSeqNum seq_num, ThreadID tid) = 0;
@@ -60,7 +60,7 @@
void * indirect_history) = 0;
virtual void squash(InstSeqNum seq_num, ThreadID tid) = 0;
virtual void recordTarget(InstSeqNum seq_num, void * indirect_history,
- const TheISA::PCState& target, ThreadID tid) = 0;
+ const PCStateBase& target, ThreadID tid) = 0;
virtual void genIndirectInfo(ThreadID tid, void* & indirect_history) = 0;
virtual void updateDirectionInfo(ThreadID tid, bool actually_taken) = 0;
virtual void deleteIndirectInfo(ThreadID tid, void * indirect_history) = 0;
diff --git a/src/cpu/pred/ras.cc b/src/cpu/pred/ras.cc
index d2235e9..8d415b7 100644
--- a/src/cpu/pred/ras.cc
+++ b/src/cpu/pred/ras.cc
@@ -47,16 +47,14 @@
{
usedEntries = 0;
tos = 0;
- for (unsigned i = 0; i < numEntries; ++i)
- addrStack[i].set(0);
}
void
-ReturnAddrStack::push(const TheISA::PCState &return_addr)
+ReturnAddrStack::push(const PCStateBase &return_addr)
{
incrTos();
- addrStack[tos] = return_addr;
+ set(addrStack[tos], return_addr);
if (usedEntries != numEntries) {
++usedEntries;
@@ -74,12 +72,11 @@
}
void
-ReturnAddrStack::restore(unsigned top_entry_idx,
- const TheISA::PCState &restored)
+ReturnAddrStack::restore(unsigned top_entry_idx, const PCStateBase *restored)
{
tos = top_entry_idx;
- addrStack[tos] = restored;
+ set(addrStack[tos], restored);
if (usedEntries != numEntries) {
++usedEntries;
diff --git a/src/cpu/pred/ras.hh b/src/cpu/pred/ras.hh
index 40c6dac..0b4b471 100644
--- a/src/cpu/pred/ras.hh
+++ b/src/cpu/pred/ras.hh
@@ -31,9 +31,8 @@
#include <vector>
-#include "arch/pcstate.hh"
+#include "arch/generic/pcstate.hh"
#include "base/types.hh"
-#include "config/the_isa.hh"
namespace gem5
{
@@ -58,13 +57,13 @@
void reset();
/** Returns the top address on the RAS. */
- TheISA::PCState top() { return addrStack[tos]; }
+ const PCStateBase *top() { return addrStack[tos].get(); }
/** Returns the index of the top of the RAS. */
unsigned topIdx() { return tos; }
/** Pushes an address onto the RAS. */
- void push(const TheISA::PCState &return_addr);
+ void push(const PCStateBase &return_addr);
/** Pops the top address from the RAS. */
void pop();
@@ -74,7 +73,7 @@
* @param top_entry_idx The index of the RAS that will now be the top.
* @param restored The new target address of the new top of the RAS.
*/
- void restore(unsigned top_entry_idx, const TheISA::PCState &restored);
+ void restore(unsigned top_entry_idx, const PCStateBase *restored);
bool empty() { return usedEntries == 0; }
@@ -96,7 +95,7 @@
}
/** The RAS itself. */
- std::vector<TheISA::PCState> addrStack;
+ std::vector<std::unique_ptr<PCStateBase>> addrStack;
/** The number of entries in the RAS. */
unsigned numEntries;
diff --git a/src/cpu/pred/simple_indirect.cc b/src/cpu/pred/simple_indirect.cc
index 7fd75f4..2a1fc7a 100644
--- a/src/cpu/pred/simple_indirect.cc
+++ b/src/cpu/pred/simple_indirect.cc
@@ -93,7 +93,7 @@
}
bool
-SimpleIndirectPredictor::lookup(Addr br_addr, TheISA::PCState& target,
+SimpleIndirectPredictor::lookup(Addr br_addr, PCStateBase& target,
ThreadID tid)
{
Addr set_index = getSetIndex(br_addr, threadInfo[tid].ghr, tid);
@@ -105,8 +105,8 @@
const auto &iset = targetCache[set_index];
for (auto way = iset.begin(); way != iset.end(); ++way) {
if (way->tag == tag) {
- DPRINTF(Indirect, "Hit %x (target:%s)\n", br_addr, way->target);
- target = way->target;
+ DPRINTF(Indirect, "Hit %x (target:%s)\n", br_addr, *way->target);
+ set(target, *way->target);
return true;
}
}
@@ -177,7 +177,7 @@
void
SimpleIndirectPredictor::recordTarget(
- InstSeqNum seq_num, void * indirect_history, const TheISA::PCState& target,
+ InstSeqNum seq_num, void * indirect_history, const PCStateBase& target,
ThreadID tid)
{
ThreadInfo &t_info = threadInfo[tid];
@@ -200,7 +200,7 @@
if (way->tag == tag) {
DPRINTF(Indirect, "Updating Target (seq: %d br:%x set:%d target:"
"%s)\n", seq_num, hist_entry.pcAddr, set_index, target);
- way->target = target;
+ set(way->target, target);
return;
}
}
@@ -210,7 +210,7 @@
// Did not find entry, random replacement
auto &way = iset[rand() % numWays];
way.tag = tag;
- way.target = target;
+ set(way.target, target);
}
diff --git a/src/cpu/pred/simple_indirect.hh b/src/cpu/pred/simple_indirect.hh
index 0949a76..8587047 100644
--- a/src/cpu/pred/simple_indirect.hh
+++ b/src/cpu/pred/simple_indirect.hh
@@ -47,13 +47,13 @@
public:
SimpleIndirectPredictor(const SimpleIndirectPredictorParams ¶ms);
- bool lookup(Addr br_addr, TheISA::PCState& br_target, ThreadID tid);
+ bool lookup(Addr br_addr, PCStateBase& br_target, ThreadID tid);
void recordIndirect(Addr br_addr, Addr tgt_addr, InstSeqNum seq_num,
ThreadID tid);
void commit(InstSeqNum seq_num, ThreadID tid, void * indirect_history);
void squash(InstSeqNum seq_num, ThreadID tid);
void recordTarget(InstSeqNum seq_num, void * indirect_history,
- const TheISA::PCState& target, ThreadID tid);
+ const PCStateBase& target, ThreadID tid);
void genIndirectInfo(ThreadID tid, void* & indirect_history);
void updateDirectionInfo(ThreadID tid, bool actually_taken);
void deleteIndirectInfo(ThreadID tid, void * indirect_history);
@@ -73,9 +73,8 @@
struct IPredEntry
{
- IPredEntry() : tag(0), target(0) { }
- Addr tag;
- TheISA::PCState target;
+ Addr tag = 0;
+ std::unique_ptr<PCStateBase> target;
};
std::vector<std::vector<IPredEntry> > targetCache;
@@ -95,11 +94,9 @@
struct ThreadInfo
{
- ThreadInfo() : headHistEntry(0), ghr(0) { }
-
std::deque<HistoryEntry> pathHist;
- unsigned headHistEntry;
- unsigned ghr;
+ unsigned headHistEntry = 0;
+ unsigned ghr = 0;
};
std::vector<ThreadInfo> threadInfo;
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 38caaf5..7ddd100 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -371,9 +371,8 @@
const InstSeqNum cur_sn(0);
set(t_info.predPC, thread->pcState());
const bool predict_taken(
- branchPred->predict(curStaticInst, cur_sn,
- t_info.predPC->as<TheISA::PCState>(),
- curThread));
+ branchPred->predict(curStaticInst, cur_sn, *t_info.predPC,
+ curThread));
if (predict_taken)
++t_info.execContextStats.numPredictedBranches;
@@ -489,7 +488,8 @@
branchPred->update(cur_sn, curThread);
} else {
// Mis-predicted branch
- branchPred->squash(cur_sn, thread->pcState(), branching, curThread);
+ branchPred->squash(cur_sn, thread->pcState(), branching,
+ curThread);
++t_info.execContextStats.numBranchMispred;
}
}