summaryrefslogtreecommitdiff
path: root/cpu/beta_cpu/commit_impl.hh
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2004-10-21 18:02:36 -0400
committerKevin Lim <ktlim@umich.edu>2004-10-21 18:02:36 -0400
commit2fb632dbda1b5db9163322541676cef52a55029f (patch)
tree102f60acd87e237820600070ba485dd6fc14db42 /cpu/beta_cpu/commit_impl.hh
parente3fb9afa79e37cb8c60a48b9ff3976665c2c7675 (diff)
downloadgem5-2fb632dbda1b5db9163322541676cef52a55029f.tar.xz
Check in of various updates to the CPU. Mainly adds in stats, improves
branch prediction, and makes memory dependence work properly. SConscript: Added return address stack, tournament predictor. cpu/base_cpu.cc: Added debug break and print statements. cpu/base_dyn_inst.cc: cpu/base_dyn_inst.hh: Comment out possibly unneeded variables. cpu/beta_cpu/2bit_local_pred.cc: 2bit predictor no longer speculatively updates itself. cpu/beta_cpu/alpha_dyn_inst.hh: Comment formatting. cpu/beta_cpu/alpha_full_cpu.hh: Formatting cpu/beta_cpu/alpha_full_cpu_builder.cc: Added new parameters for branch predictors, and IQ parameters. cpu/beta_cpu/alpha_full_cpu_impl.hh: Register stats. cpu/beta_cpu/alpha_params.hh: Added parameters for IQ, branch predictors, and store sets. cpu/beta_cpu/bpred_unit.cc: Removed one class. cpu/beta_cpu/bpred_unit.hh: Add in RAS, stats. Changed branch predictor unit functionality so that it holds a history of past branches so it can update, and also hold a proper history of the RAS so it can be restored on branch mispredicts. cpu/beta_cpu/bpred_unit_impl.hh: Added in stats, history of branches, RAS. Now bpred unit actually modifies the instruction's predicted next PC. cpu/beta_cpu/btb.cc: Add in sanity checks. cpu/beta_cpu/comm.hh: Add in communication where needed, remove it where it's not. cpu/beta_cpu/commit.hh: cpu/beta_cpu/rename.hh: cpu/beta_cpu/rename_impl.hh: Add in stats. cpu/beta_cpu/commit_impl.hh: Stats, update what is sent back on branch mispredict. cpu/beta_cpu/cpu_policy.hh: Change the bpred unit being used. cpu/beta_cpu/decode.hh: cpu/beta_cpu/decode_impl.hh: Stats. cpu/beta_cpu/fetch.hh: Stats, change squash so it can handle squashes from decode differently than squashes from commit. cpu/beta_cpu/fetch_impl.hh: Add in stats. Change how a cache line is fetched. Update to work with caches. Also have separate functions for different behavior if squash is coming from decode vs commit. cpu/beta_cpu/free_list.hh: Remove some old comments. cpu/beta_cpu/full_cpu.cc: cpu/beta_cpu/full_cpu.hh: Added function to remove instructions from back of instruction list until a certain sequence number. cpu/beta_cpu/iew.hh: Stats, separate squashing behavior due to branches vs memory. cpu/beta_cpu/iew_impl.hh: Stats, separate squashing behavior for branches vs memory. cpu/beta_cpu/inst_queue.cc: Debug stuff cpu/beta_cpu/inst_queue.hh: Stats, change how mem dep unit works, debug stuff cpu/beta_cpu/inst_queue_impl.hh: Stats, change how mem dep unit works, debug stuff. Also add in parameters that used to be hardcoded. cpu/beta_cpu/mem_dep_unit.hh: cpu/beta_cpu/mem_dep_unit_impl.hh: Add in stats, change how memory dependence unit works. It now holds the memory instructions that are waiting for their memory dependences to resolve. It provides which instructions are ready directly to the IQ. cpu/beta_cpu/regfile.hh: Fix up sanity checks. cpu/beta_cpu/rename_map.cc: Fix loop variable type. cpu/beta_cpu/rob_impl.hh: Remove intermediate DynInstPtr cpu/beta_cpu/store_set.cc: Add in debugging statements. cpu/beta_cpu/store_set.hh: Reorder function arguments to match the rest of the calls. --HG-- extra : convert_revision : aabf9b1fecd1d743265dfc3b174d6159937c6f44
Diffstat (limited to 'cpu/beta_cpu/commit_impl.hh')
-rw-r--r--cpu/beta_cpu/commit_impl.hh127
1 files changed, 88 insertions, 39 deletions
diff --git a/cpu/beta_cpu/commit_impl.hh b/cpu/beta_cpu/commit_impl.hh
index 45b8bc7de..9a69c9259 100644
--- a/cpu/beta_cpu/commit_impl.hh
+++ b/cpu/beta_cpu/commit_impl.hh
@@ -23,6 +23,51 @@ SimpleCommit<Impl>::SimpleCommit(Params &params)
template <class Impl>
void
+SimpleCommit<Impl>::regStats()
+{
+ commitCommittedInsts
+ .name(name() + ".commitCommittedInsts")
+ .desc("The number of committed instructions")
+ .prereq(commitCommittedInsts);
+ commitSquashedInsts
+ .name(name() + ".commitSquashedInsts")
+ .desc("The number of squashed insts skipped by commit")
+ .prereq(commitSquashedInsts);
+ commitSquashEvents
+ .name(name() + ".commitSquashEvents")
+ .desc("The number of times commit is told to squash")
+ .prereq(commitSquashEvents);
+ commitNonSpecStalls
+ .name(name() + ".commitNonSpecStalls")
+ .desc("The number of times commit has been forced to stall to "
+ "communicate backwards")
+ .prereq(commitNonSpecStalls);
+ commitCommittedBranches
+ .name(name() + ".commitCommittedBranches")
+ .desc("The number of committed branches")
+ .prereq(commitCommittedBranches);
+ commitCommittedLoads
+ .name(name() + ".commitCommittedLoads")
+ .desc("The number of committed loads")
+ .prereq(commitCommittedLoads);
+ commitCommittedMemRefs
+ .name(name() + ".commitCommittedMemRefs")
+ .desc("The number of committed memory references")
+ .prereq(commitCommittedMemRefs);
+ branchMispredicts
+ .name(name() + ".branchMispredicts")
+ .desc("The number of times a branch was mispredicted")
+ .prereq(branchMispredicts);
+ n_committed_dist
+ .init(0,commitWidth,1)
+ .name(name() + ".COM:committed_per_cycle")
+ .desc("Number of insts commited each cycle")
+ .flags(Stats::pdf)
+ ;
+}
+
+template <class Impl>
+void
SimpleCommit<Impl>::setCPU(FullCPU *cpu_ptr)
{
DPRINTF(Commit, "Commit: Setting CPU pointer.\n");
@@ -143,12 +188,12 @@ SimpleCommit<Impl>::commit()
// Should I also check if the commit stage is telling the ROB to squah?
// This might be necessary to keep the same timing between the IQ and
// the ROB...
- if (robInfoFromIEW->iewInfo.squash) {
+ if (fromIEW->squash) {
DPRINTF(Commit, "Commit: Squashing instructions in the ROB.\n");
_status = ROBSquashing;
- InstSeqNum squashed_inst = robInfoFromIEW->iewInfo.squashedSeqNum;
+ InstSeqNum squashed_inst = fromIEW->squashedSeqNum;
rob->squash(squashed_inst);
@@ -162,15 +207,19 @@ SimpleCommit<Impl>::commit()
// ROB is in the process of squashing.
toIEW->commitInfo.robSquashing = true;
- toIEW->commitInfo.branchMispredict =
- robInfoFromIEW->iewInfo.branchMispredict;
+ toIEW->commitInfo.branchMispredict = fromIEW->branchMispredict;
+
+ toIEW->commitInfo.branchTaken = fromIEW->branchTaken;
+
+ toIEW->commitInfo.nextPC = fromIEW->nextPC;
- toIEW->commitInfo.branchTaken =
- robInfoFromIEW->iewInfo.branchTaken;
+ toIEW->commitInfo.mispredPC = fromIEW->mispredPC;
- toIEW->commitInfo.nextPC = robInfoFromIEW->iewInfo.nextPC;
+ toIEW->commitInfo.globalHist = fromIEW->globalHist;
- toIEW->commitInfo.mispredPC = robInfoFromIEW->iewInfo.mispredPC;
+ if (toIEW->commitInfo.branchMispredict) {
+ ++branchMispredicts;
+ }
}
if (_status != ROBSquashing) {
@@ -237,6 +286,8 @@ SimpleCommit<Impl>::commitInsts()
// inst in the ROB without affecting any other stages.
rob->retireHead();
+ ++commitSquashedInsts;
+
} else {
// Increment the total number of non-speculative instructions
// executed.
@@ -249,7 +300,7 @@ SimpleCommit<Impl>::commitInsts()
bool commit_success = commitHead(head_inst, num_committed);
// Update what instruction we are looking at if the commit worked.
- if(commit_success) {
+ if (commit_success) {
++num_committed;
// Send back which instruction has been committed.
@@ -258,7 +309,11 @@ SimpleCommit<Impl>::commitInsts()
// sequence number instead (copy).
toIEW->commitInfo.doneSeqNum = head_inst->seqNum;
- cpu->instDone();
+ ++commitCommittedInsts;
+
+ if (!head_inst->isNop()) {
+ cpu->instDone();
+ }
} else {
break;
}
@@ -267,6 +322,8 @@ SimpleCommit<Impl>::commitInsts()
// Update the pointer to read the next instruction in the ROB.
head_inst = rob->readHeadInst();
}
+
+ n_committed_dist.sample(num_committed);
}
template <class Impl>
@@ -276,18 +333,13 @@ SimpleCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
// Make sure instruction is valid
assert(head_inst);
- Fault fault = No_Fault;
-
- // If the head instruction is a store or a load, then execute it
- // because this simple model does no speculative memory access.
- // Hopefully this covers all memory references.
- // Also check if it's nonspeculative. Or a nop. Then it will be
- // executed only when it reaches the head of the ROB. Actually
- // executing a nop is a bit overkill...
+ // If the instruction is not executed yet, then it is a non-speculative
+ // or store inst. Signal backwards that it should be executed.
if (!head_inst->isExecuted()) {
// Keep this number correct. We have not yet actually executed
// and committed this instruction.
cpu->funcExeInst--;
+
if (head_inst->isStore() || head_inst->isNonSpeculative()) {
DPRINTF(Commit, "Commit: Encountered a store or non-speculative "
"instruction at the head of the ROB, PC %#x.\n",
@@ -299,6 +351,8 @@ SimpleCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
// it is executed.
head_inst->clearCanCommit();
+ ++commitNonSpecStalls;
+
return false;
} else {
panic("Commit: Trying to commit un-executed instruction "
@@ -306,19 +360,6 @@ SimpleCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
}
}
- // Check if memory access was successful.
- if (fault != No_Fault) {
- // Handle data cache miss here. In the future, set the status
- // to data cache miss, then exit the stage. Have an event
- // that handles commiting the head instruction, then setting
- // the stage back to running, when the event is run. (just
- // make sure that event is commit's run for that cycle)
- panic("Commit: Load/store instruction failed, not sure what "
- "to do.\n");
- // Also will want to clear the instruction's fault after being
- // handled here so it's not handled again below.
- }
-
// Now check if it's one of the special trap or barrier or
// serializing instructions.
if (head_inst->isThreadSync() ||
@@ -335,39 +376,43 @@ SimpleCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
// Check if the instruction caused a fault. If so, trap.
if (head_inst->getFault() != No_Fault) {
+ if (!head_inst->isNop()) {
#ifdef FULL_SYSTEM
- cpu->trap(fault);
+ cpu->trap(fault);
#else // !FULL_SYSTEM
- if (!head_inst->isNop()) {
panic("fault (%d) detected @ PC %08p", head_inst->getFault(),
head_inst->PC);
- }
#endif // FULL_SYSTEM
+ }
}
// Check if we're really ready to commit. If not then return false.
// I'm pretty sure all instructions should be able to commit if they've
// reached this far. For now leave this in as a check.
if(!rob->isHeadReady()) {
- DPRINTF(Commit, "Commit: Unable to commit head instruction!\n");
+ panic("Commit: Unable to commit head instruction!\n");
return false;
}
// If it's a branch, then send back branch prediction update info
// to the fetch stage.
// This should be handled in the iew stage if a mispredict happens...
-#if 0
+
if (head_inst->isControl()) {
+#if 0
toIEW->nextPC = head_inst->readPC();
//Maybe switch over to BTB incorrect.
toIEW->btbMissed = head_inst->btbMiss();
toIEW->target = head_inst->nextPC;
//Maybe also include global history information.
//This simple version will have no branch prediction however.
- }
#endif
+ ++commitCommittedBranches;
+ }
+
+
#if 0
// Check if the instruction has a destination register.
// If so add the previous physical register of its logical register's
@@ -383,8 +428,12 @@ SimpleCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
// the LDSTQ will already have been told that a store has reached the head
// of the ROB. Consider including communication if it's a store as well
// to keep things orthagonal.
- if (head_inst->isLoad()) {
- toIEW->commitInfo.commitIsLoad = true;
+ if (head_inst->isMemRef()) {
+ ++commitCommittedMemRefs;
+ if (head_inst->isLoad()) {
+ toIEW->commitInfo.commitIsLoad = true;
+ ++commitCommittedLoads;
+ }
}
// Now that the instruction is going to be committed, finalize its