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

Reply via email to