From: Korey Sewell Date: Mon, 20 Jun 2011 01:43:33 +0000 (-0400) Subject: inorder: update bpred code X-Git-Tag: stable_2012_02_02~265 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e2f9266dbfc7ef54f94028eeffa4e40c76ffc17a;p=gem5.git inorder: update bpred code clean up control flow to make it easier to understand --- diff --git a/src/cpu/inorder/resource.cc b/src/cpu/inorder/resource.cc index bdcfbde7d..cad5cfb09 100644 --- a/src/cpu/inorder/resource.cc +++ b/src/cpu/inorder/resource.cc @@ -305,8 +305,10 @@ Resource::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, int req_slot_num = req_ptr->getSlot(); - if (resourceEvent[req_slot_num].scheduled()) - unscheduleEvent(req_slot_num); + if (latency > 0) { + if (resourceEvent[req_slot_num].scheduled()) + unscheduleEvent(req_slot_num); + } freeSlot(req_slot_num); } diff --git a/src/cpu/inorder/resources/bpred_unit.cc b/src/cpu/inorder/resources/bpred_unit.cc index 127843e96..25b8b165a 100644 --- a/src/cpu/inorder/resources/bpred_unit.cc +++ b/src/cpu/inorder/resources/bpred_unit.cc @@ -1,3 +1,4 @@ + /* * Copyright (c) 2004-2005 The Regents of The University of Michigan * All rights reserved. @@ -189,10 +190,6 @@ BPredUnit::predict(DynInstPtr &inst, TheISA::PCState &predPC, ThreadID tid) ++condPredicted; pred_taken = BPLookup(predPC.instAddr(), bp_history); - - DPRINTF(InOrderBPred, "[tid:%i]: Branch predictor predicted %i " - "for PC %s\n", - tid, pred_taken, inst->pcState()); } PredictorHistory predict_record(inst->seqNum, predPC, pred_taken, @@ -242,10 +239,6 @@ BPredUnit::predict(DynInstPtr &inst, TheISA::PCState &predPC, ThreadID tid) inst->isUncondCtrl() && inst->isDirectCtrl()) { target = inst->branchTarget(); - - DPRINTF(InOrderBPred, "[tid:%i]: Setting %s predicted" - " target to %s.\n", - tid, inst->pcState(), target); } else if (BTB.valid(predPC.instAddr(), asid)) { ++BTBHits; @@ -267,6 +260,8 @@ BPredUnit::predict(DynInstPtr &inst, TheISA::PCState &predPC, ThreadID tid) // Set the PC and the instruction's predicted target. predPC = target; } + DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Setting Predicted PC to %s.\n", + tid, inst->seqNum, predPC); predHist[tid].push_front(predict_record); diff --git a/src/cpu/inorder/resources/branch_predictor.cc b/src/cpu/inorder/resources/branch_predictor.cc index 829ae4346..0507bc356 100644 --- a/src/cpu/inorder/resources/branch_predictor.cc +++ b/src/cpu/inorder/resources/branch_predictor.cc @@ -66,13 +66,19 @@ BranchPredictor::regStats() void BranchPredictor::execute(int slot_num) { - // After this is working, change this to a reinterpret cast - // for performance considerations ResourceRequest* bpred_req = reqs[slot_num]; DynInstPtr inst = bpred_req->inst; ThreadID tid = inst->readTid(); InstSeqNum seq_num = inst->seqNum; + if (!inst->isControl()) { + DPRINTF(Resource, "Ignoring %s, not a control inst.\n", + inst->instName()); + bpred_req->done(); + return; + } + + switch (bpred_req->cmd) { case PredictBranch: @@ -84,12 +90,6 @@ BranchPredictor::execute(int slot_num) } else { TheISA::PCState pred_PC = inst->pcState(); TheISA::advancePC(pred_PC, inst->staticInst); -#if ISA_HAS_DELAY_SLOT - // By default set target to NNPC (e.g. PC + 8) - // so that a not-taken branch will update - // correctly - pred_PC.advance(); -#endif if (inst->isControl()) { // If not, the pred_PC be updated to pc+8 @@ -111,8 +111,8 @@ BranchPredictor::execute(int slot_num) } inst->setPredTarg(pred_PC); - DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Predicted PC is " - "%s.\n", tid, seq_num, pred_PC); + DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: %s Predicted PC is " + "%s.\n", tid, seq_num, inst->instName(), pred_PC); } bpred_req->done(); diff --git a/src/cpu/inorder/resources/execution_unit.cc b/src/cpu/inorder/resources/execution_unit.cc index 7ed9aed9a..4fca9e5e1 100644 --- a/src/cpu/inorder/resources/execution_unit.cc +++ b/src/cpu/inorder/resources/execution_unit.cc @@ -139,10 +139,11 @@ ExecutionUnit::execute(int slot_num) lastControlTick = curTick(); // Evaluate Branch + DPRINTF(IEW, "Pre-Execute %s PC:%s nextPC:%s predPC:%s\n", inst->instName(), inst->pcState(), inst->readPredTarg()); fault = inst->execute(); executions++; - inst->setExecuted(); + DPRINTF(IEW, "Post-Execute %s PC:%s nextPC:%s predPC:%s\n", inst->instName(), inst->pcState(), inst->readPredTarg()); if (fault == NoFault) { // If branch is mispredicted, then signal squash @@ -160,14 +161,14 @@ ExecutionUnit::execute(int slot_num) inst->setPredTarg(pc); 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()) { + } else if (!inst->predTaken() && inst->isCondDelaySlot()) { + assert(0 && "Not Handling Conditional Delay Slots (2)"); inst->bdelaySeqNum = seq_num; inst->procDelaySlotOnMispred = true; diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc index df8c6de63..67f6c5102 100644 --- a/src/cpu/inorder/resources/fetch_seq_unit.cc +++ b/src/cpu/inorder/resources/fetch_seq_unit.cc @@ -111,13 +111,16 @@ FetchSeqUnit::execute(int slot_num) { if (inst->isControl()) { // If it's a return, then we must wait for resolved address. + // The Predictor will mark a return a false as "not taken" + // if there is no RAS entry if (inst->isReturn() && !inst->predTaken()) { cpu->pipelineStage[stage_num]-> toPrevStages->stageBlock[stage_num][tid] = true; pcValid[tid] = false; pcBlockStage[tid] = stage_num; } else if (inst->isCondDelaySlot() && !inst->predTaken()) { - // Not-Taken AND Conditional Control + assert(0 && "Not Handling Conditional Delay Slot"); + // Not-Taken AND Conditional Control DPRINTF(InOrderFetchSeq, "[tid:%i]: [sn:%i]: [PC:%s] " "Predicted Not-Taken Cond. Delay inst. Skipping " "delay slot and Updating PC to %s\n", @@ -138,15 +141,9 @@ FetchSeqUnit::execute(int slot_num) "Not-Taken Control " "inst. updating PC to %s\n", tid, inst->seqNum, inst->readPredTarg()); -#if ISA_HAS_DELAY_SLOT - pc[tid] = inst->pcState(); - advancePC(pc[tid], inst->staticInst); -#endif } else if (inst->predTaken()) { // Taken Control #if ISA_HAS_DELAY_SLOT - pc[tid] = inst->readPredTarg(); - DPRINTF(InOrderFetchSeq, "[tid:%i]: [sn:%i] Updating delay" " slot target to PC %s\n", tid, inst->seqNum, inst->readPredTarg()); @@ -184,9 +181,6 @@ FetchSeqUnit::squashAfterInst(DynInstPtr inst, int stage_num, ThreadID tid) // Squash In Pipeline Stage cpu->pipelineStage[stage_num]->squashDueToBranch(inst, tid); - // Squash inside current resource, so if there needs to be fetching on - // same cycle the fetch information will be correct. - // Schedule Squash Through-out Resource Pool cpu->resPool->scheduleEvent( (InOrderCPU::CPUEventType)ResourcePool::SquashAll, inst, 0); @@ -222,32 +216,32 @@ FetchSeqUnit::squash(DynInstPtr inst, int squash_stage, squashSeqNum[tid] = done_seq_num; lastSquashCycle[tid] = curTick(); - // If The very next instruction number is the done seq. num, - // then we haven't seen the delay slot yet ... if it isn't - // the last done_seq_num then this is the delay slot inst. - if (cpu->nextInstSeqNum(tid) != done_seq_num && - !inst->procDelaySlotOnMispred) { + if (inst->isControl()) { + // If the next inst. num is greater than done seq num, + // then that means we have seen the delay slot + assert(cpu->nextInstSeqNum(tid) >= done_seq_num); + if (cpu->nextInstSeqNum(tid) > done_seq_num) { + // Reset PC + pc[tid] = newPC; - // Reset PC - pc[tid] = newPC; #if ISA_HAS_DELAY_SLOT - TheISA::advancePC(pc[tid], inst->staticInst); + // The Pred. Target will be (NPC, NNPC, NNPC+4) + // so since we already saw the NPC (i.e. delay slot) + // advance one more to get (NNPC, NNPC+4, NNPC+8) + TheISA::advancePC(pc[tid], inst->staticInst); #endif - DPRINTF(InOrderFetchSeq, "[tid:%i]: Setting PC to %s.\n", - tid, newPC); - } else { - assert(ISA_HAS_DELAY_SLOT); - - pc[tid] = (inst->procDelaySlotOnMispred) ? - inst->branchTarget() : newPC; - - // Reset PC to Delay Slot Instruction - if (inst->procDelaySlotOnMispred) { - // Reset PC - pc[tid] = newPC; + DPRINTF(InOrderFetchSeq, "[tid:%i]: Setting PC to %s.\n", + tid, newPC); + } else { + // If The very next instruction number that needs to be given + // out by the CPU is the done seq. num, then we haven't seen + // the delay slot instruction yet. + assert(ISA_HAS_DELAY_SLOT); + pc[tid] = newPC; } - + } else { + pc[tid] = newPC; } // Unblock Any Stages Waiting for this information to be updated ...