diff options
-rw-r--r-- | src/cpu/o3/iew_impl.hh | 62 | ||||
-rw-r--r-- | src/cpu/o3/inst_queue_impl.hh | 18 | ||||
-rw-r--r-- | src/cpu/o3/mem_dep_unit_impl.hh | 10 |
3 files changed, 62 insertions, 28 deletions
diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index f24eaf2c4..4883e5a5c 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -1153,19 +1153,6 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid) inst->setCanCommit(); instQueue.insertBarrier(inst); add_to_iq = false; - } else if (inst->isNonSpeculative()) { - DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction " - "encountered, skipping.\n", tid); - - // Same as non-speculative stores. - inst->setCanCommit(); - - // Specifically insert it as nonspeculative. - instQueue.insertNonSpec(inst); - - ++iewDispNonSpecInsts; - - add_to_iq = false; } else if (inst->isNop()) { DPRINTF(IEW, "[tid:%i]: Issue: Nop instruction encountered, " "skipping.\n", tid); @@ -1193,6 +1180,20 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid) } else { add_to_iq = true; } + if (inst->isNonSpeculative()) { + DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction " + "encountered, skipping.\n", tid); + + // Same as non-speculative stores. + inst->setCanCommit(); + + // Specifically insert it as nonspeculative. + instQueue.insertNonSpec(inst); + + ++iewDispNonSpecInsts; + + add_to_iq = false; + } // If the instruction queue is not full, then add the // instruction. @@ -1379,6 +1380,7 @@ DefaultIEW<Impl>::executeInsts() predictedNotTakenIncorrect++; } } else if (ldstQueue.violation(tid)) { + assert(inst->isMemRef()); // If there was an ordering violation, then get the // DynInst that caused the violation. Note that this // clears the violation signal. @@ -1391,10 +1393,10 @@ DefaultIEW<Impl>::executeInsts() // Ensure the violating instruction is older than // current squash - if (fetchRedirect[tid] && - violator->seqNum >= toCommit->squashedSeqNum[tid]) +/* if (fetchRedirect[tid] && + violator->seqNum >= toCommit->squashedSeqNum[tid] + 1) continue; - +*/ fetchRedirect[tid] = true; // Tell the instruction queue that a violation has occured. @@ -1414,6 +1416,33 @@ DefaultIEW<Impl>::executeInsts() squashDueToMemBlocked(inst, tid); } + } else { + // Reset any state associated with redirects that will not + // be used. + if (ldstQueue.violation(tid)) { + assert(inst->isMemRef()); + + DynInstPtr violator = ldstQueue.getMemDepViolator(tid); + + DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: " + "%#x, inst PC: %#x. Addr is: %#x.\n", + violator->readPC(), inst->readPC(), inst->physEffAddr); + DPRINTF(IEW, "Violation will not be handled because " + "already squashing\n"); + + ++memOrderViolationEvents; + } + if (ldstQueue.loadBlocked(tid) && + !ldstQueue.isLoadBlockedHandled(tid)) { + DPRINTF(IEW, "Load operation couldn't execute because the " + "memory system is blocked. PC: %#x [sn:%lli]\n", + inst->readPC(), inst->seqNum); + DPRINTF(IEW, "Blocked load will not be handled because " + "already squashing\n"); + + ldstQueue.setLoadBlockedHandled(tid); + } + } } @@ -1563,6 +1592,7 @@ DefaultIEW<Impl>::tick() //DPRINTF(IEW,"NonspecInst from thread %i",tid); if (fromCommit->commitInfo[tid].uncached) { instQueue.replayMemInst(fromCommit->commitInfo[tid].uncachedLoad); + fromCommit->commitInfo[tid].uncachedLoad->setAtCommit(); } else { instQueue.scheduleNonSpec( fromCommit->commitInfo[tid].nonSpecSeqNum); diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh index 98b8fa900..87bf60dfa 100644 --- a/src/cpu/o3/inst_queue_impl.hh +++ b/src/cpu/o3/inst_queue_impl.hh @@ -829,6 +829,8 @@ InstructionQueue<Impl>::scheduleNonSpec(const InstSeqNum &inst) unsigned tid = (*inst_it).second->threadNumber; + (*inst_it).second->setAtCommit(); + (*inst_it).second->setCanIssue(); if (!(*inst_it).second->isMemRef()) { @@ -960,6 +962,8 @@ template <class Impl> void InstructionQueue<Impl>::rescheduleMemInst(DynInstPtr &resched_inst) { + DPRINTF(IQ, "Rescheduling mem inst [sn:%lli]\n", resched_inst->seqNum); + resched_inst->clearCanIssue(); memDepUnit[resched_inst->threadNumber].reschedule(resched_inst); } @@ -984,7 +988,6 @@ InstructionQueue<Impl>::completeMemInst(DynInstPtr &completed_inst) completed_inst->memOpDone = true; memDepUnit[tid].completed(completed_inst); - count[tid]--; } @@ -1084,16 +1087,21 @@ InstructionQueue<Impl>::doSquash(unsigned tid) ++iqSquashedOperandsExamined; } - } else if (!squashed_inst->isStoreConditional() || !squashed_inst->isCompleted()) { + } else if (!squashed_inst->isStoreConditional() || + !squashed_inst->isCompleted()) { NonSpecMapIt ns_inst_it = nonSpecInsts.find(squashed_inst->seqNum); assert(ns_inst_it != nonSpecInsts.end()); + if (ns_inst_it == nonSpecInsts.end()) { + assert(squashed_inst->getFault() != NoFault); + } else { - (*ns_inst_it).second = NULL; + (*ns_inst_it).second = NULL; - nonSpecInsts.erase(ns_inst_it); + nonSpecInsts.erase(ns_inst_it); - ++iqSquashedNonSpecRemoved; + ++iqSquashedNonSpecRemoved; + } } // Might want to also clear out the head of the dependency graph. diff --git a/src/cpu/o3/mem_dep_unit_impl.hh b/src/cpu/o3/mem_dep_unit_impl.hh index f19980fd5..64558efaa 100644 --- a/src/cpu/o3/mem_dep_unit_impl.hh +++ b/src/cpu/o3/mem_dep_unit_impl.hh @@ -214,6 +214,9 @@ MemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst) inst_entry->regsReady = true; } + // Clear the bit saying this instruction can issue. + inst->clearCanIssue(); + // Add this instruction to the list of dependents. store_entry->dependInsts.push_back(inst_entry); @@ -357,7 +360,6 @@ void MemDepUnit<MemDepPred, Impl>::replay(DynInstPtr &inst) { DynInstPtr temp_inst; - bool found_inst = false; // For now this replay function replays all waiting memory ops. while (!instsToReplay.empty()) { @@ -371,14 +373,8 @@ MemDepUnit<MemDepPred, Impl>::replay(DynInstPtr &inst) moveToReady(inst_entry); - if (temp_inst == inst) { - found_inst = true; - } - instsToReplay.pop_front(); } - - assert(found_inst); } template <class MemDepPred, class Impl> |