changeset 8ae78a9733b0 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=8ae78a9733b0
description:
inorder: track last branch committed
when threads are switching in/out the CPU, we need to keep
track of special cases like branches. Add appropriate
variables in ThreadState t track this and then use
these variables when updating pc after context switch
diffstat:
4 files changed, 51 insertions(+), 24 deletions(-)
src/cpu/inorder/cpu.cc | 27 +++++++++++++++++----------
src/cpu/inorder/pipeline_stage.cc | 9 ++++++---
src/cpu/inorder/resources/fetch_seq_unit.cc | 26 +++++++++++++++++++-------
src/cpu/inorder/thread_state.hh | 13 +++++++++----
diffs (166 lines):
diff -r 0b8c6a579218 -r 8ae78a9733b0 src/cpu/inorder/cpu.cc
--- a/src/cpu/inorder/cpu.cc Sun Jan 31 18:27:49 2010 -0500
+++ b/src/cpu/inorder/cpu.cc Sun Jan 31 18:27:58 2010 -0500
@@ -709,7 +709,9 @@
activeThreads.push_back(tid);
activateThreadInPipeline(tid);
-
+
+ thread[tid]->lastActivate = curTick;
+
wakeCPU();
}
}
@@ -888,6 +890,7 @@
DPRINTF(InOrderCPU, "[tid: %i]: Placing on Suspended Threads List...\n",
tid);
deactivateThread(tid);
suspendedThreads.push_back(tid);
+ thread[tid]->lastSuspend = curTick;
}
void
@@ -1063,15 +1066,22 @@
InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
{
// Set the CPU's PCs - This contributes to the precise state of the CPU
- // which can be used when restoring a thread to the CPU after a fork or
- // after an exception
- // =================
- // @TODO: Set-Up Grad-Info/Committed-Info to let ThreadState know if
- // it's a branch or not
+ // which can be used when restoring a thread to the CPU after after any
+ // type of context switching activity (fork, exception, etc.)
setPC(inst->readPC(), tid);
setNextPC(inst->readNextPC(), tid);
setNextNPC(inst->readNextNPC(), tid);
+ if (inst->isControl()) {
+ thread[tid]->lastGradIsBranch = true;
+ thread[tid]->lastBranchPC = inst->readPC();
+ thread[tid]->lastBranchNextPC = inst->readNextPC();
+ thread[tid]->lastBranchNextNPC = inst->readNextNPC();
+ } else {
+ thread[tid]->lastGradIsBranch = false;
+ }
+
+
// Finalize Trace Data For Instruction
if (inst->traceData) {
//inst->traceData->setCycle(curTick);
@@ -1082,9 +1092,6 @@
inst->traceData = NULL;
}
- // Set Last Graduated Instruction In Thread State
- //thread[tid]->lastGradInst = inst;
-
// Increment thread-state's instruction count
thread[tid]->numInst++;
@@ -1108,7 +1115,7 @@
// Broadcast to other resources an instruction
// has been completed
resPool->scheduleEvent((CPUEventType)ResourcePool::InstGraduated, inst,
- tid);
+ 0, 0, tid);
// Finally, remove instruction from CPU
removeInst(inst);
diff -r 0b8c6a579218 -r 8ae78a9733b0 src/cpu/inorder/pipeline_stage.cc
--- a/src/cpu/inorder/pipeline_stage.cc Sun Jan 31 18:27:49 2010 -0500
+++ b/src/cpu/inorder/pipeline_stage.cc Sun Jan 31 18:27:58 2010 -0500
@@ -568,15 +568,18 @@
} else {
DynInstPtr inst = switchedOutBuffer[tid];
- DPRINTF(InOrderStage,"[tid:%i]: Re-Inserting [sn:%lli] PC:%#x into
stage skidBuffer %i\n",
- tid, inst->seqNum, inst->readPC(), inst->threadNumber);
+ DPRINTF(InOrderStage,"[tid:%i]: Re-Inserting [sn:%lli] PC:%#x into
"
+ "stage skidBuffer %i\n", tid, inst->seqNum,
+ inst->readPC(), inst->threadNumber);
// Make instruction available for pipeline processing
skidBuffer[tid].push(inst);
// Update PC so that we start fetching after this instruction to
prevent
// "double"-execution of instructions
-
cpu->resPool->scheduleEvent((InOrderCPU::CPUEventType)ResourcePool::UpdateAfterContextSwitch,
inst, 0, 0, tid);
+ cpu->resPool->scheduleEvent((InOrderCPU::CPUEventType)
+
ResourcePool::UpdateAfterContextSwitch,
+ inst, 0, 0, tid);
// Clear switchout buffer
switchedOutBuffer[tid] = NULL;
diff -r 0b8c6a579218 -r 8ae78a9733b0 src/cpu/inorder/resources/fetch_seq_unit.cc
--- a/src/cpu/inorder/resources/fetch_seq_unit.cc Sun Jan 31 18:27:49
2010 -0500
+++ b/src/cpu/inorder/resources/fetch_seq_unit.cc Sun Jan 31 18:27:58
2010 -0500
@@ -348,11 +348,23 @@
{
pcValid[tid] = true;
- PC[tid] = inst->readNextPC();
- nextPC[tid] = inst->readNextNPC();
- nextNPC[tid] = inst->readNextNPC() + instSize;
-
-
- DPRINTF(InOrderFetchSeq, "[tid:%i]: Updating PC:%08p NPC:%08p
NNPC:%08p.\n",
- tid, PC[tid], nextPC[tid], nextNPC[tid]);
+ if (cpu->thread[tid]->lastGradIsBranch) {
+ /** This function assumes that the instruction causing the context
+ * switch was right after the branch. Thus, if it's not, then
+ * we are updating incorrectly here
+ */
+ assert(cpu->thread[tid]->lastBranchNextPC == inst->readPC());
+
+ PC[tid] = cpu->thread[tid]->lastBranchNextNPC;
+ nextPC[tid] = PC[tid] + instSize;
+ nextNPC[tid] = nextPC[tid] + instSize;
+ } else {
+ PC[tid] = inst->readNextPC();
+ nextPC[tid] = inst->readNextNPC();
+ nextNPC[tid] = inst->readNextNPC() + instSize;
+ }
+
+ DPRINTF(InOrderFetchSeq, "[tid:%i]: Updating PCs due to Context Switch."
+ "Assigning PC:%08p NPC:%08p NNPC:%08p.\n", tid, PC[tid],
+ nextPC[tid], nextNPC[tid]);
}
diff -r 0b8c6a579218 -r 8ae78a9733b0 src/cpu/inorder/thread_state.hh
--- a/src/cpu/inorder/thread_state.hh Sun Jan 31 18:27:49 2010 -0500
+++ b/src/cpu/inorder/thread_state.hh Sun Jan 31 18:27:58 2010 -0500
@@ -79,14 +79,14 @@
#if FULL_SYSTEM
InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num)
: ThreadState(reinterpret_cast<BaseCPU*>(_cpu), _thread_num),
- cpu(_cpu), inSyscall(0), trapPending(0)
+ cpu(_cpu), inSyscall(0), trapPending(0), lastGradIsBranch(false)
{ }
#else
InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num,
Process *_process)
: ThreadState(reinterpret_cast<BaseCPU*>(_cpu), _thread_num,
_process),
- cpu(_cpu), inSyscall(0), trapPending(0)
+ cpu(_cpu), inSyscall(0), trapPending(0), lastGradIsBranch(false)
{ }
#endif
@@ -105,10 +105,15 @@
/** Returns a pointer to the TC of this thread. */
ThreadContext *getTC() { return tc; }
+ /** Return the thread id */
int readTid() { return threadId(); }
- /** Pointer to the last graduated instruction in the thread */
- //DynInstPtr lastGradInst;
+
+ /** Is last instruction graduated a branch? */
+ bool lastGradIsBranch;
+ Addr lastBranchPC;
+ Addr lastBranchNextPC;
+ Addr lastBranchNextNPC;
};
#endif // __CPU_INORDER_THREAD_STATE_HH__
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev