inorder: timing for inst forwarding
authorKorey Sewell <ksewell@umich.edu>
Sun, 11 Apr 2010 03:31:36 +0000 (23:31 -0400)
committerKorey Sewell <ksewell@umich.edu>
Sun, 11 Apr 2010 03:31:36 +0000 (23:31 -0400)
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.

src/cpu/inorder/inorder_dyn_inst.cc
src/cpu/inorder/reg_dep_map.cc
src/cpu/inorder/reg_dep_map.hh
src/cpu/inorder/resources/use_def.cc

index 1b55c90e08ac32a5a453f7ad5286041dd99d50cf..83004fdb8b212d2da1ecdd96749f068a7e2010e9 100644 (file)
@@ -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);
 }
 
index 7fac0a90568fa6a4a85787775e845118658a8ad3..cd1c3450c09aba42a9d0101d21106ba55ae4b4cb 100644 (file)
@@ -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 {
-            DPRINTF(RegDepMap, "[sn:%i] Can't get value through forwarding, "
-                    " [sn:%i] has not been executed yet.\n",
-                    inst->seqNum, forward_inst->seqNum);
+            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 {
index cb9d35bf4f014ba62e3b3067b0398ea3dbcb7cc8..2e938a6b532d873434caacb9d678f9fecb3c8532 100644 (file)
@@ -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);
index 5fd6a4724c89f0e69fceafad704726bdebf1bbdd..cf3883e478d7e99ca27283faaf378605f3f12d86 100644 (file)
@@ -196,8 +196,7 @@ UseDefUnit::execute(int slot_idx)
 
             } else {
                 // Look for forwarding opportunities
-                DynInstPtr forward_inst = regDepMap[tid]->canForward(reg_idx, 
-                                                                     ud_idx, 
+                DynInstPtr forward_inst = regDepMap[tid]->canForward(reg_idx,
                                                                      inst);
 
                 if (forward_inst) {