summaryrefslogtreecommitdiff
path: root/src/cpu/o3/bpred_unit_impl.hh
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2006-05-30 14:17:41 -0400
committerKevin Lim <ktlim@umich.edu>2006-05-30 14:17:41 -0400
commit4a5b51b516853c9fcaabc44caacdd7e8e93dc0ef (patch)
tree4b7d92408a2b74a16ae6f7b4167ded00079355ef /src/cpu/o3/bpred_unit_impl.hh
parentd308055afc1ace1f321b76e8a85a9a45165da2ce (diff)
parentf1fab2a4469d6cb2e55ebac15da02f8c1fcb7055 (diff)
downloadgem5-4a5b51b516853c9fcaabc44caacdd7e8e93dc0ef.tar.xz
Merge ktlim@zizzer:/bk/m5
into zamp.eecs.umich.edu:/z/ktlim2/clean/newmem SConstruct: src/SConscript: src/arch/SConscript: src/arch/alpha/faults.cc: src/arch/alpha/tlb.cc: src/base/traceflags.py: src/cpu/SConscript: src/cpu/base.cc: src/cpu/base.hh: src/cpu/base_dyn_inst.cc: src/cpu/cpu_exec_context.cc: src/cpu/cpu_exec_context.hh: src/cpu/exec_context.hh: src/cpu/o3/alpha_cpu.hh: src/cpu/o3/alpha_cpu_impl.hh: src/cpu/o3/alpha_dyn_inst.hh: src/cpu/o3/cpu.cc: src/cpu/o3/cpu.hh: src/cpu/o3/regfile.hh: src/cpu/ozone/cpu.hh: src/cpu/simple/base.cc: src/cpu/base_dyn_inst.hh: src/cpu/o3/2bit_local_pred.cc: src/cpu/o3/2bit_local_pred.hh: src/cpu/o3/alpha_cpu.cc: src/cpu/o3/alpha_cpu_builder.cc: src/cpu/o3/alpha_dyn_inst.cc: src/cpu/o3/alpha_dyn_inst_impl.hh: src/cpu/o3/alpha_impl.hh: src/cpu/o3/alpha_params.hh: src/cpu/o3/bpred_unit.cc: src/cpu/o3/bpred_unit.hh: src/cpu/o3/bpred_unit_impl.hh: src/cpu/o3/btb.cc: src/cpu/o3/btb.hh: src/cpu/o3/comm.hh: src/cpu/o3/commit.cc: src/cpu/o3/commit.hh: src/cpu/o3/commit_impl.hh: src/cpu/o3/cpu_policy.hh: src/cpu/o3/decode.cc: src/cpu/o3/decode.hh: src/cpu/o3/decode_impl.hh: src/cpu/o3/fetch.cc: src/cpu/o3/fetch.hh: src/cpu/o3/fetch_impl.hh: src/cpu/o3/free_list.cc: src/cpu/o3/free_list.hh: src/cpu/o3/iew.cc: src/cpu/o3/iew.hh: src/cpu/o3/iew_impl.hh: src/cpu/o3/inst_queue.cc: src/cpu/o3/inst_queue.hh: src/cpu/o3/inst_queue_impl.hh: src/cpu/o3/mem_dep_unit.cc: src/cpu/o3/mem_dep_unit.hh: src/cpu/o3/mem_dep_unit_impl.hh: src/cpu/o3/ras.cc: src/cpu/o3/ras.hh: src/cpu/o3/rename.cc: src/cpu/o3/rename.hh: src/cpu/o3/rename_impl.hh: src/cpu/o3/rename_map.cc: src/cpu/o3/rename_map.hh: src/cpu/o3/rob.cc: src/cpu/o3/rob.hh: src/cpu/o3/rob_impl.hh: src/cpu/o3/sat_counter.cc: src/cpu/o3/sat_counter.hh: src/cpu/o3/store_set.cc: src/cpu/o3/store_set.hh: src/cpu/o3/tournament_pred.cc: src/cpu/o3/tournament_pred.hh: Hand merges. --HG-- rename : build/SConstruct => SConstruct rename : SConscript => src/SConscript rename : arch/alpha/ev5.cc => src/arch/alpha/ev5.cc rename : arch/alpha/isa/decoder.isa => src/arch/alpha/isa/decoder.isa rename : arch/alpha/isa/pal.isa => src/arch/alpha/isa/pal.isa rename : base/traceflags.py => src/base/traceflags.py rename : cpu/SConscript => src/cpu/SConscript rename : cpu/base.cc => src/cpu/base.cc rename : cpu/base.hh => src/cpu/base.hh rename : cpu/base_dyn_inst.cc => src/cpu/base_dyn_inst.cc rename : cpu/base_dyn_inst.hh => src/cpu/base_dyn_inst.hh rename : cpu/cpu_exec_context.cc => src/cpu/cpu_exec_context.cc rename : cpu/cpu_exec_context.hh => src/cpu/cpu_exec_context.hh rename : cpu/cpu_models.py => src/cpu/cpu_models.py rename : cpu/exec_context.hh => src/cpu/exec_context.hh rename : cpu/exetrace.cc => src/cpu/exetrace.cc rename : cpu/exetrace.hh => src/cpu/exetrace.hh rename : cpu/inst_seq.hh => src/cpu/inst_seq.hh rename : cpu/o3/2bit_local_pred.cc => src/cpu/o3/2bit_local_pred.cc rename : cpu/o3/2bit_local_pred.hh => src/cpu/o3/2bit_local_pred.hh rename : cpu/o3/alpha_cpu.hh => src/cpu/o3/alpha_cpu.hh rename : cpu/o3/alpha_cpu_builder.cc => src/cpu/o3/alpha_cpu_builder.cc rename : cpu/o3/alpha_cpu_impl.hh => src/cpu/o3/alpha_cpu_impl.hh rename : cpu/o3/alpha_dyn_inst.hh => src/cpu/o3/alpha_dyn_inst.hh rename : cpu/o3/alpha_dyn_inst_impl.hh => src/cpu/o3/alpha_dyn_inst_impl.hh rename : cpu/o3/alpha_impl.hh => src/cpu/o3/alpha_impl.hh rename : cpu/o3/alpha_params.hh => src/cpu/o3/alpha_params.hh rename : cpu/o3/bpred_unit.cc => src/cpu/o3/bpred_unit.cc rename : cpu/o3/bpred_unit.hh => src/cpu/o3/bpred_unit.hh rename : cpu/o3/bpred_unit_impl.hh => src/cpu/o3/bpred_unit_impl.hh rename : cpu/o3/btb.cc => src/cpu/o3/btb.cc rename : cpu/o3/btb.hh => src/cpu/o3/btb.hh rename : cpu/o3/comm.hh => src/cpu/o3/comm.hh rename : cpu/o3/commit.cc => src/cpu/o3/commit.cc rename : cpu/o3/commit.hh => src/cpu/o3/commit.hh rename : cpu/o3/commit_impl.hh => src/cpu/o3/commit_impl.hh rename : cpu/o3/cpu.cc => src/cpu/o3/cpu.cc rename : cpu/o3/cpu.hh => src/cpu/o3/cpu.hh rename : cpu/o3/cpu_policy.hh => src/cpu/o3/cpu_policy.hh rename : cpu/o3/decode.cc => src/cpu/o3/decode.cc rename : cpu/o3/decode.hh => src/cpu/o3/decode.hh rename : cpu/o3/decode_impl.hh => src/cpu/o3/decode_impl.hh rename : cpu/o3/fetch.cc => src/cpu/o3/fetch.cc rename : cpu/o3/fetch.hh => src/cpu/o3/fetch.hh rename : cpu/o3/fetch_impl.hh => src/cpu/o3/fetch_impl.hh rename : cpu/o3/free_list.cc => src/cpu/o3/free_list.cc rename : cpu/o3/free_list.hh => src/cpu/o3/free_list.hh rename : cpu/o3/iew.cc => src/cpu/o3/iew.cc rename : cpu/o3/iew.hh => src/cpu/o3/iew.hh rename : cpu/o3/iew_impl.hh => src/cpu/o3/iew_impl.hh rename : cpu/o3/inst_queue.cc => src/cpu/o3/inst_queue.cc rename : cpu/o3/inst_queue.hh => src/cpu/o3/inst_queue.hh rename : cpu/o3/inst_queue_impl.hh => src/cpu/o3/inst_queue_impl.hh rename : cpu/o3/mem_dep_unit.cc => src/cpu/o3/mem_dep_unit.cc rename : cpu/o3/mem_dep_unit.hh => src/cpu/o3/mem_dep_unit.hh rename : cpu/o3/mem_dep_unit_impl.hh => src/cpu/o3/mem_dep_unit_impl.hh rename : cpu/o3/ras.cc => src/cpu/o3/ras.cc rename : cpu/o3/ras.hh => src/cpu/o3/ras.hh rename : cpu/o3/regfile.hh => src/cpu/o3/regfile.hh rename : cpu/o3/rename.cc => src/cpu/o3/rename.cc rename : cpu/o3/rename.hh => src/cpu/o3/rename.hh rename : cpu/o3/rename_impl.hh => src/cpu/o3/rename_impl.hh rename : cpu/o3/rename_map.cc => src/cpu/o3/rename_map.cc rename : cpu/o3/rename_map.hh => src/cpu/o3/rename_map.hh rename : cpu/o3/rob.hh => src/cpu/o3/rob.hh rename : cpu/o3/rob_impl.hh => src/cpu/o3/rob_impl.hh rename : cpu/o3/sat_counter.hh => src/cpu/o3/sat_counter.hh rename : cpu/o3/store_set.cc => src/cpu/o3/store_set.cc rename : cpu/o3/store_set.hh => src/cpu/o3/store_set.hh rename : cpu/o3/tournament_pred.cc => src/cpu/o3/tournament_pred.cc rename : cpu/o3/tournament_pred.hh => src/cpu/o3/tournament_pred.hh rename : cpu/ozone/cpu.cc => src/cpu/ozone/cpu.cc rename : cpu/ozone/cpu.hh => src/cpu/ozone/cpu.hh rename : cpu/ozone/cpu_impl.hh => src/cpu/ozone/cpu_impl.hh rename : cpu/static_inst.hh => src/cpu/static_inst.hh rename : kern/system_events.cc => src/kern/system_events.cc rename : kern/tru64/tru64.hh => src/kern/tru64/tru64.hh rename : python/m5/objects/AlphaFullCPU.py => src/python/m5/objects/AlphaFullCPU.py rename : sim/pseudo_inst.cc => src/sim/pseudo_inst.cc extra : convert_revision : ff351fc0e3a7c0f23e59fdbec33d8209eb9280be
Diffstat (limited to 'src/cpu/o3/bpred_unit_impl.hh')
-rw-r--r--src/cpu/o3/bpred_unit_impl.hh202
1 files changed, 125 insertions, 77 deletions
diff --git a/src/cpu/o3/bpred_unit_impl.hh b/src/cpu/o3/bpred_unit_impl.hh
index 8d16a0cdf..c37df606b 100644
--- a/src/cpu/o3/bpred_unit_impl.hh
+++ b/src/cpu/o3/bpred_unit_impl.hh
@@ -26,20 +26,26 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <list>
+#include <vector>
+
#include "base/trace.hh"
#include "base/traceflags.hh"
#include "cpu/o3/bpred_unit.hh"
+using namespace std;
+
template<class Impl>
-TwobitBPredUnit<Impl>::TwobitBPredUnit(Params &params)
- : BP(params.local_predictor_size,
- params.local_ctr_bits,
- params.instShiftAmt),
- BTB(params.BTBEntries,
- params.BTBTagSize,
- params.instShiftAmt),
- RAS(params.RASSize)
+TwobitBPredUnit<Impl>::TwobitBPredUnit(Params *params)
+ : BP(params->localPredictorSize,
+ params->localCtrBits,
+ params->instShiftAmt),
+ BTB(params->BTBEntries,
+ params->BTBTagSize,
+ params->instShiftAmt)
{
+ for (int i=0; i < Impl::MaxThreads; i++)
+ RAS[i].init(params->RASSize);
}
template <class Impl>
@@ -79,7 +85,7 @@ TwobitBPredUnit<Impl>::regStats()
usedRAS
.name(name() + ".BPredUnit.usedRAS")
- .desc("Number of times the RAS was used.")
+ .desc("Number of times the RAS was used to get a target.")
;
RASIncorrect
@@ -89,8 +95,30 @@ TwobitBPredUnit<Impl>::regStats()
}
template <class Impl>
+void
+TwobitBPredUnit<Impl>::switchOut()
+{
+ for (int i = 0; i < Impl::MaxThreads; ++i) {
+ predHist[i].clear();
+ }
+}
+
+template <class Impl>
+void
+TwobitBPredUnit<Impl>::takeOverFrom()
+{
+/*
+ for (int i = 0; i < Impl::MaxThreads; ++i)
+ RAS[i].reset();
+
+ BP.reset();
+ BTB.reset();
+*/
+}
+
+template <class Impl>
bool
-TwobitBPredUnit<Impl>::predict(DynInstPtr &inst, Addr &PC)
+TwobitBPredUnit<Impl>::predict(DynInstPtr &inst, Addr &PC, unsigned tid)
{
// See if branch predictor predicts taken.
// If so, get its target addr either from the BTB or the RAS.
@@ -106,18 +134,19 @@ TwobitBPredUnit<Impl>::predict(DynInstPtr &inst, Addr &PC)
++lookups;
if (inst->isUncondCtrl()) {
- DPRINTF(Fetch, "BranchPred: Unconditional control.\n");
+ DPRINTF(Fetch, "BranchPred: [tid:%i] Unconditional control.\n", tid);
pred_taken = true;
} else {
++condPredicted;
pred_taken = BPLookup(PC);
- DPRINTF(Fetch, "BranchPred: Branch predictor predicted %i for PC %#x"
- "\n", pred_taken, inst->readPC());
+ DPRINTF(Fetch, "BranchPred: [tid:%i]: Branch predictor predicted %i "
+ "for PC %#x\n",
+ tid, pred_taken, inst->readPC());
}
- PredictorHistory predict_record(inst->seqNum, PC, pred_taken);
+ PredictorHistory predict_record(inst->seqNum, PC, pred_taken, tid);
// Now lookup in the BTB or RAS.
if (pred_taken) {
@@ -126,45 +155,48 @@ TwobitBPredUnit<Impl>::predict(DynInstPtr &inst, Addr &PC)
// If it's a function return call, then look up the address
// in the RAS.
- target = RAS.top();
+ target = RAS[tid].top();
// Record the top entry of the RAS, and its index.
predict_record.usedRAS = true;
- predict_record.RASIndex = RAS.topIdx();
+ predict_record.RASIndex = RAS[tid].topIdx();
predict_record.RASTarget = target;
- RAS.pop();
+ assert(predict_record.RASIndex < 16);
- DPRINTF(Fetch, "BranchPred: Instruction %#x is a return, RAS "
- "predicted target: %#x, RAS index: %i.\n",
- inst->readPC(), target, predict_record.RASIndex);
+ RAS[tid].pop();
+
+ DPRINTF(Fetch, "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.push(PC+sizeof(MachInst));
+ RAS[tid].push(PC + sizeof(MachInst));
// 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(Fetch, "BranchPred: Instruction %#x was a call, "
- "adding %#x to the RAS.\n",
- inst->readPC(), PC+sizeof(MachInst));
+ DPRINTF(Fetch, "BranchPred: [tid:%i] Instruction %#x was a call"
+ ", adding %#x to the RAS.\n",
+ tid, inst->readPC(), PC + sizeof(MachInst));
}
- if (BTB.valid(PC)) {
+ if (BTB.valid(PC, tid)) {
++BTBHits;
//If it's anything else, use the BTB to get the target addr.
- target = BTB.lookup(PC);
+ target = BTB.lookup(PC, tid);
- DPRINTF(Fetch, "BranchPred: Instruction %#x predicted target "
- "is %#x.\n", inst->readPC(), target);
+ DPRINTF(Fetch, "BranchPred: [tid:%i]: Instruction %#x predicted"
+ " target is %#x.\n",
+ tid, inst->readPC(), target);
} else {
- DPRINTF(Fetch, "BranchPred: BTB doesn't have a valid entry."
- "\n");
+ DPRINTF(Fetch, "BranchPred: [tid:%i]: BTB doesn't have a "
+ "valid entry.\n",tid);
pred_taken = false;
}
@@ -180,97 +212,113 @@ TwobitBPredUnit<Impl>::predict(DynInstPtr &inst, Addr &PC)
inst->setPredTarg(PC);
}
- predHist.push_front(predict_record);
+ predHist[tid].push_front(predict_record);
- assert(!predHist.empty());
+ DPRINTF(Fetch, "[tid:%i] predHist.size(): %i\n", tid, predHist[tid].size());
return pred_taken;
}
template <class Impl>
void
-TwobitBPredUnit<Impl>::update(const InstSeqNum &done_sn)
+TwobitBPredUnit<Impl>::update(const InstSeqNum &done_sn, unsigned tid)
{
- DPRINTF(Fetch, "BranchPred: Commiting branches until sequence number "
- "%i.\n", done_sn);
-
- while (!predHist.empty() && predHist.back().seqNum <= done_sn) {
- assert(!predHist.empty());
+ DPRINTF(Fetch, "BranchPred: [tid:%i]: Commiting branches until sequence"
+ "number %lli.\n", tid, done_sn);
- // Update the branch predictor with the correct results of branches.
- BP.update(predHist.back().PC, predHist.back().predTaken);
+ while (!predHist[tid].empty() &&
+ predHist[tid].back().seqNum <= done_sn) {
+ // Update the branch predictor with the correct results.
+ BP.update(predHist[tid].back().PC,
+ predHist[tid].back().predTaken);
- predHist.pop_back();
+ predHist[tid].pop_back();
}
}
template <class Impl>
void
-TwobitBPredUnit<Impl>::squash(const InstSeqNum &squashed_sn)
+TwobitBPredUnit<Impl>::squash(const InstSeqNum &squashed_sn, unsigned tid)
{
- while (!predHist.empty() && predHist.front().seqNum > squashed_sn) {
- if (predHist.front().usedRAS) {
- DPRINTF(Fetch, "BranchPred: Restoring top of RAS to: %i, "
- "target: %#x.\n",
- predHist.front().RASIndex,
- predHist.front().RASTarget);
+ History &pred_hist = predHist[tid];
+
+ while (!pred_hist.empty() &&
+ pred_hist.front().seqNum > squashed_sn) {
+ if (pred_hist.front().usedRAS) {
+ DPRINTF(Fetch, "BranchPred: [tid:%i]: Restoring top of RAS to: %i,"
+ " target: %#x.\n",
+ tid,
+ pred_hist.front().RASIndex,
+ pred_hist.front().RASTarget);
+
+ RAS[tid].restore(pred_hist.front().RASIndex,
+ pred_hist.front().RASTarget);
- RAS.restore(predHist.front().RASIndex,
- predHist.front().RASTarget);
- } else if (predHist.front().wasCall) {
- DPRINTF(Fetch, "BranchPred: Removing speculative entry added "
- "to the RAS.\n");
+ } else if (pred_hist.front().wasCall) {
+ DPRINTF(Fetch, "BranchPred: [tid:%i]: Removing speculative entry added "
+ "to the RAS.\n",tid);
- RAS.pop();
+ RAS[tid].pop();
}
- predHist.pop_front();
+ pred_hist.pop_front();
}
+
}
template <class Impl>
void
TwobitBPredUnit<Impl>::squash(const InstSeqNum &squashed_sn,
const Addr &corr_target,
- const bool actually_taken)
+ const bool actually_taken,
+ unsigned tid)
{
// Now that we know that a branch was mispredicted, we need to undo
// all the branches that have been seen up until this branch and
// fix up everything.
+ History &pred_hist = predHist[tid];
+
++condIncorrect;
- DPRINTF(Fetch, "BranchPred: Squashing from sequence number %i, "
+ DPRINTF(Fetch, "BranchPred: [tid:%i]: Squashing from sequence number %i, "
"setting target to %#x.\n",
- squashed_sn, corr_target);
-
- while (!predHist.empty() && predHist.front().seqNum > squashed_sn) {
+ tid, squashed_sn, corr_target);
- if (predHist.front().usedRAS) {
- DPRINTF(Fetch, "BranchPred: Restoring top of RAS to: %i, "
+ while (!pred_hist.empty() &&
+ pred_hist.front().seqNum > squashed_sn) {
+ if (pred_hist.front().usedRAS) {
+ DPRINTF(Fetch, "BranchPred: [tid:%i]: Restoring top of RAS to: %i, "
"target: %#x.\n",
- predHist.front().RASIndex,
- predHist.front().RASTarget);
+ tid,
+ pred_hist.front().RASIndex,
+ pred_hist.front().RASTarget);
- RAS.restore(predHist.front().RASIndex,
- predHist.front().RASTarget);
- } else if (predHist.front().wasCall) {
- DPRINTF(Fetch, "BranchPred: Removing speculative entry added "
- "to the RAS.\n");
+ RAS[tid].restore(pred_hist.front().RASIndex,
+ pred_hist.front().RASTarget);
+ } else if (pred_hist.front().wasCall) {
+ DPRINTF(Fetch, "BranchPred: [tid:%i]: Removing speculative entry"
+ " added to the RAS.\n", tid);
- RAS.pop();
+ RAS[tid].pop();
}
- predHist.pop_front();
+ pred_hist.pop_front();
}
- predHist.front().predTaken = actually_taken;
+ // If there's a squash due to a syscall, there may not be an entry
+ // corresponding to the squash. In that case, don't bother trying to
+ // fix up the entry.
+ if (!pred_hist.empty()) {
+ pred_hist.front().predTaken = actually_taken;
- if (predHist.front().usedRAS) {
- ++RASIncorrect;
- }
+ if (pred_hist.front().usedRAS) {
+ ++RASIncorrect;
+ }
- BP.update(predHist.front().PC, actually_taken);
+ BP.update(pred_hist.front().PC, actually_taken);
- BTB.update(predHist.front().PC, corr_target);
+ BTB.update(pred_hist.front().PC, corr_target, tid);
+ pred_hist.pop_front();
+ }
}