inorder: timing for inst forwarding
when insts execute, they mark the time they finish to be used for subsequent isnts they may need forwarding of data. However, the regdepmap was using the wrong value to index into the destination operands of the instruction to be forwarded. Thus, in some cases, we are checking to see if the 3rd destination register for an instruction is executed at a certain time, when there is only 1 dest. register valid. Thus, we get a bad, uninitialized time value that will stall forwarding causing performance loss but still the correct execution.
This commit is contained in:
parent
d71f9712b3
commit
b49511ae48
4 changed files with 30 additions and 10 deletions
|
@ -534,6 +534,10 @@ InOrderDynInst::setIntRegOperand(const StaticInst *si, int idx, IntReg val)
|
|||
instResult[idx].type = Integer;
|
||||
instResult[idx].val.integer = val;
|
||||
instResult[idx].tick = curTick;
|
||||
|
||||
DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting Result Int Reg. %i "
|
||||
"being set to %#x (result-tick:%i).\n",
|
||||
threadNumber, seqNum, idx, val, instResult[idx].tick);
|
||||
}
|
||||
|
||||
/** Sets a FP register. */
|
||||
|
@ -542,8 +546,11 @@ InOrderDynInst::setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
|
|||
{
|
||||
instResult[idx].val.dbl = val;
|
||||
instResult[idx].type = Float;
|
||||
|
||||
instResult[idx].tick = curTick;
|
||||
|
||||
DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting Result Float Reg. %i "
|
||||
"being set to %#x (result-tick:%i).\n",
|
||||
threadNumber, seqNum, idx, val, instResult[idx].tick);
|
||||
}
|
||||
|
||||
/** Sets a FP register as a integer. */
|
||||
|
@ -554,6 +561,10 @@ InOrderDynInst::setFloatRegOperandBits(const StaticInst *si, int idx,
|
|||
instResult[idx].type = Integer;
|
||||
instResult[idx].val.integer = val;
|
||||
instResult[idx].tick = curTick;
|
||||
|
||||
DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting Result Float Reg. %i "
|
||||
"being set to %#x (result-tick:%i).\n",
|
||||
threadNumber, seqNum, idx, val, instResult[idx].tick);
|
||||
}
|
||||
|
||||
/** Sets a misc. register. */
|
||||
|
@ -655,7 +666,7 @@ InOrderDynInst::write(T data, Addr addr, unsigned flags, uint64_t *res)
|
|||
storeData = data;
|
||||
|
||||
DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting store data to %#x.\n",
|
||||
threadNumber, seqNum, memData);
|
||||
threadNumber, seqNum, storeData);
|
||||
return cpu->write(this, data, addr, flags, res);
|
||||
}
|
||||
|
||||
|
|
|
@ -161,7 +161,7 @@ RegDepMap::canRead(unsigned idx, DynInstPtr inst)
|
|||
}
|
||||
|
||||
ThePipeline::DynInstPtr
|
||||
RegDepMap::canForward(unsigned reg_idx, unsigned src_idx, DynInstPtr inst)
|
||||
RegDepMap::canForward(unsigned reg_idx, DynInstPtr inst)
|
||||
{
|
||||
std::list<DynInstPtr>::iterator list_it = regMap[reg_idx].begin();
|
||||
std::list<DynInstPtr>::iterator list_end = regMap[reg_idx].end();
|
||||
|
@ -176,13 +176,23 @@ RegDepMap::canForward(unsigned reg_idx, unsigned src_idx, DynInstPtr inst)
|
|||
}
|
||||
|
||||
if (forward_inst) {
|
||||
int dest_reg_idx = forward_inst->getDestIdxNum(reg_idx);
|
||||
assert(dest_reg_idx != -1);
|
||||
|
||||
if (forward_inst->isExecuted() &&
|
||||
forward_inst->readResultTime(src_idx) < curTick) {
|
||||
forward_inst->readResultTime(dest_reg_idx) < curTick) {
|
||||
return forward_inst;
|
||||
} else {
|
||||
if (!forward_inst->isExecuted()) {
|
||||
DPRINTF(RegDepMap, "[sn:%i] Can't get value through forwarding, "
|
||||
" [sn:%i] has not been executed yet.\n",
|
||||
inst->seqNum, forward_inst->seqNum);
|
||||
} else if (forward_inst->readResultTime(dest_reg_idx) >= curTick) {
|
||||
DPRINTF(RegDepMap, "[sn:%i] Can't get value through forwarding, "
|
||||
" [sn:%i] executed on tick:%i.\n",
|
||||
inst->seqNum, forward_inst->seqNum, forward_inst->readResultTime(dest_reg_idx));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -77,7 +77,7 @@ class RegDepMap
|
|||
|
||||
/** Is the current instruction able to get a forwarded value from another instruction
|
||||
* for this destination register? */
|
||||
DynInstPtr canForward(unsigned reg_idx, unsigned src_idx, DynInstPtr inst);
|
||||
DynInstPtr canForward(unsigned reg_idx, DynInstPtr inst);
|
||||
|
||||
/** find an instruction to forward/bypass a value from */
|
||||
DynInstPtr findBypassInst(unsigned idx);
|
||||
|
|
|
@ -197,7 +197,6 @@ UseDefUnit::execute(int slot_idx)
|
|||
} else {
|
||||
// Look for forwarding opportunities
|
||||
DynInstPtr forward_inst = regDepMap[tid]->canForward(reg_idx,
|
||||
ud_idx,
|
||||
inst);
|
||||
|
||||
if (forward_inst) {
|
||||
|
|
Loading…
Reference in a new issue