X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcpu%2Fo3%2Finst_queue_impl.hh;h=4d99fb520dbfe6f43d3c5e9c55a18388f96f07b0;hb=ec09e5ad6f7c0af6ebb10ee85b326155e2f26cd5;hp=b99bd0900008e0d5a250266eeb2bf72d9bc13297;hpb=ec72f6534c2bb6aada305815fb306680508d7a7c;p=gem5.git diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh index b99bd0900..4d99fb520 100644 --- a/src/cpu/o3/inst_queue_impl.hh +++ b/src/cpu/o3/inst_queue_impl.hh @@ -32,13 +32,11 @@ #include #include -#include "sim/root.hh" +#include "sim/core.hh" #include "cpu/o3/fu_pool.hh" #include "cpu/o3/inst_queue.hh" -using namespace std; - template InstructionQueue::FUCompletion::FUCompletion(DynInstPtr &_inst, int fu_idx, @@ -83,8 +81,6 @@ InstructionQueue::InstructionQueue(Params *params) // Set the number of physical registers as the number of int + float numPhysRegs = numPhysIntRegs + numPhysFloatRegs; - DPRINTF(IQ, "There are %i physical registers.\n", numPhysRegs); - //Create an entry for each physical register within the //dependency graph. dependGraph.resize(numPhysRegs); @@ -100,7 +96,7 @@ InstructionQueue::InstructionQueue(Params *params) resetState(); - string policy = params->smtIQPolicy; + std::string policy = params->smtIQPolicy; //Convert string to lowercase std::transform(policy.begin(), policy.end(), policy.begin(), @@ -126,8 +122,10 @@ InstructionQueue::InstructionQueue(Params *params) maxEntries[i] = part_amt; } +/* DPRINTF(IQ, "IQ sharing policy set to Partitioned:" "%i entries per thread.\n",part_amt); +*/ } else if (policy == "threshold") { iqPolicy = Threshold; @@ -141,8 +139,10 @@ InstructionQueue::InstructionQueue(Params *params) maxEntries[i] = thresholdIQ; } +/* DPRINTF(IQ, "IQ sharing policy set to Threshold:" "%i entries per thread.\n",thresholdIQ); +*/ } else { assert(0 && "Invalid IQ Sharing Policy.Options Are:{Dynamic," "Partitioned, Threshold}"); @@ -232,7 +232,7 @@ InstructionQueue::regStats() .name(name() + ".iqSquashedNonSpecRemoved") .desc("Number of squashed non-spec instructions that were removed") .prereq(iqSquashedNonSpecRemoved); - +/* queueResDist .init(Num_OpClasses, 0, 99, 2) .name(name() + ".IQ:residence:") @@ -242,6 +242,7 @@ InstructionQueue::regStats() for (int i = 0; i < Num_OpClasses; ++i) { queueResDist.subname(i, opClassStrings[i]); } +*/ numIssuedDist .init(0,totalWidth,1) .name(name() + ".ISSUE:issued_per_cycle") @@ -270,7 +271,7 @@ InstructionQueue::regStats() // // How long did instructions for a particular FU type wait prior to issue // - +/* issueDelayDist .init(Num_OpClasses,0,99,2) .name(name() + ".ISSUE:") @@ -279,11 +280,11 @@ InstructionQueue::regStats() ; for (int i=0; i::resetState() template void -InstructionQueue::setActiveThreads(list *at_ptr) +InstructionQueue::setActiveThreads(std::list *at_ptr) { - DPRINTF(IQ, "Setting active threads list pointer.\n"); activeThreads = at_ptr; } @@ -369,15 +369,13 @@ template void InstructionQueue::setIssueToExecuteQueue(TimeBuffer *i2e_ptr) { - DPRINTF(IQ, "Set the issue to execute queue.\n"); - issueToExecuteQueue = i2e_ptr; + issueToExecuteQueue = i2e_ptr; } template void InstructionQueue::setTimeBuffer(TimeBuffer *tb_ptr) { - DPRINTF(IQ, "Set the time buffer.\n"); timeBuffer = tb_ptr; fromCommit = timeBuffer->getWire(-commitToIEWDelay); @@ -387,8 +385,16 @@ template void InstructionQueue::switchOut() { +/* + if (!instList[0].empty() || (numEntries != freeEntries) || + !readyInsts[0].empty() || !nonSpecInsts.empty() || !listOrder.empty()) { + dumpInsts(); +// assert(0); + } +*/ resetState(); dependGraph.reset(); + instsToExecute.clear(); switchedOut = true; for (int i = 0; i < numThreads; ++i) { memDepUnit[i].switchOut(); @@ -419,16 +425,18 @@ void InstructionQueue::resetEntries() { if (iqPolicy != Dynamic || numThreads > 1) { - int active_threads = (*activeThreads).size(); + int active_threads = activeThreads->size(); - list::iterator threads = (*activeThreads).begin(); - list::iterator list_end = (*activeThreads).end(); + std::list::iterator threads = activeThreads->begin(); + std::list::iterator end = activeThreads->end(); + + while (threads != end) { + unsigned tid = *threads++; - while (threads != list_end) { if (iqPolicy == Partitioned) { - maxEntries[*threads++] = numEntries / active_threads; + maxEntries[tid] = numEntries / active_threads; } else if(iqPolicy == Threshold && active_threads == 1) { - maxEntries[*threads++] = numEntries; + maxEntries[tid] = numEntries; } } } @@ -644,9 +652,12 @@ template void InstructionQueue::processFUCompletion(DynInstPtr &inst, int fu_idx) { + DPRINTF(IQ, "Processing FU completion [sn:%lli]\n", inst->seqNum); // The CPU could have been sleeping until this op completed (*extremely* // long latency op). Wake it if it was. This may be overkill. if (isSwitchedOut()) { + DPRINTF(IQ, "FU completion not processed, IQ is switched out [sn:%lli]\n", + inst->seqNum); return; } @@ -687,6 +698,7 @@ InstructionQueue::scheduleReadyInsts() int total_issued = 0; while (total_issued < totalWidth && + iewStage->canIssue() && order_it != order_end_it) { OpClass op_class = (*order_it).queueType; @@ -784,6 +796,7 @@ InstructionQueue::scheduleReadyInsts() listOrder.erase(order_it++); statIssuedInstType[tid][op_class]++; + iewStage->incrWb(issuing_inst->seqNum); } else { statFuBusy[op_class]++; fuBusy[tid]++; @@ -815,6 +828,8 @@ InstructionQueue::scheduleNonSpec(const InstSeqNum &inst) unsigned tid = (*inst_it).second->threadNumber; + (*inst_it).second->setAtCommit(); + (*inst_it).second->setCanIssue(); if (!(*inst_it).second->isMemRef()) { @@ -946,6 +961,8 @@ template void InstructionQueue::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); } @@ -970,7 +987,6 @@ InstructionQueue::completeMemInst(DynInstPtr &completed_inst) completed_inst->memOpDone = true; memDepUnit[tid].completed(completed_inst); - count[tid]--; } @@ -991,7 +1007,11 @@ InstructionQueue::squash(unsigned tid) // Read instruction sequence number of last instruction out of the // time buffer. +#if ISA_HAS_DELAY_SLOT + squashedSeqNum[tid] = fromCommit->commitInfo[tid].bdelayDoneSeqNum; +#else squashedSeqNum[tid] = fromCommit->commitInfo[tid].doneSeqNum; +#endif // Call doSquash if there are insts in the IQ if (count[tid] > 0) { @@ -1032,6 +1052,10 @@ InstructionQueue::doSquash(unsigned tid) (squashed_inst->isMemRef() && !squashed_inst->memOpDone)) { + DPRINTF(IQ, "[tid:%i]: Instruction [sn:%lli] PC %#x " + "squashed.\n", + tid, squashed_inst->seqNum, squashed_inst->readPC()); + // Remove the instruction from the dependency list. if (!squashed_inst->isNonSpeculative() && !squashed_inst->isStoreConditional() && @@ -1062,16 +1086,21 @@ InstructionQueue::doSquash(unsigned tid) ++iqSquashedOperandsExamined; } - } else { + } 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. @@ -1089,10 +1118,6 @@ InstructionQueue::doSquash(unsigned tid) count[squashed_inst->threadNumber]--; ++freeEntries; - - DPRINTF(IQ, "[tid:%i]: Instruction [sn:%lli] PC %#x " - "squashed.\n", - tid, squashed_inst->seqNum, squashed_inst->readPC()); } instList[tid].erase(squash_it--);