From 11bef2ab3811e5c7a65d33ba86718d8c606be87a Mon Sep 17 00:00:00 2001 From: Matt Horsnell Date: Tue, 18 Jan 2011 16:30:05 -0600 Subject: [PATCH] O3: Fix corner cases where multiple squashes/fetch redirects overwrite timebuf. --- src/cpu/o3/iew_impl.hh | 69 +++++++++++++++++++++---------------- src/cpu/o3/lsq_unit_impl.hh | 4 +-- 2 files changed, 42 insertions(+), 31 deletions(-) diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index 0d58357fd..29c6786c0 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -452,20 +452,24 @@ DefaultIEW::squashDueToBranch(DynInstPtr &inst, ThreadID tid) DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %s " "[sn:%i].\n", tid, inst->pcState(), inst->seqNum); - toCommit->squash[tid] = true; - toCommit->squashedSeqNum[tid] = inst->seqNum; - toCommit->mispredPC[tid] = inst->instAddr(); - toCommit->branchMispredict[tid] = true; - toCommit->mispredictInst[tid] = inst; + if (toCommit->squash[tid] == false || + inst->seqNum < toCommit->squashedSeqNum[tid]) { + toCommit->squash[tid] = true; + toCommit->squashedSeqNum[tid] = inst->seqNum; + toCommit->mispredPC[tid] = inst->instAddr(); + toCommit->branchMispredict[tid] = true; + toCommit->branchTaken[tid] = inst->pcState().branching(); - toCommit->branchTaken[tid] = inst->pcState().branching(); - TheISA::PCState pc = inst->pcState(); - TheISA::advancePC(pc, inst->staticInst); - toCommit->pc[tid] = pc; + TheISA::PCState pc = inst->pcState(); + TheISA::advancePC(pc, inst->staticInst); - toCommit->includeSquashInst[tid] = false; + toCommit->pc[tid] = pc; + toCommit->mispredictInst[tid] = inst; + toCommit->includeSquashInst[tid] = false; + + wroteToTimeBuffer = true; + } - wroteToTimeBuffer = true; } template @@ -475,16 +479,19 @@ DefaultIEW::squashDueToMemOrder(DynInstPtr &inst, ThreadID tid) DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, " "PC: %s [sn:%i].\n", tid, inst->pcState(), inst->seqNum); - toCommit->squash[tid] = true; - toCommit->squashedSeqNum[tid] = inst->seqNum; - TheISA::PCState pc = inst->pcState(); - TheISA::advancePC(pc, inst->staticInst); - toCommit->pc[tid] = pc; - toCommit->branchMispredict[tid] = false; + if (toCommit->squash[tid] == false || + inst->seqNum < toCommit->squashedSeqNum[tid]) { + toCommit->squash[tid] = true; + toCommit->squashedSeqNum[tid] = inst->seqNum; + TheISA::PCState pc = inst->pcState(); + TheISA::advancePC(pc, inst->staticInst); + toCommit->pc[tid] = pc; + toCommit->branchMispredict[tid] = false; - toCommit->includeSquashInst[tid] = false; + toCommit->includeSquashInst[tid] = false; - wroteToTimeBuffer = true; + wroteToTimeBuffer = true; + } } template @@ -493,18 +500,21 @@ DefaultIEW::squashDueToMemBlocked(DynInstPtr &inst, ThreadID tid) { DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, " "PC: %s [sn:%i].\n", tid, inst->pcState(), inst->seqNum); + if (toCommit->squash[tid] == false || + inst->seqNum < toCommit->squashedSeqNum[tid]) { + toCommit->squash[tid] = true; - toCommit->squash[tid] = true; - toCommit->squashedSeqNum[tid] = inst->seqNum; - toCommit->pc[tid] = inst->pcState(); - toCommit->branchMispredict[tid] = false; + toCommit->squashedSeqNum[tid] = inst->seqNum; + toCommit->pc[tid] = inst->pcState(); + toCommit->branchMispredict[tid] = false; - // Must include the broadcasted SN in the squash. - toCommit->includeSquashInst[tid] = true; + // Must include the broadcasted SN in the squash. + toCommit->includeSquashInst[tid] = true; - ldstQueue.setLoadBlockedHandled(tid); + ldstQueue.setLoadBlockedHandled(tid); - wroteToTimeBuffer = true; + wroteToTimeBuffer = true; + } } template @@ -788,7 +798,6 @@ DefaultIEW::checkSignalsAndUpdate(ThreadID tid) } dispatchStatus[tid] = Squashing; - fetchRedirect[tid] = false; return; } @@ -797,7 +806,6 @@ DefaultIEW::checkSignalsAndUpdate(ThreadID tid) DPRINTF(IEW, "[tid:%i]: ROB is still squashing.\n", tid); dispatchStatus[tid] = Squashing; - emptyRenameInsts(tid); wroteToTimeBuffer = true; return; @@ -1286,6 +1294,7 @@ DefaultIEW::executeInsts() ThreadID tid = inst->threadNumber; if (!fetchRedirect[tid] || + !toCommit->squash[tid] || toCommit->squashedSeqNum[tid] > inst->seqNum) { if (inst->mispredicted()) { @@ -1382,6 +1391,7 @@ DefaultIEW::executeInsts() // iew queue. That way the writeback event will write into the correct // spot in the queue. wbNumInst = 0; + } template @@ -1596,6 +1606,7 @@ DefaultIEW::checkMisprediction(DynInstPtr &inst) ThreadID tid = inst->threadNumber; if (!fetchRedirect[tid] || + !toCommit->squash[tid] || toCommit->squashedSeqNum[tid] > inst->seqNum) { if (inst->mispredicted()) { diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index 7be5e4e5b..dd3604ffe 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -90,8 +90,8 @@ LSQUnit::completeDataAccess(PacketPtr pkt) { LSQSenderState *state = dynamic_cast(pkt->senderState); DynInstPtr inst = state->inst; - DPRINTF(IEW, "Writeback event [sn:%lli]\n", inst->seqNum); - DPRINTF(Activity, "Activity: Writeback event [sn:%lli]\n", inst->seqNum); + DPRINTF(IEW, "Writeback event [sn:%lli].\n", inst->seqNum); + DPRINTF(Activity, "Activity: Writeback event [sn:%lli].\n", inst->seqNum); //iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum);