summaryrefslogtreecommitdiff
path: root/src/cpu/inorder/resources/bpred_unit.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/inorder/resources/bpred_unit.cc')
-rw-r--r--src/cpu/inorder/resources/bpred_unit.cc95
1 files changed, 66 insertions, 29 deletions
diff --git a/src/cpu/inorder/resources/bpred_unit.cc b/src/cpu/inorder/resources/bpred_unit.cc
index c4bb61974..0002c270b 100644
--- a/src/cpu/inorder/resources/bpred_unit.cc
+++ b/src/cpu/inorder/resources/bpred_unit.cc
@@ -103,6 +103,12 @@ BPredUnit::regStats()
.desc("Number of BTB hits")
;
+ BTBHitPct
+ .name(name() + ".BTBHitPct")
+ .desc("BTB Hit Percentage")
+ .precision(6);
+ BTBHitPct = (BTBHits / BTBLookups) * 100;
+
usedRAS
.name(name() + ".usedRAS")
.desc("Number of times the RAS was used to get a target.")
@@ -150,30 +156,35 @@ BPredUnit::predict(DynInstPtr &inst, Addr &PC, ThreadID tid)
using TheISA::MachInst;
+ int asid = inst->asid;
bool pred_taken = false;
Addr target;
++lookups;
+ DPRINTF(InOrderBPred, "[tid:%i] [sn:%i] %s ... PC%#x doing branch prediction\n",
+ tid, inst->seqNum, inst->staticInst->disassemble(inst->PC),
+ inst->readPC());
+
void *bp_history = NULL;
if (inst->isUncondCtrl()) {
- DPRINTF(Resource, "BranchPred: [tid:%i] Unconditional control.\n", tid);
+ DPRINTF(InOrderBPred, "BranchPred: [tid:%i] Unconditional control.\n", tid);
pred_taken = true;
// Tell the BP there was an unconditional branch.
BPUncond(bp_history);
- if (inst->isReturn() && RAS[tid].empty()) {
- DPRINTF(Resource, "BranchPred: [tid:%i] RAS is empty, predicting "
- "false.\n", tid);
- pred_taken = false;
- }
+ if (inst->isReturn() && RAS[tid].empty()) {
+ DPRINTF(InOrderBPred, "BranchPred: [tid:%i] RAS is empty, predicting "
+ "false.\n", tid);
+ pred_taken = false;
+ }
} else {
++condPredicted;
pred_taken = BPLookup(PC, bp_history);
- DPRINTF(Resource, "BranchPred: [tid:%i]: Branch predictor predicted %i "
+ DPRINTF(InOrderBPred, "BranchPred: [tid:%i]: Branch predictor predicted %i "
"for PC %#x\n",
tid, pred_taken, inst->readPC());
}
@@ -199,22 +210,28 @@ BPredUnit::predict(DynInstPtr &inst, Addr &PC, ThreadID tid)
RAS[tid].pop();
- DPRINTF(Resource, "BranchPred: [tid:%i]: Instruction %#x is a return, "
+ DPRINTF(InOrderBPred, "BranchPred: [tid:%i]: Instruction %#x is a return, "
"RAS predicted target: %#x, RAS index: %i.\n",
tid, inst->readPC(), target, predict_record.RASIndex);
} else {
++BTBLookups;
if (inst->isCall()) {
- RAS[tid].push(PC + sizeof(MachInst));
+#if ISA_HAS_DELAY_SLOT
+ Addr ras_pc = PC + (2 * sizeof(MachInst)); // Next Next PC
+#else
+ Addr ras_pc = PC + sizeof(MachInst); // Next PC
+#endif
+
+ RAS[tid].push(ras_pc);
// Record that it was a call so that the top RAS entry can
// be popped off if the speculation is incorrect.
predict_record.wasCall = true;
- DPRINTF(Resource, "BranchPred: [tid:%i] Instruction %#x was a call"
- ", adding %#x to the RAS.\n",
- tid, inst->readPC(), PC + sizeof(MachInst));
+ DPRINTF(InOrderBPred, "BranchPred: [tid:%i]: Instruction %#x was a call"
+ ", adding %#x to the RAS index: %i.\n",
+ tid, inst->readPC(), ras_pc, RAS[tid].topIdx());
}
if (inst->isCall() &&
@@ -222,20 +239,20 @@ BPredUnit::predict(DynInstPtr &inst, Addr &PC, ThreadID tid)
inst->isDirectCtrl()) {
target = inst->branchTarget();
- DPRINTF(Fetch, "BranchPred: [tid:%i]: Setting %#x predicted"
+ DPRINTF(InOrderBPred, "BranchPred: [tid:%i]: Setting %#x predicted"
" target to %#x.\n",
tid, inst->readPC(), target);
- } else if (BTB.valid(PC, tid)) {
+ } else if (BTB.valid(PC, asid)) {
++BTBHits;
// If it's not a return, use the BTB to get the target addr.
- target = BTB.lookup(PC, tid);
+ target = BTB.lookup(PC, asid);
- DPRINTF(Resource, "BranchPred: [tid:%i]: Instruction %#x predicted"
+ DPRINTF(InOrderBPred, "BranchPred: [tid:%i]: [asid:%i] Instruction %#x predicted"
" target is %#x.\n",
- tid, inst->readPC(), target);
+ tid, asid, inst->readPC(), target);
} else {
- DPRINTF(Resource, "BranchPred: [tid:%i]: BTB doesn't have a "
+ DPRINTF(InOrderBPred, "BranchPred: [tid:%i]: BTB doesn't have a "
"valid entry.\n",tid);
pred_taken = false;
}
@@ -258,7 +275,8 @@ BPredUnit::predict(DynInstPtr &inst, Addr &PC, ThreadID tid)
predHist[tid].push_front(predict_record);
- DPRINTF(Resource, "[tid:%i] predHist.size(): %i\n", tid, predHist[tid].size());
+ DPRINTF(InOrderBPred, "[tid:%i] [sn:%i] pushed onto front of predHist ...predHist.size(): %i\n",
+ tid, inst->seqNum, predHist[tid].size());
inst->setBranchPred(pred_taken);
@@ -292,7 +310,7 @@ BPredUnit::squash(const InstSeqNum &squashed_sn, ThreadID tid)
while (!pred_hist.empty() &&
pred_hist.front().seqNum > squashed_sn) {
if (pred_hist.front().usedRAS) {
- DPRINTF(Resource, "BranchPred: [tid:%i]: Restoring top of RAS to: %i,"
+ DPRINTF(InOrderBPred, "BranchPred: [tid:%i]: Restoring top of RAS to: %i,"
" target: %#x.\n",
tid,
pred_hist.front().RASIndex,
@@ -302,7 +320,7 @@ BPredUnit::squash(const InstSeqNum &squashed_sn, ThreadID tid)
pred_hist.front().RASTarget);
} else if (pred_hist.front().wasCall) {
- DPRINTF(Resource, "BranchPred: [tid:%i]: Removing speculative entry "
+ DPRINTF(InOrderBPred, "BranchPred: [tid:%i]: Removing speculative entry "
"added to the RAS.\n",tid);
RAS[tid].pop();
@@ -331,7 +349,7 @@ BPredUnit::squash(const InstSeqNum &squashed_sn,
++condIncorrect;
- DPRINTF(Resource, "BranchPred: [tid:%i]: Squashing from sequence number %i, "
+ DPRINTF(InOrderBPred, "BranchPred: [tid:%i]: Squashing from sequence number %i, "
"setting target to %#x.\n",
tid, squashed_sn, corr_target);
@@ -341,19 +359,38 @@ BPredUnit::squash(const InstSeqNum &squashed_sn,
// corresponding to the squash. In that case, don't bother trying to
// fix up the entry.
if (!pred_hist.empty()) {
- if(pred_hist.front().seqNum==squashed_sn){
+ HistoryIt hist_it = pred_hist.begin();
+ //HistoryIt hist_it = find(pred_hist.begin(), pred_hist.end(),
+ // squashed_sn);
- assert(pred_hist.front().seqNum == squashed_sn);
- if (pred_hist.front().usedRAS) {
+ //assert(hist_it != pred_hist.end());
+ if (pred_hist.front().seqNum != squashed_sn) {
+ DPRINTF(InOrderBPred, "Front sn %i != Squash sn %i\n",
+ pred_hist.front().seqNum, squashed_sn);
+
+ assert(pred_hist.front().seqNum == squashed_sn);
+ }
+
+
+ if ((*hist_it).usedRAS) {
++RASIncorrect;
}
- BPUpdate(pred_hist.front().PC, actually_taken,
+ BPUpdate((*hist_it).PC, actually_taken,
pred_hist.front().bpHistory);
- BTB.update(pred_hist.front().PC, corr_target, tid);
- pred_hist.pop_front();
- }
+ BTB.update((*hist_it).PC, corr_target, tid);
+
+ DPRINTF(InOrderBPred, "BranchPred: [tid:%i]: Removing history for [sn:%i] "
+ "PC %#x.\n", tid, (*hist_it).seqNum, (*hist_it).PC);
+
+ pred_hist.erase(hist_it);
+
+ DPRINTF(InOrderBPred, "[tid:%i]: predHist.size(): %i\n", tid, predHist[tid].size());
+
+ } else {
+ DPRINTF(InOrderBPred, "BranchPred: [tid:%i]: [sn:%i] pred_hist empty, can't update.\n",
+ tid, squashed_sn);
}
}