summaryrefslogtreecommitdiff
path: root/cpu/o3/iew_impl.hh
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2006-05-19 15:44:03 -0400
committerKevin Lim <ktlim@umich.edu>2006-05-19 15:44:03 -0400
commit5df3e61f168a5dd7d86ba2f81538539622d77bd2 (patch)
tree09303f47fecd95b0aa9cc91d379adf1e2192be1a /cpu/o3/iew_impl.hh
parentc4a87f874a69535f70c0f6f2733ea716e32c70cf (diff)
downloadgem5-5df3e61f168a5dd7d86ba2f81538539622d77bd2.tar.xz
IEW/IQ code cleanup and reorganization.
Dependecy graph code moved into its own class. This requires the changes to the functional units, which is in the next check in. cpu/o3/iew.hh: cpu/o3/iew_impl.hh: IEW and IQ code cleanup and reorganization. cpu/o3/inst_queue.cc: Dependency graph code moved into its own class now. cpu/o3/inst_queue.hh: IEW/IQ code cleanup and reorganization. Dependecy graph code moved into its own class. cpu/o3/inst_queue_impl.hh: IEW/IQ code cleanup and reorganization. Dependecy graph code moved into its own class. Issue loop cleaned up, with completion events for functional units now used more correctly (before they weren't used for multi-cycle ops with pipelined FU's). --HG-- extra : convert_revision : 35e50192df6f71dc81d46a73fdd65f7ec07c10e4
Diffstat (limited to 'cpu/o3/iew_impl.hh')
-rw-r--r--cpu/o3/iew_impl.hh152
1 files changed, 59 insertions, 93 deletions
diff --git a/cpu/o3/iew_impl.hh b/cpu/o3/iew_impl.hh
index cbd7396f7..59f4055a6 100644
--- a/cpu/o3/iew_impl.hh
+++ b/cpu/o3/iew_impl.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -69,7 +69,7 @@ DefaultIEW<Impl>::LdWritebackEvent::process()
if (!inst->isExecuted()) {
inst->setExecuted();
- // Execute again to copy data to proper place.
+ // Complete access to copy data to proper place.
if (inst->isStore()) {
inst->completeAcc();
}
@@ -78,7 +78,6 @@ DefaultIEW<Impl>::LdWritebackEvent::process()
// Need to insert instruction into queue to commit
iewStage->instToCommit(inst);
- //wroteToTimeBuffer = true;
iewStage->activityThisCycle();
inst = NULL;
@@ -93,8 +92,7 @@ DefaultIEW<Impl>::LdWritebackEvent::description()
template<class Impl>
DefaultIEW<Impl>::DefaultIEW(Params *params)
- : // Just make this time buffer really big for now
- // @todo: Make this into a parameter.
+ : // @todo: Make this into a parameter.
issueToExecQueue(5, 5),
instQueue(params),
ldstQueue(params),
@@ -108,7 +106,6 @@ DefaultIEW<Impl>::DefaultIEW(Params *params)
numThreads(params->numberOfThreads),
switchedOut(false)
{
- DPRINTF(IEW, "executeIntWidth: %i.\n", params->executeIntWidth);
_status = Active;
exeStatus = Running;
wbStatus = Idle;
@@ -130,7 +127,6 @@ DefaultIEW<Impl>::DefaultIEW(Params *params)
updateLSQNextCycle = false;
- // @todo: Make into a parameter
skidBufferMax = (3 * (renameToIEWDelay * params->renameWidth)) + issueWidth;
}
@@ -149,8 +145,6 @@ DefaultIEW<Impl>::regStats()
instQueue.regStats();
- //ldstQueue.regStats();
-
iewIdleCycles
.name(name() + ".iewIdleCycles")
.desc("Number of cycles IEW is idle");
@@ -167,8 +161,6 @@ DefaultIEW<Impl>::regStats()
.name(name() + ".iewUnblockCycles")
.desc("Number of cycles IEW is unblocking");
-// iewWBInsts;
-
iewDispatchedInsts
.name(name() + ".iewDispatchedInsts")
.desc("Number of instructions dispatched to IQ");
@@ -206,11 +198,7 @@ DefaultIEW<Impl>::regStats()
.name(name() + ".iewExecLoadInsts")
.desc("Number of load instructions executed")
.flags(total);
-/*
- iewExecStoreInsts
- .name(name() + ".iewExecStoreInsts")
- .desc("Number of store instructions executed");
-*/
+
iewExecSquashedInsts
.name(name() + ".iewExecSquashedInsts")
.desc("Number of squashed instructions skipped in execute");
@@ -233,47 +221,47 @@ DefaultIEW<Impl>::regStats()
branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect;
- exe_swp
+ exeSwp
.init(cpu->number_of_threads)
.name(name() + ".EXEC:swp")
.desc("number of swp insts executed")
.flags(total)
;
- exe_nop
+ exeNop
.init(cpu->number_of_threads)
.name(name() + ".EXEC:nop")
.desc("number of nop insts executed")
.flags(total)
;
- exe_refs
+ exeRefs
.init(cpu->number_of_threads)
.name(name() + ".EXEC:refs")
.desc("number of memory reference insts executed")
.flags(total)
;
- exe_branches
+ exeBranches
.init(cpu->number_of_threads)
.name(name() + ".EXEC:branches")
.desc("Number of branches executed")
.flags(total)
;
- issue_rate
+ issueRate
.name(name() + ".EXEC:rate")
.desc("Inst execution rate")
.flags(total)
;
- issue_rate = iewExecutedInsts / cpu->numCycles;
+ issueRate = iewExecutedInsts / cpu->numCycles;
iewExecStoreInsts
.name(name() + ".EXEC:stores")
.desc("Number of stores executed")
.flags(total)
;
- iewExecStoreInsts = exe_refs - iewExecLoadInsts;
+ iewExecStoreInsts = exeRefs - iewExecLoadInsts;
/*
for (int i=0; i<Num_OpClasses; ++i) {
stringstream subname;
@@ -292,56 +280,56 @@ DefaultIEW<Impl>::regStats()
.flags(total)
;
- writeback_count
+ writebackCount
.init(cpu->number_of_threads)
.name(name() + ".WB:count")
.desc("cumulative count of insts written-back")
.flags(total)
;
- producer_inst
+ producerInst
.init(cpu->number_of_threads)
.name(name() + ".WB:producers")
.desc("num instructions producing a value")
.flags(total)
;
- consumer_inst
+ consumerInst
.init(cpu->number_of_threads)
.name(name() + ".WB:consumers")
.desc("num instructions consuming a value")
.flags(total)
;
- wb_penalized
+ wbPenalized
.init(cpu->number_of_threads)
.name(name() + ".WB:penalized")
.desc("number of instrctions required to write to 'other' IQ")
.flags(total)
;
- wb_penalized_rate
+ wbPenalizedRate
.name(name() + ".WB:penalized_rate")
.desc ("fraction of instructions written-back that wrote to 'other' IQ")
.flags(total)
;
- wb_penalized_rate = wb_penalized / writeback_count;
+ wbPenalizedRate = wbPenalized / writebackCount;
- wb_fanout
+ wbFanout
.name(name() + ".WB:fanout")
.desc("average fanout of values written-back")
.flags(total)
;
- wb_fanout = producer_inst / consumer_inst;
+ wbFanout = producerInst / consumerInst;
- wb_rate
+ wbRate
.name(name() + ".WB:rate")
.desc("insts written-back per cycle")
.flags(total)
;
- wb_rate = writeback_count / cpu->numCycles;
+ wbRate = writebackCount / cpu->numCycles;
}
template<class Impl>
@@ -507,7 +495,7 @@ DefaultIEW<Impl>::squash(unsigned tid)
instQueue.squash(tid);
// Tell the LDSTQ to start squashing.
- ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum,tid);
+ ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
updatedQueues = true;
@@ -543,18 +531,15 @@ DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, unsigned tid)
DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %#x "
"[sn:%i].\n", tid, inst->readPC(), inst->seqNum);
- // Tell rename to squash through the time buffer.
toCommit->squash[tid] = true;
toCommit->squashedSeqNum[tid] = inst->seqNum;
toCommit->mispredPC[tid] = inst->readPC();
toCommit->nextPC[tid] = inst->readNextPC();
toCommit->branchMispredict[tid] = true;
- // Prediction was incorrect, so send back inverse.
toCommit->branchTaken[tid] = inst->readNextPC() !=
(inst->readPC() + sizeof(TheISA::MachInst));
toCommit->includeSquashInst[tid] = false;
- //toCommit->iewSquashNum[tid] = inst->seqNum;
wroteToTimeBuffer = true;
}
@@ -566,13 +551,11 @@ DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid)
DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, "
"PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
- // Tell rename to squash through the time buffer.
toCommit->squash[tid] = true;
toCommit->squashedSeqNum[tid] = inst->seqNum;
toCommit->nextPC[tid] = inst->readNextPC();
toCommit->includeSquashInst[tid] = false;
- //toCommit->iewSquashNum[tid] = inst->seqNum;
wroteToTimeBuffer = true;
}
@@ -611,7 +594,6 @@ DefaultIEW<Impl>::block(unsigned tid)
// reprocessed when this stage unblocks.
skidInsert(tid);
- // Set the status to Blocked.
dispatchStatus[tid] = Blocked;
}
@@ -661,10 +643,7 @@ DefaultIEW<Impl>::instToCommit(DynInstPtr &inst)
// to. If there are free write ports at the time, then go ahead
// and write the instruction to that time. If there are not,
// keep looking back to see where's the first time there's a
- // free slot. What happens if you run out of free spaces?
- // For now naively assume that all instructions take one cycle.
- // Otherwise would have to look into the time buffer based on the
- // latency of the instruction.
+ // free slot.
while ((*iewQueue)[wbCycle].insts[wbNumInst]) {
++wbNumInst;
if (wbNumInst == issueWidth) {
@@ -918,10 +897,10 @@ void
DefaultIEW<Impl>::sortInsts()
{
int insts_from_rename = fromRename->size;
-
+#ifdef DEBUG
for (int i = 0; i < numThreads; i++)
assert(insts[i].empty());
-
+#endif
for (int i = 0; i < insts_from_rename; ++i) {
insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]);
}
@@ -1047,9 +1026,6 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid)
// Be sure to mark these instructions as ready so that the
// commit stage can go ahead and execute them, and mark
// them as issued so the IQ doesn't reprocess them.
- // -------------
- // @TODO: What happens if the ldstqueue is full?
- // Do we process the other instructions?
// Check for squashed instructions.
if (inst->isSquashed()) {
@@ -1125,6 +1101,9 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid)
++iewDispStoreInsts;
if (inst->isNonSpeculative()) {
+ // Non-speculative stores (namely store conditionals)
+ // need to be set as "canCommit()" so that commit can
+ // process them when they reach the head of commit.
inst->setCanCommit();
instQueue.insertNonSpec(inst);
add_to_iq = false;
@@ -1137,6 +1116,7 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid)
toRename->iewInfo[tid].dispatchedToLSQ++;
#if FULL_SYSTEM
} else if (inst->isMemBarrier() || inst->isWriteBarrier()) {
+ // Same as non-speculative stores.
inst->setCanCommit();
instQueue.insertBarrier(inst);
add_to_iq = false;
@@ -1145,7 +1125,7 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid)
DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction "
"encountered, skipping.\n", tid);
- // Same hack as with stores.
+ // Same as non-speculative stores.
inst->setCanCommit();
// Specifically insert it as nonspeculative.
@@ -1162,9 +1142,9 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid)
inst->setExecuted();
inst->setCanCommit();
- instQueue.advanceTail(inst);
+ instQueue.recordProducer(inst);
- exe_nop[tid]++;
+ exeNop[tid]++;
add_to_iq = false;
} else if (inst->isExecuted()) {
@@ -1175,7 +1155,7 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid)
inst->setIssued();
inst->setCanCommit();
- instQueue.advanceTail(inst);
+ instQueue.recordProducer(inst);
add_to_iq = false;
} else {
@@ -1237,7 +1217,6 @@ template <class Impl>
void
DefaultIEW<Impl>::executeInsts()
{
- //bool fetch_redirect[(*activeThreads).size()];
wbNumInst = 0;
wbCycle = 0;
@@ -1254,20 +1233,17 @@ DefaultIEW<Impl>::executeInsts()
// Execute/writeback any instructions that are available.
int inst_num = 0;
- for ( ; inst_num < issueWidth && /* Haven't exceeded issue bandwidth */
- fromIssue->insts[inst_num];
- ++inst_num) {
+ for ( ; inst_num < issueWidth && fromIssue->insts[inst_num];
+ ++inst_num) {
DPRINTF(IEW, "Execute: Executing instructions from IQ.\n");
- // Get instruction from issue's queue.
DynInstPtr inst = fromIssue->insts[inst_num];
DPRINTF(IEW, "Execute: Processing PC %#x, [tid:%i] [sn:%i].\n",
inst->readPC(), inst->threadNumber,inst->seqNum);
// Check if the instruction is squashed; if so then skip it
- // and don't count it towards the FU usage.
if (inst->isSquashed()) {
DPRINTF(IEW, "Execute: Instruction was squashed.\n");
@@ -1299,22 +1275,19 @@ DefaultIEW<Impl>::executeInsts()
// Loads will mark themselves as executed, and their writeback
// event adds the instruction to the queue to commit
fault = ldstQueue.executeLoad(inst);
-
-// ++iewExecLoadInsts;
} else if (inst->isStore()) {
ldstQueue.executeStore(inst);
-// ++iewExecStoreInsts;
-
// If the store had a fault then it may not have a mem req
if (inst->req && !(inst->req->flags & LOCKED)) {
inst->setExecuted();
instToCommit(inst);
}
- // Store conditionals will mark themselves as executed, and
- // their writeback event will add the instruction to the queue
- // to commit.
+
+ // Store conditionals will mark themselves as
+ // executed, and their writeback event will add the
+ // instruction to the queue to commit.
} else {
panic("Unexpected memory type!\n");
}
@@ -1329,10 +1302,9 @@ DefaultIEW<Impl>::executeInsts()
updateExeInstStats(inst);
- // Check if branch was correct. This check happens after the
- // instruction is added to the queue because even if the branch
- // is mispredicted, the branch instruction itself is still valid.
- // Only handle this if there hasn't already been something that
+ // Check if branch prediction was correct, if not then we need
+ // to tell commit to squash in flight instructions. Only
+ // handle this if there hasn't already been something that
// redirects fetch in this group of instructions.
// This probably needs to prioritize the redirects if a different
@@ -1360,7 +1332,8 @@ DefaultIEW<Impl>::executeInsts()
} else if (ldstQueue.violation(tid)) {
fetchRedirect[tid] = true;
- // Get the DynInst that caused the violation. Note that this
+ // If there was an ordering violation, then get the
+ // DynInst that caused the violation. Note that this
// clears the violation signal.
DynInstPtr violator;
violator = ldstQueue.getMemDepViolator(tid);
@@ -1409,13 +1382,11 @@ template <class Impl>
void
DefaultIEW<Impl>::writebackInsts()
{
- // Loop through the head of the time buffer and wake any dependents.
- // These instructions are about to write back. In the simple model
- // this loop can really happen within the previous loop, but when
- // instructions have actual latencies, this loop must be separate.
- // Also mark scoreboard that this instruction is finally complete.
- // Either have IEW have direct access to rename map, or have this as
- // part of backwards communication.
+ // Loop through the head of the time buffer and wake any
+ // dependents. These instructions are about to write back. Also
+ // mark scoreboard that this instruction is finally complete.
+ // Either have IEW have direct access to scoreboard, or have this
+ // as part of backwards communication.
for (int inst_num = 0; inst_num < issueWidth &&
toCommit->insts[inst_num]; inst_num++) {
DynInstPtr inst = toCommit->insts[inst_num];
@@ -1441,9 +1412,9 @@ DefaultIEW<Impl>::writebackInsts()
scoreboard->setReg(inst->renamedDestRegIdx(i));
}
- producer_inst[tid]++;
- consumer_inst[tid]+= dependents;
- writeback_count[tid]++;
+ producerInst[tid]++;
+ consumerInst[tid]+= dependents;
+ writebackCount[tid]++;
}
}
}
@@ -1452,8 +1423,6 @@ template<class Impl>
void
DefaultIEW<Impl>::tick()
{
- // Try to fill up issue queue with as many instructions as bandwidth
- // allows.
wbNumInst = 0;
wbCycle = 0;
@@ -1462,9 +1431,12 @@ DefaultIEW<Impl>::tick()
sortInsts();
+ // Free function units marked as being freed this cycle.
+ fuPool->processFreeUnits();
+
list<unsigned>::iterator threads = (*activeThreads).begin();
- // Check stall and squash signals.
+ // Check stall and squash signals, dispatch any instructions.
while (threads != (*activeThreads).end()) {
unsigned tid = *threads++;
@@ -1472,7 +1444,6 @@ DefaultIEW<Impl>::tick()
checkSignalsAndUpdate(tid);
dispatch(tid);
-
}
if (exeStatus != Squashing) {
@@ -1502,9 +1473,6 @@ DefaultIEW<Impl>::tick()
// Writeback any stores using any leftover bandwidth.
ldstQueue.writebackStores();
- // Free function units marked as being freed this cycle.
- fuPool->processFreeUnits();
-
// Check the committed load/store signals to see if there's a load
// or store to commit. Also check if it's being told to execute a
// nonspeculative instruction.
@@ -1557,8 +1525,6 @@ DefaultIEW<Impl>::tick()
DPRINTF(IEW, "[tid:%i], Dispatch dispatched %i instructions.\n",
tid, toRename->iewInfo[tid].dispatched);
-
- //thread_queue.pop();
}
DPRINTF(IEW, "IQ has %i free entries (Can schedule: %i). "
@@ -1585,7 +1551,7 @@ DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst)
//
#ifdef TARGET_ALPHA
if (inst->isDataPrefetch())
- exe_swp[thread_number]++;
+ exeSwp[thread_number]++;
else
iewExecutedInsts++;
#else
@@ -1596,13 +1562,13 @@ DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst)
// Control operations
//
if (inst->isControl())
- exe_branches[thread_number]++;
+ exeBranches[thread_number]++;
//
// Memory operations
//
if (inst->isMemRef()) {
- exe_refs[thread_number]++;
+ exeRefs[thread_number]++;
if (inst->isLoad()) {
iewExecLoadInsts[thread_number]++;