changeset b085f409d89c in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=b085f409d89c
description:
        inorder: use setupSquash for misspeculation
        implement a clean interface to handle branch misprediction and 
eventually all pipeline
        flushing

diffstat:

 src/cpu/inorder/cpu.cc                        |   18 ++++
 src/cpu/inorder/cpu.hh                        |    3 +
 src/cpu/inorder/inorder_dyn_inst.cc           |   22 +++++
 src/cpu/inorder/inorder_dyn_inst.hh           |    2 +
 src/cpu/inorder/resource.cc                   |   13 +++
 src/cpu/inorder/resource.hh                   |    4 +
 src/cpu/inorder/resources/branch_predictor.cc |   14 +--
 src/cpu/inorder/resources/execution_unit.cc   |   94 ++++-----------------
 src/cpu/inorder/resources/fetch_seq_unit.cc   |  110 +++++++++++--------------
 9 files changed, 134 insertions(+), 146 deletions(-)

diffs (truncated from 446 to 300 lines):

diff -r 18173b099ed1 -r b085f409d89c src/cpu/inorder/cpu.cc
--- a/src/cpu/inorder/cpu.cc    Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/cpu.cc    Sun Jun 19 21:43:35 2011 -0400
@@ -1272,6 +1272,24 @@
     return --(instList[tid].end());
 }
 
+InOrderCPU::ListIt
+InOrderCPU::findInst(InstSeqNum seq_num, ThreadID tid)
+{
+    ListIt it = instList[tid].begin();
+    ListIt end = instList[tid].end();
+
+    while (it != end) {
+        if ((*it)->seqNum == seq_num)
+            return it;
+        else if ((*it)->seqNum > seq_num)
+            break;
+
+        it++;
+    }
+
+    return instList[tid].end();
+}
+
 void 
 InOrderCPU::updateContextSwitchStats()
 {
diff -r 18173b099ed1 -r b085f409d89c src/cpu/inorder/cpu.hh
--- a/src/cpu/inorder/cpu.hh    Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/cpu.hh    Sun Jun 19 21:43:35 2011 -0400
@@ -581,6 +581,9 @@
      */
     ListIt addInst(DynInstPtr inst);
 
+    /** Find instruction on instruction list */
+    ListIt findInst(InstSeqNum seq_num, ThreadID tid);
+
     /** Function to tell the CPU that an instruction has completed. */
     void instDone(DynInstPtr inst, ThreadID tid);
 
diff -r 18173b099ed1 -r b085f409d89c src/cpu/inorder/inorder_dyn_inst.cc
--- a/src/cpu/inorder/inorder_dyn_inst.cc       Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/inorder_dyn_inst.cc       Sun Jun 19 21:43:35 2011 -0400
@@ -316,6 +316,28 @@
 #endif
 
 void
+InOrderDynInst::setSquashInfo(unsigned stage_num)
+{
+    squashingStage = stage_num;
+    bdelaySeqNum = seqNum;
+
+#if ISA_HAS_DELAY_SLOT
+    if (isControl()) {
+        TheISA::PCState nextPC = pc;
+        TheISA::advancePC(nextPC, staticInst);
+
+        // Check to see if we should squash after the
+        // branch or after a branch delay slot.
+        if (pc.nextInstAddr() == pc.instAddr() + sizeof(MachInst))
+            bdelaySeqNum = seqNum + 1;
+        else
+            bdelaySeqNum = seqNum;
+
+    }
+#endif
+}
+
+void
 InOrderDynInst::releaseReq(ResourceRequest* req)
 {
     std::list<ResourceRequest*>::iterator list_it = reqList.begin();
diff -r 18173b099ed1 -r b085f409d89c src/cpu/inorder/inorder_dyn_inst.hh
--- a/src/cpu/inorder/inorder_dyn_inst.hh       Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/inorder_dyn_inst.hh       Sun Jun 19 21:43:35 2011 -0400
@@ -576,6 +576,8 @@
 
     bool procDelaySlotOnMispred;
 
+    void setSquashInfo(unsigned stage_num);
+
     ////////////////////////////////////////////
     //
     // MEMORY ACCESS
diff -r 18173b099ed1 -r b085f409d89c src/cpu/inorder/resource.cc
--- a/src/cpu/inorder/resource.cc       Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/resource.cc       Sun Jun 19 21:43:35 2011 -0400
@@ -35,6 +35,7 @@
 #include "base/str.hh"
 #include "cpu/inorder/cpu.hh"
 #include "cpu/inorder/resource.hh"
+#include "cpu/inorder/resource_pool.hh"
 #include "debug/RefCount.hh"
 #include "debug/ResReqCount.hh"
 #include "debug/Resource.hh"
@@ -287,6 +288,18 @@
 }
 
 void
+Resource::setupSquash(DynInstPtr inst, int stage_num, ThreadID tid)
+{
+    assert(inst->isControl() && "Function Assumes Squash From A Branch");
+
+    // Squash In Pipeline Stage
+    cpu->pipelineStage[stage_num]->squashDueToBranch(inst, tid);
+
+    // Schedule Squash Through-out Resource Pool
+    cpu->resPool->scheduleEvent(
+        (InOrderCPU::CPUEventType)ResourcePool::SquashAll, inst, 0);
+}
+void
 Resource::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
                  ThreadID tid)
 {
diff -r 18173b099ed1 -r b085f409d89c src/cpu/inorder/resource.hh
--- a/src/cpu/inorder/resource.hh       Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/resource.hh       Sun Jun 19 21:43:35 2011 -0400
@@ -154,10 +154,14 @@
     virtual Fault doCacheAccess(DynInstPtr inst, uint64_t *res=NULL)
     { panic("doCacheAccess undefined for %s", name()); return NoFault; }
 
+    /** Setup Squash to be sent out to pipeline and resource pool */
+    void setupSquash(DynInstPtr inst, int stage_num, ThreadID tid);
+
     /** Squash All Requests After This Seq Num */
     virtual void squash(DynInstPtr inst, int stage_num,
                         InstSeqNum squash_seq_num, ThreadID tid);
 
+    /** Squash Requests Due to a Memory Stall (By Default, same as "squash" */
     virtual void squashDueToMemStall(DynInstPtr inst, int stage_num,
                                      InstSeqNum squash_seq_num, ThreadID tid);
 
diff -r 18173b099ed1 -r b085f409d89c 
src/cpu/inorder/resources/branch_predictor.cc
--- a/src/cpu/inorder/resources/branch_predictor.cc     Sun Jun 19 21:43:35 
2011 -0400
+++ b/src/cpu/inorder/resources/branch_predictor.cc     Sun Jun 19 21:43:35 
2011 -0400
@@ -148,19 +148,15 @@
 BranchPredictor::squash(DynInstPtr inst, int squash_stage,
                         InstSeqNum squash_seq_num, ThreadID tid)
 {
-    DPRINTF(InOrderBPred, "[tid:%i][sn:%i] Squashing...\n", tid, inst->seqNum);
-
-#if ISA_HAS_DELAY_SLOT
-    // We need to squash the actual branch , NOT the delay slot
-    // in the branch predictor
-    //squash_seq_num = squash_seq_num - 1;
-#endif
+    InstSeqNum bpred_squash_num = inst->seqNum;
+    DPRINTF(InOrderBPred, "[tid:%i][sn:%i] Squashing...\n", tid,
+            bpred_squash_num);
 
     if (squash_stage >= ThePipeline::BackEndStartStage) {
         bool taken = inst->predTaken();
-        branchPred.squash(squash_seq_num, inst->readPredTarg(), taken, tid);
+        branchPred.squash(bpred_squash_num, inst->readPredTarg(), taken, tid);
     } else {
-        branchPred.squash(squash_seq_num, tid);
+        branchPred.squash(bpred_squash_num, tid);
     }
 }
 
diff -r 18173b099ed1 -r b085f409d89c src/cpu/inorder/resources/execution_unit.cc
--- a/src/cpu/inorder/resources/execution_unit.cc       Sun Jun 19 21:43:35 
2011 -0400
+++ b/src/cpu/inorder/resources/execution_unit.cc       Sun Jun 19 21:43:35 
2011 -0400
@@ -143,87 +143,30 @@
                 inst->setExecuted();
 
                 if (fault == NoFault) {
-                    // If branch is mispredicted, then signal squash
-                    // throughout all stages behind the pipeline stage
-                    // that got squashed.
                     if (inst->mispredicted()) {
-                        int stage_num = exec_req->getStageNum();
+                        assert(inst->isControl());
+
+                        // Set up Squash Generated By this Misprediction
+                        unsigned stage_num = exec_req->getStageNum();
                         ThreadID tid = inst->readTid();
-                        // If it's a branch ...
-                        if (inst->isDirectCtrl()) {
-                            assert(!inst->isIndirectCtrl());
+                        TheISA::PCState pc = inst->pcState();
+                        TheISA::advancePC(pc, inst->staticInst);
+                        inst->setPredTarg(pc);
+                        inst->setSquashInfo(stage_num);
 
-                            TheISA::PCState pc = inst->pcState();
-                            TheISA::advancePC(pc, inst->staticInst);
-                            inst->setPredTarg(pc);
+                        setupSquash(inst, stage_num, tid);
 
-                            if (inst->predTaken() && inst->isCondDelaySlot()) {
-                                assert(0 && "Not Handling Conditional Delay 
Slots (1)");
-                                inst->bdelaySeqNum = seq_num;
-                                DPRINTF(InOrderExecute, "[tid:%i]: Conditional"
-                                        " branch inst [sn:%i] PC %s mis"
-                                        "predicted as taken.\n", tid,
-                                        seq_num, inst->pcState());
-                            } else if (!inst->predTaken() && 
inst->isCondDelaySlot()) {
-                                assert(0 && "Not Handling Conditional Delay 
Slots (2)");
-                                inst->bdelaySeqNum = seq_num;
-                                inst->procDelaySlotOnMispred = true;
-
-                                DPRINTF(InOrderExecute, "[tid:%i]: Conditional"
-                                        " branch inst [sn:%i] PC %s mis"
-                                        "predicted as not taken.\n", tid,
-                                        seq_num, inst->pcState());
-                            } else {
-                                inst->bdelaySeqNum = seq_num;
-
-                                DPRINTF(InOrderExecute, "[tid:%i]: "
-                                        "Misprediction detected at "
-                                        "[sn:%i] PC %s,\n\t squashing after "
-                                        "delay slot instruction [sn:%i].\n",
-                                        tid, seq_num, inst->pcState(),
-                                        inst->bdelaySeqNum);
-                                DPRINTF(InOrderStall, "STALL: [tid:%i]: Branch"
-                                        " misprediction at %s\n",
-                                        tid, inst->pcState());
-                            }
-
-                            DPRINTF(InOrderExecute, "[tid:%i] Redirecting "
-                                    "fetch to %s.\n", tid,
-                                    inst->readPredTarg());
-
-                        } else if (inst->isIndirectCtrl()){
-                            TheISA::PCState pc = inst->pcState();
-                            TheISA::advancePC(pc, inst->staticInst);
-                            inst->seqNum = seq_num;
-                            inst->setPredTarg(pc);
-
-                            inst->bdelaySeqNum = seq_num;
-
-                            DPRINTF(InOrderExecute, "[tid:%i] Redirecting"
-                                    " fetch to %s.\n", tid,
-                                    inst->readPredTarg());
-                        } else {
-                            panic("Non-control instruction (%s) mispredict"
-                                  "ing?!!", inst->staticInst->getName());
-                        }
-
-                        DPRINTF(InOrderExecute, "[tid:%i] Squashing will "
-                                "start from stage %i.\n", tid, stage_num);
-
-                        cpu->pipelineStage[stage_num]->squashDueToBranch(inst,
-                                                                         tid);
-
-                        inst->squashingStage = stage_num;
-
-                        // Squash throughout other resources
-                        cpu->resPool->scheduleEvent((InOrderCPU::CPUEventType)
-                                                    ResourcePool::SquashAll,
-                                                    inst, 0, 0, tid);
+                        DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i] Squashing 
from "
+                                "stage %i. Redirecting  fetch to %s.\n", tid,
+                                inst->seqNum, stage_num, pc);
+                        DPRINTF(InOrderStall, "STALL: [tid:%i]: Branch"
+                                " misprediction at %s\n", tid, 
inst->pcState());
 
                         if (inst->predTaken()) {
                             predictedTakenIncorrect++;
                             DPRINTF(InOrderExecute, "[tid:%i] [sn:%i] %s ..."
-                                    "PC %s ... Mispredicts! (Taken)\n",
+                                    "PC %s ... Mispredicts! "
+                                    "(Prediction: Taken)\n",
                                     tid, inst->seqNum,
                                     inst->staticInst->disassemble(
                                         inst->instAddr()),
@@ -231,7 +174,8 @@
                         } else {
                             predictedNotTakenIncorrect++;
                             DPRINTF(InOrderExecute, "[tid:%i] [sn:%i] %s ..."
-                                    "PC %s ... Mispredicts! (Not Taken)\n",
+                                    "PC %s ... Mispredicts! "
+                                    "(Prediction: Not Taken)\n",
                                     tid, inst->seqNum,
                                     inst->staticInst->disassemble(
                                         inst->instAddr()),
@@ -247,7 +191,7 @@
                     exec_req->done();
                 } else {
                     warn("inst [sn:%i] had a %s fault", seq_num, 
fault->name());
-
+                    inst->fault = fault;
                     exec_req->done();
                 }
             } else {
diff -r 18173b099ed1 -r b085f409d89c src/cpu/inorder/resources/fetch_seq_unit.cc
--- a/src/cpu/inorder/resources/fetch_seq_unit.cc       Sun Jun 19 21:43:35 
2011 -0400
+++ b/src/cpu/inorder/resources/fetch_seq_unit.cc       Sun Jun 19 21:43:35 
2011 -0400
@@ -78,7 +78,6 @@
     DynInstPtr inst = fs_req->inst;
     ThreadID tid = inst->readTid();
     int stage_num = fs_req->getStageNum();
-    InstSeqNum seq_num = inst->seqNum;
 
     DPRINTF(InOrderFetchSeq, "[tid:%i]: Current PC is %s\n", tid,
             pc[tid]);
@@ -109,48 +108,26 @@
 
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to