From 71018f5e8b59c359065580a41a96f1a78a88dea9 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 19 Jun 2011 21:43:37 -0400 Subject: [PATCH] inorder: remove stalls on trap squash --- src/cpu/inorder/comm.hh | 20 +++++++++++-- src/cpu/inorder/inorder_dyn_inst.hh | 3 +- src/cpu/inorder/pipeline_stage.cc | 33 +++++++++++++++++++-- src/cpu/inorder/reg_dep_map.cc | 4 +-- src/cpu/inorder/resources/fetch_seq_unit.cc | 15 +++++++++- 5 files changed, 66 insertions(+), 9 deletions(-) diff --git a/src/cpu/inorder/comm.hh b/src/cpu/inorder/comm.hh index b05ec4eff..02a7e9fa4 100644 --- a/src/cpu/inorder/comm.hh +++ b/src/cpu/inorder/comm.hh @@ -55,18 +55,32 @@ struct InterStageStruct { /** Struct that defines all backwards communication. */ struct TimeStruct { - struct stageComm { + struct StageComm { bool squash; InstSeqNum doneSeqNum; bool uncached; ThePipeline::DynInstPtr uncachedLoad; - }; - stageComm stageInfo[ThePipeline::NumStages][ThePipeline::MaxThreads]; + StageComm() + : squash(false), doneSeqNum(0), uncached(false), uncachedLoad(NULL) + { } + }; + StageComm stageInfo[ThePipeline::NumStages][ThePipeline::MaxThreads]; bool stageBlock[ThePipeline::NumStages][ThePipeline::MaxThreads]; bool stageUnblock[ThePipeline::NumStages][ThePipeline::MaxThreads]; + + TimeStruct() + { + for (int i = 0; i < ThePipeline::NumStages; i++) { + for (int j = 0; j < ThePipeline::MaxThreads; j++) { + stageBlock[i][j] = false; + stageUnblock[i][j] = false; + } + } + } + }; #endif //__CPU_INORDER_COMM_HH__ diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh index c2c484074..b374e24a6 100644 --- a/src/cpu/inorder/inorder_dyn_inst.hh +++ b/src/cpu/inorder/inorder_dyn_inst.hh @@ -314,7 +314,8 @@ class InOrderDynInst : public FastAlloc, public RefCounted // BASE INSTRUCTION INFORMATION. // //////////////////////////////////////////////////////////// - std::string instName() { return staticInst->getName(); } + std::string instName() + { return (staticInst) ? staticInst->getName() : "undecoded-inst"; } void setMachInst(ExtMachInst inst); diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc index 2e9ca64e3..e739fd2e6 100644 --- a/src/cpu/inorder/pipeline_stage.cc +++ b/src/cpu/inorder/pipeline_stage.cc @@ -226,6 +226,7 @@ PipelineStage::checkStall(ThreadID tid) const } if (!stalls[tid].resources.empty()) { +#if TRACING_ON string stall_src; for (int i=0; i < stalls[tid].resources.size(); i++) { @@ -234,6 +235,7 @@ PipelineStage::checkStall(ThreadID tid) const DPRINTF(InOrderStage,"[tid:%i]: Stall fom resources (%s) detected.\n", tid, stall_src); +#endif ret_val = true; } @@ -294,8 +296,11 @@ PipelineStage::block(ThreadID tid) stageStatus[tid] = Blocked; - if (prevStageValid) + if (prevStageValid) { + DPRINTF(InOrderStage, "[tid:%d]: Stage %i setting block signal.\n", + tid, stageNum); toPrevStages->stageBlock[stageNum][tid] = true; + } return true; } @@ -323,6 +328,7 @@ PipelineStage::blockDueToBuffer(ThreadID tid) bool PipelineStage::unblock(ThreadID tid) { + // @todo: Shouldnt this be if any available slots are open??? // Stage is done unblocking only if the skid buffer is empty. if (skidBuffer[tid].empty()) { DPRINTF(InOrderStage, "[tid:%u]: Done unblocking.\n", tid); @@ -623,6 +629,13 @@ PipelineStage::readStallSignals(ThreadID tid) for (int stage_idx = stageNum+1; stage_idx <= lastStallingStage[tid]; stage_idx++) { + DPRINTF(InOrderStage, "[tid:%i] Reading stall signals from Stage " + "%i. Block:%i Unblock:%i.\n", + tid, + stage_idx, + fromNextStages->stageBlock[stage_idx][tid], + fromNextStages->stageUnblock[stage_idx][tid]); + // Check for Stage Blocking Signal if (fromNextStages->stageBlock[stage_idx][tid]) { DPRINTF(InOrderStage, "[tid:%i] Stall from stage %i set.\n", tid, @@ -637,6 +650,20 @@ PipelineStage::readStallSignals(ThreadID tid) stalls[tid].stage[stage_idx] = false; } } + + for (int stage_idx = 0; stage_idx < NumStages; + stage_idx++) { + + DPRINTF(InOrderStage, "[tid:%i] Stall signals from Stage " + "%i. Block:%i Unblock:%i...NBlock:%i NUnblock:%i\n", + tid, + stage_idx, + fromNextStages->stageBlock[stage_idx][tid], + fromNextStages->stageUnblock[stage_idx][tid], + toPrevStages->stageBlock[stage_idx][tid], + toPrevStages->stageUnblock[stage_idx][tid]); + } + } @@ -866,7 +893,9 @@ PipelineStage::processInsts(ThreadID tid) inst = insts_to_stage.front(); DPRINTF(InOrderStage, "[tid:%u]: Processing instruction [sn:%lli] " - "with PC %s\n", tid, inst->seqNum, inst->pcState()); + "%s with PC %s\n", tid, inst->seqNum, + inst->instName(), + inst->pcState()); if (inst->isSquashed()) { DPRINTF(InOrderStage, "[tid:%u]: Instruction %i with PC %s is " diff --git a/src/cpu/inorder/reg_dep_map.cc b/src/cpu/inorder/reg_dep_map.cc index 075c31208..2cb6b7adb 100644 --- a/src/cpu/inorder/reg_dep_map.cc +++ b/src/cpu/inorder/reg_dep_map.cc @@ -105,7 +105,7 @@ RegDepMap::insert(DynInstPtr inst) inst->flattenDestReg(i, flat_idx); if (flat_idx == TheISA::ZeroReg) { - DPRINTF(IntRegs, "[sn:%i]: Ignoring Insert-Dependency tracking for " + DPRINTF(RegDepMap, "[sn:%i]: Ignoring Insert-Dependency tracking for " "ISA-ZeroReg (Int. Reg %i).\n", inst->seqNum, flat_idx); continue; @@ -145,7 +145,7 @@ RegDepMap::remove(DynInstPtr inst) RegIndex flat_idx = inst->flattenedDestRegIdx(i); if (flat_idx == TheISA::ZeroReg) { - DPRINTF(IntRegs, "[sn:%i]: Ignoring Remove-Dependency tracking for " + DPRINTF(RegDepMap, "[sn:%i]: Ignoring Remove-Dependency tracking for " "ISA-ZeroReg (Int. Reg %i).\n", inst->seqNum, flat_idx); continue; diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc index 5d90f71d3..072ecb76f 100644 --- a/src/cpu/inorder/resources/fetch_seq_unit.cc +++ b/src/cpu/inorder/resources/fetch_seq_unit.cc @@ -116,6 +116,9 @@ FetchSeqUnit::execute(int slot_num) // If it's a return, then we must wait for resolved address. // The Predictor will mark a return a false as "not taken" // if there is no RAS entry + DPRINTF(InOrderFetchSeq, "[tid:%d]: Setting block signal " + "for stage %i.\n", + tid, stage_num); cpu->pipelineStage[stage_num]-> toPrevStages->stageBlock[stage_num][tid] = true; pcValid[tid] = false; @@ -215,8 +218,16 @@ FetchSeqUnit::squash(DynInstPtr inst, int squash_stage, // Unblock Any Stages Waiting for this information to be updated ... if (!pcValid[tid]) { + DPRINTF(InOrderFetchSeq, "[tid:%d]: Setting unblock signal " + "for stage %i.\n", + tid, pcBlockStage[tid]); + + // Need to use "fromNextStages" instead of "toPrevStages" + // because the timebuffer will have already have advanced + // in the tick function and this squash function will happen after + // the tick cpu->pipelineStage[pcBlockStage[tid]]-> - toPrevStages->stageUnblock[pcBlockStage[tid]][tid] = true; + fromNextStages->stageUnblock[pcBlockStage[tid]][tid] = true; } pcValid[tid] = true; @@ -291,6 +302,8 @@ FetchSeqUnit::trap(Fault fault, ThreadID tid, DynInstPtr inst) "%s.\n", tid, pc[tid]); DPRINTF(InOrderFetchSeq, "[tid:%i]: Trap updating to PC: " "%s.\n", tid, pc[tid]); + + cpu->removePipelineStalls(tid); } void -- 2.30.2