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
This commit is contained in:
parent
aacc5cb205
commit
069b38c0d5
4 changed files with 51 additions and 24 deletions
|
@ -709,7 +709,9 @@ InOrderCPU::activateThread(ThreadID tid)
|
|||
activeThreads.push_back(tid);
|
||||
|
||||
activateThreadInPipeline(tid);
|
||||
|
||||
|
||||
thread[tid]->lastActivate = curTick;
|
||||
|
||||
wakeCPU();
|
||||
}
|
||||
}
|
||||
|
@ -888,6 +890,7 @@ InOrderCPU::suspendThread(ThreadID tid)
|
|||
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 @@ void
|
|||
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 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
|
|||
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 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
|
|||
// 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);
|
||||
|
|
|
@ -568,15 +568,18 @@ PipelineStage::activateThread(ThreadID tid)
|
|||
} 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;
|
||||
|
|
|
@ -348,11 +348,23 @@ FetchSeqUnit::updateAfterContextSwitch(DynInstPtr inst, ThreadID tid)
|
|||
{
|
||||
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]);
|
||||
}
|
||||
|
|
|
@ -79,14 +79,14 @@ class InOrderThreadState : public ThreadState {
|
|||
#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 @@ class InOrderThreadState : public ThreadState {
|
|||
/** 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__
|
||||
|
|
Loading…
Reference in a new issue