diff --git a/src/cpu/o3/comm.hh b/src/cpu/o3/comm.hh index c0cf38c3b5..cde822d6e7 100644 --- a/src/cpu/o3/comm.hh +++ b/src/cpu/o3/comm.hh @@ -147,7 +147,6 @@ struct IEWStruct DynInstPtr mispredictInst[MaxThreads]; Addr mispredPC[MaxThreads]; InstSeqNum squashedSeqNum[MaxThreads]; - uint64_t squashedStreamId[MaxThreads]; uint64_t squashedTargetId[MaxThreads]; uint64_t squashedLoopIter[MaxThreads]; std::unique_ptr pc[MaxThreads]; @@ -196,7 +195,7 @@ struct SquashVersion struct ResolveQueueEntry { - uint64_t resolvedFSQId; + uint64_t resolvedFTQId; std::vector resolvedInstPC; }; @@ -250,7 +249,7 @@ struct TimeStruct struct ResolvedCFIEntry { - uint64_t fsqId; + uint64_t ftqId; uint64_t pc; }; /** Resolved control-flow PCs produced this cycle (fetch buffers/merges). */ @@ -301,8 +300,7 @@ struct TimeStruct InstSeqNum doneMemSeqNum; - uint64_t doneFsqId; // F - uint64_t squashedStreamId; // F + uint64_t doneFtqId; // F uint64_t squashedTargetId; // F unsigned squashedLoopIter; // F diff --git a/src/cpu/o3/commit.cc b/src/cpu/o3/commit.cc index 89c780cd62..9304ebae15 100644 --- a/src/cpu/o3/commit.cc +++ b/src/cpu/o3/commit.cc @@ -701,7 +701,6 @@ Commit::squashAll(ThreadID tid) set(toIEW->commitInfo[tid].pc, pc[tid]); - toIEW->commitInfo[tid].squashedStreamId = committedStreamId; toIEW->commitInfo[tid].squashedTargetId = committedTargetId; toIEW->commitInfo[tid].squashedLoopIter = committedLoopIter; @@ -1074,12 +1073,9 @@ Commit::commit() DPRINTF(Commit, "Unable to find squashed instruction in ROB\n"); } - toIEW->commitInfo[tid].squashedStreamId = fromIEW->squashedStreamId[tid]; toIEW->commitInfo[tid].squashedTargetId = fromIEW->squashedTargetId[tid]; toIEW->commitInfo[tid].squashedLoopIter = fromIEW->squashedLoopIter[tid]; - // toIEW->commitInfo[tid].doneFsqId = - // toIEW->commitInfo[tid].squashInst->getFsqId(); if (toIEW->commitInfo[tid].mispredictInst) { if (toIEW->commitInfo[tid].mispredictInst->isUncondCtrl()) { toIEW->commitInfo[tid].branchTaken = true; @@ -1322,11 +1318,9 @@ Commit::commitInsts() // Set the doneSeqNum to the youngest committed instruction. toIEW->commitInfo[tid].doneSeqNum = head_inst->seqNum; - if (head_inst->getFsqId() > 1) { - toIEW->commitInfo[tid].doneFsqId = - head_inst->getFsqId() - 1; + if (head_inst->getFtqId() > 1) { + toIEW->commitInfo[tid].doneFtqId = head_inst->getFtqId() - 1; } - committedStreamId = head_inst->getFsqId(); committedTargetId = head_inst->getFtqId(); committedLoopIter = head_inst->getLoopIteration(); diff --git a/src/cpu/o3/commit.hh b/src/cpu/o3/commit.hh index 963b8810aa..750b085df6 100644 --- a/src/cpu/o3/commit.hh +++ b/src/cpu/o3/commit.hh @@ -554,8 +554,7 @@ private: // committed Stream and Target - uint64_t committedStreamId{1}; - uint64_t committedTargetId{0}; + uint64_t committedTargetId{1}; uint64_t committedLoopIter{}; struct CommitStats : public statistics::Group diff --git a/src/cpu/o3/decode.cc b/src/cpu/o3/decode.cc index 341fece97e..e78eb0799e 100644 --- a/src/cpu/o3/decode.cc +++ b/src/cpu/o3/decode.cc @@ -1012,7 +1012,6 @@ Decode::checkAndFuseInsts(std::vector &vec, DynInstPtr& cur) instruction->setVersion(inst_pair[1]->getVersion()); instruction->setTid(inst_pair[1]->threadNumber); instruction->thread = inst_pair[1]->thread; - instruction->setFsqId(inst_pair[1]->fsqId); instruction->setFtqId(inst_pair[1]->ftqId); instruction->instListIt = cpu->instList.insert(inst_pair[0]->instListIt, instruction); diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh index 25f5b39f85..7794a1ce03 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -395,10 +395,8 @@ class DynInst : public ExecContext, public RefCounted Addr fallThruPC; - /** fsqId and ftqId are used for squashing and committing */ + /** ftqId is used for squashing and committing */ /** The fetch stream queue ID of the instruction. */ - unsigned fsqId; - /** The fetch target queue ID of the instruction. */ unsigned ftqId; /** The number of loop iteration within an fsq entry of the instruction. */ unsigned loopIteration; @@ -1558,18 +1556,6 @@ class DynInst : public ExecContext, public RefCounted } - void - setFsqId(unsigned id) - { - fsqId = id; - } - - unsigned - getFsqId() - { - return fsqId; - } - void setFtqId(unsigned id) { diff --git a/src/cpu/o3/fetch.cc b/src/cpu/o3/fetch.cc index c91a599910..a5079227a0 100644 --- a/src/cpu/o3/fetch.cc +++ b/src/cpu/o3/fetch.cc @@ -629,8 +629,8 @@ Fetch::processCacheCompletion(PacketPtr pkt) } // Verify fetchBufferPC alignment with the supplying FSQ entry. - if (fetchBuffer[tid].valid && dbpbtb->fsqHasHead()) { - const auto &stream = dbpbtb->fsqHead(); + if (fetchBuffer[tid].valid && dbpbtb->ftqHasHead()) { + const auto &stream = dbpbtb->ftqHead(); if (fetchBuffer[tid].startPC != stream.startPC) { panic("fetchBufferPC %#x should be aligned with FSQ startPC %#x", fetchBuffer[tid].startPC, stream.startPC); @@ -782,10 +782,8 @@ Fetch::lookupAndUpdateNextPC(const DynInstPtr &inst, PCStateBase &next_pc) // Decoupled+BTB-only: compute next PC directly from the supplying FSQ entry. ThreadID tid = inst->threadNumber; assert(dbpbtb); - assert(dbpbtb->fsqHasHead()); - const auto &stream = dbpbtb->fsqHead(); - const auto fsq_id = dbpbtb->fsqHeadId(); - const auto ftq_id = dbpbtb->fsqHeadFtqId(); + assert(dbpbtb->ftqHasHead()); + const auto &stream = dbpbtb->ftqHead(); const Addr curr_pc = next_pc.instAddr(); assert(stream.startPC <= curr_pc && curr_pc < stream.predEndPC); @@ -818,7 +816,7 @@ Fetch::lookupAndUpdateNextPC(const DynInstPtr &inst, PCStateBase &next_pc) // Track how many dynamic instructions were fetched for this (legacy) FTQ/FSQ entry. ftqEntryFetchedInsts[tid]++; if (run_out) { - dbpbtb->consumeFetchTarget(ftq_id, fsq_id, ftqEntryFetchedInsts[tid]); + dbpbtb->consumeFetchTarget(ftqEntryFetchedInsts[tid]); ftqEntryFetchedInsts[tid] = 0; fetchBuffer[tid].valid = false; DPRINTF(DecoupleBP, "Used up fetch targets.\n"); @@ -1519,7 +1517,7 @@ Fetch::handleIEWSignals() for (const auto &resolved : incoming) { bool merged = false; for (auto &queued : resolveQueue) { - if (queued.resolvedFSQId == resolved.fsqId) { + if (queued.resolvedFTQId == resolved.ftqId) { queued.resolvedInstPC.push_back(resolved.pc); merged = true; break; @@ -1531,7 +1529,7 @@ Fetch::handleIEWSignals() } ResolveQueueEntry new_entry; - new_entry.resolvedFSQId = resolved.fsqId; + new_entry.resolvedFTQId = resolved.ftqId; new_entry.resolvedInstPC.push_back(resolved.pc); resolveQueue.push_back(std::move(new_entry)); enqueueCount++; @@ -1543,7 +1541,7 @@ Fetch::handleIEWSignals() if (!resolveQueue.empty()) { auto &entry = resolveQueue.front(); - unsigned int stream_id = entry.resolvedFSQId; + unsigned int stream_id = entry.resolvedFTQId; dbpbtb->prepareResolveUpdateEntries(stream_id); for (const auto resolvedInstPC : entry.resolvedInstPC) { dbpbtb->markCFIResolved(stream_id, resolvedInstPC); @@ -1564,10 +1562,10 @@ Fetch::handleCommitSignals(ThreadID tid) { // Check squash signals from commit. if (!fromCommit->commitInfo[tid].squash) { - if (fromCommit->commitInfo[tid].doneSeqNum) { - DPRINTF(DecoupleBP, "Commit stream Id: %lu\n", fromCommit->commitInfo[tid].doneFsqId); + if (fromCommit->commitInfo[tid].doneFtqId) { + DPRINTF(DecoupleBP, "Commit stream Id: %lu\n", fromCommit->commitInfo[tid].doneFtqId); assert(dbpbtb); - dbpbtb->update(fromCommit->commitInfo[tid].doneFsqId, tid); + dbpbtb->update(fromCommit->commitInfo[tid].doneFtqId, tid); } return false; } @@ -1602,7 +1600,7 @@ Fetch::handleCommitSignals(ThreadID tid) DPRINTF(Fetch, "Use mispred inst to redirect, treating as control squash\n"); const auto corr_pc = fromCommit->commitInfo[tid].pc->as(); assert(dbpbtb); - dbpbtb->controlSquash(mispred_inst->getFtqId(), mispred_inst->getFsqId(), mispred_inst->pcState(), + dbpbtb->controlSquash(mispred_inst->getFtqId(), mispred_inst->pcState(), corr_pc, mispred_inst->staticInst, mispred_inst->getInstBytes(), fromCommit->commitInfo[tid].branchTaken, mispred_inst->seqNum, tid, mispred_inst->getLoopIteration(), true); @@ -1610,16 +1608,14 @@ Fetch::handleCommitSignals(ThreadID tid) DPRINTF(Fetch, "Treating as trap squash\n", tid); const auto trap_pc = fromCommit->commitInfo[tid].pc->as(); assert(dbpbtb); - dbpbtb->trapSquash(fromCommit->commitInfo[tid].squashedTargetId, - fromCommit->commitInfo[tid].squashedStreamId, fromCommit->commitInfo[tid].committedPC, + dbpbtb->trapSquash(fromCommit->commitInfo[tid].squashedTargetId, fromCommit->commitInfo[tid].committedPC, trap_pc, tid, fromCommit->commitInfo[tid].squashedLoopIter); } else { - if (fromCommit->commitInfo[tid].pc && fromCommit->commitInfo[tid].squashedStreamId != 0) { + if (fromCommit->commitInfo[tid].pc && fromCommit->commitInfo[tid].squashedTargetId != 0) { DPRINTF(Fetch, "Squash with stream id and target id from IEW\n"); const auto nc_pc = fromCommit->commitInfo[tid].pc->as(); assert(dbpbtb); - dbpbtb->nonControlSquash(fromCommit->commitInfo[tid].squashedTargetId, - fromCommit->commitInfo[tid].squashedStreamId, nc_pc, + dbpbtb->nonControlSquash(fromCommit->commitInfo[tid].squashedTargetId, nc_pc, 0, tid, fromCommit->commitInfo[tid].squashedLoopIter); } else { DPRINTF(Fetch, "Dont squash dbq because no meaningful stream\n"); @@ -1643,7 +1639,7 @@ Fetch::handleDecodeSquash(ThreadID tid) const auto next_pc = fromDecode->decodeInfo[tid].nextPC->as(); dbpbtb->controlSquash( - mispred_inst->getFtqId(), mispred_inst->getFsqId(), + mispred_inst->getFtqId(), mispred_inst->pcState(), next_pc, mispred_inst->staticInst, mispred_inst->getInstBytes(), @@ -1703,11 +1699,9 @@ Fetch::buildInst(ThreadID tid, StaticInstPtr staticInst, DPRINTF(Fetch, "Is nop: %i, is move: %i\n", instruction->isNop(), instruction->isMov()); assert(dbpbtb); - DPRINTF(DecoupleBP, "Set instruction %lu with stream id %lu, fetch id %lu\n", - instruction->seqNum, dbpbtb->fsqHeadId(), - dbpbtb->fsqHeadFtqId()); - instruction->setFsqId(dbpbtb->fsqHeadId()); - instruction->setFtqId(dbpbtb->fsqHeadFtqId()); + DPRINTF(DecoupleBP, "Set instruction %lu with fetch id %lu\n", + instruction->seqNum, dbpbtb->ftqHeadId()); + instruction->setFtqId(dbpbtb->ftqHeadId()); #if TRACING_ON if (trace) { @@ -1763,7 +1757,7 @@ bool Fetch::checkDecoupledFrontend(ThreadID tid) { assert(dbpbtb); - if (!isTraceMode() && !dbpbtb->fsqHasHead()) { + if (!isTraceMode() && !dbpbtb->ftqHasHead()) { dbpbtb->addFtqNotValid(); DPRINTF(Fetch, "Skip fetch when FSQ head is not available\n"); setAllFetchStalls(StallReason::FTQBubble); @@ -1991,7 +1985,7 @@ Fetch::performInstructionFetch(ThreadID tid) // For decoupled frontend (including trace mode), check FTQ availability StallReason stall = StallReason::NoStall; while (numInst < fetchWidth && fetchQueue[tid].size() < fetchQueueSize && - !predictedBranch && !fsqEmpty() && !waitForVsetvl) { + !predictedBranch && !ftqEmpty() && !waitForVsetvl) { // Check memory needs and supply bytes to decoder if required stall = checkMemoryNeeds(tid, pc_state, curMacroop); @@ -2051,13 +2045,13 @@ Fetch::sendNextCacheRequest(ThreadID tid, const PCStateBase &pc_state) { return; } - if (fsqEmpty()) { + if (ftqEmpty()) { DPRINTF(Fetch, "[tid:%i] No FSQ entry available for next fetch\n", tid); return; } assert(dbpbtb); - const auto &stream = dbpbtb->fsqHead(); + const auto &stream = dbpbtb->ftqHead(); const Addr start_pc = stream.startPC; fetchBuffer[tid].startPC = start_pc; diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh index 42597fdb51..65ae953797 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -968,7 +968,7 @@ class Fetch // Decoupled+BTB-only: fetch consumes the supplying FSQ entry directly. // If no head is available, fetch stalls (no extra "supply" state machine). - bool fsqEmpty() const { return !dbpbtb || !dbpbtb->fsqHasHead(); } + bool ftqEmpty() const { return !dbpbtb || !dbpbtb->ftqHasHead(); } // Number of dynamic instructions fetched within the current FTQ entry. // Used to explicitly notify the BPU when an entry is consumed (Phase5 prep). diff --git a/src/cpu/o3/iew.cc b/src/cpu/o3/iew.cc index d9f7432d34..968983c59d 100644 --- a/src/cpu/o3/iew.cc +++ b/src/cpu/o3/iew.cc @@ -567,7 +567,6 @@ IEW::squashDueToBranch(const DynInstPtr& inst, ThreadID tid) inst->seqNum < toCommit->squashedSeqNum[tid]) { toCommit->squash[tid] = true; toCommit->squashedSeqNum[tid] = inst->seqNum; - toCommit->squashedStreamId[tid] = inst->getFsqId(); toCommit->squashedTargetId[tid] = inst->getFtqId(); toCommit->squashedLoopIter[tid] = inst->getLoopIteration(); toCommit->branchTaken[tid] = inst->pcState().branching(); @@ -581,10 +580,9 @@ IEW::squashDueToBranch(const DynInstPtr& inst, ThreadID tid) wroteToTimeBuffer = true; DPRINTF(DecoupleBP, - "Branch misprediction (pc=%#lx) set stream id to %lu, target " + "Branch misprediction (pc=%#lx) set target " "id to %lu, loop iter to %u\n", toCommit->pc[tid]->instAddr(), - toCommit->squashedStreamId[tid], toCommit->squashedTargetId[tid], toCommit->squashedLoopIter[tid]); } @@ -607,7 +605,6 @@ IEW::squashDueToMemOrder(const DynInstPtr& inst, ThreadID tid) toCommit->squash[tid] = true; toCommit->squashedSeqNum[tid] = inst->seqNum; - toCommit->squashedStreamId[tid] = inst->getFsqId(); toCommit->squashedTargetId[tid] = inst->getFtqId(); toCommit->squashedLoopIter[tid] = inst->getLoopIteration(); set(toCommit->pc[tid], inst->pcState()); @@ -619,10 +616,9 @@ IEW::squashDueToMemOrder(const DynInstPtr& inst, ThreadID tid) wroteToTimeBuffer = true; DPRINTF(DecoupleBP, - "Memory violation (pc=%#lx) set stream id to %lu, target id " + "Memory violation (pc=%#lx) set target id " "to %lu, loop iter to %u\n", toCommit->pc[tid]->instAddr(), - toCommit->squashedStreamId[tid], toCommit->squashedTargetId[tid], toCommit->squashedLoopIter[tid]); @@ -1570,7 +1566,7 @@ IEW::SquashCheckAfterExe(DynInstPtr inst) if (inst->isControl()) { auto &resolved_cfis = toFetch->iewInfo[tid].resolvedCFIs; TimeStruct::IewComm::ResolvedCFIEntry entry; - entry.fsqId = inst->getFsqId(); + entry.ftqId = inst->getFtqId(); entry.pc = inst->getPC(); resolved_cfis.push_back(entry); } diff --git a/src/cpu/o3/trace/TraceFetch.cc b/src/cpu/o3/trace/TraceFetch.cc index 5257fd012b..5e6694fa93 100644 --- a/src/cpu/o3/trace/TraceFetch.cc +++ b/src/cpu/o3/trace/TraceFetch.cc @@ -536,8 +536,8 @@ TraceFetch::chooseWrongPathNopSize(ThreadID tid, Addr pc) bool taken = false; if (fetch.isBTBPred()) { assert(fetch.dbpbtb); - if (fetch.dbpbtb->fsqHasHead()) { - const auto &stream = fetch.dbpbtb->fsqHead(); + if (fetch.dbpbtb->ftqHasHead()) { + const auto &stream = fetch.dbpbtb->ftqHead(); block_end = stream.predEndPC; taken_pc = stream.predBranchInfo.pc; taken = stream.predTaken; diff --git a/src/cpu/pred/btb/abtb.cc b/src/cpu/pred/btb/abtb.cc index 1e9c6e11ab..c4876e8158 100644 --- a/src/cpu/pred/btb/abtb.cc +++ b/src/cpu/pred/btb/abtb.cc @@ -30,7 +30,7 @@ #include "cpu/pred/btb/abtb.hh" #include "base/intmath.hh" -#include "stream_struct.hh" +#include "common.hh" // Additional conditional includes based on build mode #ifdef UNIT_TEST @@ -327,7 +327,7 @@ void AheadBTB::specUpdateHist(const boost::dynamic_bitset<> &history, FullBTBPrediction &pred) {} void -AheadBTB::recoverHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, bool cond_taken) +AheadBTB::recoverHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) { // clear ahead pipeline first while (!aheadReadBtbEntries.empty()) { @@ -436,7 +436,7 @@ AheadBTB::processOldEntries(const std::vector& hit_entries, * Check if the branch was predicted correctly */ void -AheadBTB::checkPredictionHit(const FetchStream &stream, const BTBMeta* meta) +AheadBTB::checkPredictionHit(const FetchTarget &stream, const BTBMeta* meta) { bool pred_branch_hit = false; for (auto &e : meta->hit_entries) { @@ -460,7 +460,7 @@ AheadBTB::checkPredictionHit(const FetchStream &stream, const BTBMeta* meta) */ std::vector AheadBTB::collectEntriesToUpdate(const std::vector& old_entries, - const FetchStream &stream) + const FetchTarget &stream) { auto all_entries = old_entries; @@ -647,7 +647,7 @@ AheadBTB::collectEntriesToUpdateFromS3Pred(const std::vector& old_entr * 5. Update MRU information */ void -AheadBTB::update(const FetchStream &stream) +AheadBTB::update(const FetchTarget &stream) { if (usingS3Pred) { DPRINTF(ABTB, "AheadBTB: using S3 prediction for update, skipping AheadBTB update\n"); @@ -689,7 +689,7 @@ AheadBTB::update(const FetchStream &stream) * @return Previous PC, 0 if the stream is not filled */ Addr -AheadBTB::getPreviousPC(const FetchStream &stream) +AheadBTB::getPreviousPC(const FetchTarget &stream) { // get pc from the nth previous block, the value of n is aheadPipelinedStages auto previous_pcs = stream.previousPCs; @@ -712,7 +712,7 @@ AheadBTB::getPreviousPC(const FetchStream &stream) #ifndef UNIT_TEST void -AheadBTB::commitBranch(const FetchStream &stream, const DynInstPtr &inst) +AheadBTB::commitBranch(const FetchTarget &stream, const DynInstPtr &inst) { auto meta = std::static_pointer_cast(stream.predMetas[getComponentIdx()]); auto &hit_entries = meta->hit_entries; diff --git a/src/cpu/pred/btb/abtb.hh b/src/cpu/pred/btb/abtb.hh index a27bfc6ae0..9e7abc6260 100644 --- a/src/cpu/pred/btb/abtb.hh +++ b/src/cpu/pred/btb/abtb.hh @@ -43,7 +43,7 @@ #include #include "base/types.hh" -#include "cpu/pred/btb/stream_struct.hh" +#include "cpu/pred/btb/common.hh" // Conditional includes based on build mode #ifdef UNIT_TEST @@ -125,7 +125,7 @@ class AheadBTB : public TimedBaseBTBPredictor void tickStart() override; void tick() override; - void commitBranch(const FetchStream &stream, const DynInstPtr &inst) override; + void commitBranch(const FetchTarget &stream, const DynInstPtr &inst) override; void setTrace() override; TraceManager *btbTrace; #endif @@ -153,7 +153,7 @@ class AheadBTB : public TimedBaseBTBPredictor void specUpdateHist(const boost::dynamic_bitset<> &history, FullBTBPrediction &pred) override; void recoverHist(const boost::dynamic_bitset<> &history, - const FetchStream &entry, int shamt, bool cond_taken) override; + const FetchTarget &entry, int shamt, bool cond_taken) override; #ifndef UNIT_TEST /** Creates a BTB with the given number of entries, number of bits per @@ -173,7 +173,7 @@ class AheadBTB : public TimedBaseBTBPredictor * 2. Adds new entries if necessary * 3. Updates MRU information */ - void update(const FetchStream &stream) override; + void update(const FetchTarget &stream) override; @@ -301,13 +301,13 @@ class AheadBTB : public TimedBaseBTBPredictor * @param stream Fetch stream containing prediction info * @return Previous PC */ - Addr getPreviousPC(const FetchStream &stream); + Addr getPreviousPC(const FetchTarget &stream); /** Check branch prediction hit status * @param stream Fetch stream containing execution results * @param meta BTB metadata from prediction */ - void checkPredictionHit(const FetchStream &stream, + void checkPredictionHit(const FetchTarget &stream, const BTBMeta* meta); /** Collect entries that need to be updated @@ -317,7 +317,7 @@ class AheadBTB : public TimedBaseBTBPredictor */ std::vector collectEntriesToUpdate( const std::vector& old_entries, - const FetchStream &stream); + const FetchTarget &stream); /** Update or replace BTB entry * @param btb_idx Index of the BTB entry diff --git a/src/cpu/pred/btb/btb_ittage.cc b/src/cpu/pred/btb/btb_ittage.cc index acd73338e2..58828467cd 100644 --- a/src/cpu/pred/btb/btb_ittage.cc +++ b/src/cpu/pred/btb/btb_ittage.cc @@ -208,7 +208,7 @@ BTBITTAGE::getPredictionMeta() { } void -BTBITTAGE::update(const FetchStream &stream) +BTBITTAGE::update(const FetchTarget &stream) { if (debugPC == stream.startPC || debugPC2 == stream.startPC) { debugFlag = true; @@ -548,7 +548,7 @@ BTBITTAGE::specUpdatePHist(const boost::dynamic_bitset<> &history, FullBTBPredic * @param cond_taken The actual branch outcome */ void -BTBITTAGE::recoverPHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, bool cond_taken) +BTBITTAGE::recoverPHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) { std::shared_ptr predMeta = std::static_pointer_cast(entry.predMetas[getComponentIdx()]); for (int i = 0; i < numPredictors; i++) { @@ -579,7 +579,7 @@ BTBITTAGE::checkFoldedHist(const boost::dynamic_bitset<> &hist, const char * whe } void -BTBITTAGE::commitBranch(const FetchStream &stream, const DynInstPtr &inst) +BTBITTAGE::commitBranch(const FetchTarget &stream, const DynInstPtr &inst) { if (!(inst->isIndirectCtrl() && !inst->isReturn())) { // ittage only cares about indirect non-return branches diff --git a/src/cpu/pred/btb/btb_ittage.hh b/src/cpu/pred/btb/btb_ittage.hh index 6bd363f557..e86b45817b 100644 --- a/src/cpu/pred/btb/btb_ittage.hh +++ b/src/cpu/pred/btb/btb_ittage.hh @@ -3,18 +3,18 @@ #include #include -#include #include +#include +#include "base/sat_counter.hh" #include "base/statistics.hh" #include "base/types.hh" -#include "base/sat_counter.hh" #include "cpu/inst_seq.hh" +#include "cpu/pred/btb/common.hh" #include "cpu/pred/btb/folded_hist.hh" -#include "cpu/pred/btb/stream_struct.hh" #include "cpu/pred/btb/timed_base_pred.hh" -#include "params/BTBITTAGE.hh" #include "debug/DecoupleBP.hh" +#include "params/BTBITTAGE.hh" #include "sim/sim_object.hh" namespace gem5 @@ -108,11 +108,11 @@ class BTBITTAGE : public TimedBaseBTBPredictor // Recover 3 folded history after a misprediction, then update 3 folded history according to history and pred.taken // the other recoverHist methods are left blank void recoverPHist(const boost::dynamic_bitset<> &history, - const FetchStream &entry,int shamt, bool cond_taken) override; + const FetchTarget &entry,int shamt, bool cond_taken) override; - void update(const FetchStream &entry) override; + void update(const FetchTarget &entry) override; - void commitBranch(const FetchStream &stream, const DynInstPtr &inst) override; + void commitBranch(const FetchTarget &stream, const DynInstPtr &inst) override; // check folded hists after speculative update and recover void checkFoldedHist(const bitset &history, const char *when); diff --git a/src/cpu/pred/btb/btb_mgsc.cc b/src/cpu/pred/btb/btb_mgsc.cc index 694bb0b3c1..0211ad7eaa 100755 --- a/src/cpu/pred/btb/btb_mgsc.cc +++ b/src/cpu/pred/btb/btb_mgsc.cc @@ -538,7 +538,7 @@ BTBMGSC::getPredictionMeta() * @return Vector of BTB entries that need to be updated */ std::vector -BTBMGSC::prepareUpdateEntries(const FetchStream &stream) +BTBMGSC::prepareUpdateEntries(const FetchTarget &stream) { auto all_entries = stream.updateBTBEntries; @@ -758,7 +758,7 @@ BTBMGSC::recordPredictionStats(const MgscPrediction &pred, bool actual_taken, bo */ void BTBMGSC::updateSinglePredictor(const BTBEntry &entry, bool actual_taken, const MgscPrediction &pred, - const FetchStream &stream) + const FetchTarget &stream) { // Extract prediction information auto total_sum = pred.total_sum; @@ -837,7 +837,7 @@ BTBMGSC::updateSinglePredictor(const BTBEntry &entry, bool actual_taken, const M } void -BTBMGSC::update(const FetchStream &stream) +BTBMGSC::update(const FetchTarget &stream) { if (!isEnabled()) { return; // No update if disabled @@ -1164,7 +1164,7 @@ BTBMGSC::specUpdateLHist(const std::vector> &history, Fu * @param cond_taken The actual branch outcome */ void -BTBMGSC::recoverHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, bool cond_taken) +BTBMGSC::recoverHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) { if (!isEnabled()) { return; // No recover when disabled @@ -1190,7 +1190,7 @@ BTBMGSC::recoverHist(const boost::dynamic_bitset<> &history, const FetchStream & * @param cond_taken The actual branch outcome */ void -BTBMGSC::recoverPHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, bool cond_taken) +BTBMGSC::recoverPHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) { if (!isEnabled()) { return; // No recover when disabled @@ -1216,7 +1216,7 @@ BTBMGSC::recoverPHist(const boost::dynamic_bitset<> &history, const FetchStream * @param cond_taken The actual branch outcome */ void -BTBMGSC::recoverBwHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, bool cond_taken) +BTBMGSC::recoverBwHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) { if (!isEnabled()) { return; // No recover when disabled @@ -1242,7 +1242,7 @@ BTBMGSC::recoverBwHist(const boost::dynamic_bitset<> &history, const FetchStream * @param cond_taken The actual branch outcome */ void -BTBMGSC::recoverIHist(const FetchStream &entry, int shamt, bool cond_taken) +BTBMGSC::recoverIHist(const FetchTarget &entry, int shamt, bool cond_taken) { if (!isEnabled()) { return; // No recover when disabled @@ -1270,7 +1270,7 @@ BTBMGSC::recoverIHist(const FetchStream &entry, int shamt, bool cond_taken) * @param cond_taken The actual branch outcome */ void -BTBMGSC::recoverLHist(const std::vector> &history, const FetchStream &entry, int shamt, +BTBMGSC::recoverLHist(const std::vector> &history, const FetchTarget &entry, int shamt, bool cond_taken) { if (!isEnabled()) { @@ -1349,7 +1349,7 @@ BTBMGSC::MgscStats::MgscStats(statistics::Group *parent) #ifndef UNIT_TEST void -BTBMGSC::commitBranch(const FetchStream &stream, const DynInstPtr &inst) +BTBMGSC::commitBranch(const FetchTarget &stream, const DynInstPtr &inst) { if (!inst->isCondCtrl()) { // tage olnly deals with conditional branches diff --git a/src/cpu/pred/btb/btb_mgsc.hh b/src/cpu/pred/btb/btb_mgsc.hh index a1fdae5c01..ee94023d1d 100755 --- a/src/cpu/pred/btb/btb_mgsc.hh +++ b/src/cpu/pred/btb/btb_mgsc.hh @@ -14,12 +14,13 @@ #include "base/sat_counter.hh" #include "base/types.hh" +#include "cpu/pred/btb/common.hh" #include "cpu/pred/btb/folded_hist.hh" -#include "cpu/pred/btb/stream_struct.hh" #include "cpu/pred/btb/timed_base_pred.hh" #ifndef UNIT_TEST #include "params/BTBMGSC.hh" + #endif namespace gem5 @@ -167,22 +168,22 @@ class BTBMGSC : public TimedBaseBTBPredictor // Recover all folded history after a misprediction, then update all folded history according to history and // pred.taken - void recoverHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, + void recoverHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) override; - void recoverPHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, + void recoverPHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) override; - void recoverBwHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, + void recoverBwHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) override; - void recoverIHist(const FetchStream &entry, int shamt, + void recoverIHist(const FetchTarget &entry, int shamt, bool cond_taken) override; - void recoverLHist(const std::vector> &history, const FetchStream &entry, int shamt, + void recoverLHist(const std::vector> &history, const FetchTarget &entry, int shamt, bool cond_taken) override; // Update predictor state based on actual branch outcomes - void update(const FetchStream &entry) override; + void update(const FetchTarget &entry) override; #ifndef UNIT_TEST - void commitBranch(const FetchStream &stream, const DynInstPtr &inst) override; + void commitBranch(const FetchTarget &stream, const DynInstPtr &inst) override; #endif void setTrace() override; @@ -279,10 +280,10 @@ class BTBMGSC : public TimedBaseBTBPredictor const TageInfoForMGSC &tage_info); // Helper method to prepare BTB entries for update - std::vector prepareUpdateEntries(const FetchStream &stream); + std::vector prepareUpdateEntries(const FetchTarget &stream); void updateSinglePredictor(const BTBEntry &entry, bool actual_taken, const MgscPrediction &pred, - const FetchStream &stream); + const FetchTarget &stream); void recordPredictionStats(const MgscPrediction &pred, bool actual_taken, bool sc_pred_taken, bool tage_pred_taken); diff --git a/src/cpu/pred/btb/btb_tage.cc b/src/cpu/pred/btb/btb_tage.cc index b39d7de7bd..be55eab771 100644 --- a/src/cpu/pred/btb/btb_tage.cc +++ b/src/cpu/pred/btb/btb_tage.cc @@ -390,7 +390,7 @@ BTBTAGE::getPredictionMeta() { * @return Vector of BTB entries that need to be updated */ std::vector -BTBTAGE::prepareUpdateEntries(const FetchStream &stream) { +BTBTAGE::prepareUpdateEntries(const FetchTarget &stream) { auto all_entries = stream.updateBTBEntries; // Add potential new BTB entry if it's a btb miss during prediction @@ -430,7 +430,7 @@ bool BTBTAGE::updatePredictorStateAndCheckAllocation(const BTBEntry &entry, bool actual_taken, const TagePrediction &pred, - const FetchStream &stream) { + const FetchTarget &stream) { tageStats.updateStatsWithTagePrediction(pred, false); auto &main_info = pred.mainInfo; @@ -636,7 +636,7 @@ BTBTAGE::handleNewEntryAllocation(const Addr &startPC, * Returns false if the update cannot proceed due to a bank conflict. */ bool -BTBTAGE::canResolveUpdate(const FetchStream &stream) { +BTBTAGE::canResolveUpdate(const FetchTarget &stream) { Addr startAddr = stream.getRealStartPC(); unsigned updateBank = getBankId(startAddr); @@ -665,7 +665,7 @@ BTBTAGE::canResolveUpdate(const FetchStream &stream) { * @brief Perform resolved update after probe success. */ void -BTBTAGE::doResolveUpdate(const FetchStream &stream) { +BTBTAGE::doResolveUpdate(const FetchTarget &stream) { if (enableBankConflict && predBankValid) { // Prediction consumed; clear bank tag for next cycle predBankValid = false; @@ -679,7 +679,7 @@ BTBTAGE::doResolveUpdate(const FetchStream &stream) { * @param stream The fetch stream containing branch execution information */ void -BTBTAGE::update(const FetchStream &stream) { +BTBTAGE::update(const FetchTarget &stream) { Addr startAddr = stream.getRealStartPC(); unsigned updateBank = getBankId(startAddr); @@ -774,7 +774,7 @@ BTBTAGE::update(const FetchStream &stream) { } void -BTBTAGE::checkUtageUpdateMisspred(const FetchStream &stream) { +BTBTAGE::checkUtageUpdateMisspred(const FetchTarget &stream) { auto predMeta = std::static_pointer_cast(stream.predMetas[getComponentIdx()]); // use for microtage updatemispred counting // sort microtage predictions by pc to find the first taken branch @@ -976,7 +976,7 @@ BTBTAGE::specUpdatePHist(const boost::dynamic_bitset<> &history, FullBTBPredicti */ void BTBTAGE::recoverPHist(const boost::dynamic_bitset<> &history, - const FetchStream &entry, int shamt, bool cond_taken) + const FetchTarget &entry, int shamt, bool cond_taken) { std::shared_ptr predMeta = std::static_pointer_cast(entry.predMetas[getComponentIdx()]); for (int i = 0; i < numPredictors; i++) { @@ -1126,7 +1126,7 @@ BTBTAGE::getLRUVictim(int table, Addr index) #ifndef UNIT_TEST void -BTBTAGE::commitBranch(const FetchStream &stream, const DynInstPtr &inst) +BTBTAGE::commitBranch(const FetchTarget &stream, const DynInstPtr &inst) { if (!inst->isCondCtrl()) { // tage olnly deals with conditional branches diff --git a/src/cpu/pred/btb/btb_tage.hh b/src/cpu/pred/btb/btb_tage.hh index 56a5041340..5d104b856d 100644 --- a/src/cpu/pred/btb/btb_tage.hh +++ b/src/cpu/pred/btb/btb_tage.hh @@ -1,17 +1,17 @@ #ifndef __CPU_PRED_BTB_TAGE_HH__ #define __CPU_PRED_BTB_TAGE_HH__ +#include #include #include -#include #include -#include +#include #include "base/sat_counter.hh" #include "base/types.hh" #include "cpu/inst_seq.hh" +#include "cpu/pred/btb/common.hh" #include "cpu/pred/btb/folded_hist.hh" -#include "cpu/pred/btb/stream_struct.hh" #include "cpu/pred/btb/timed_base_pred.hh" // Conditional includes based on build mode @@ -134,7 +134,7 @@ class BTBTAGE : public TimedBaseBTBPredictor // Recover 3 folded history after a misprediction, then update 3 folded history according to history and pred.taken // the other recoverHist methods are left blank void recoverPHist(const boost::dynamic_bitset<> &history, - const FetchStream &entry,int shamt, bool cond_taken) override; + const FetchTarget &entry,int shamt, bool cond_taken) override; #ifdef UNIT_TEST // API compatibility wrappers for testing @@ -143,7 +143,7 @@ class BTBTAGE : public TimedBaseBTBPredictor specUpdatePHist(history, pred); } - void recoverHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, + void recoverHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) override { recoverPHist(history, entry, shamt, cond_taken); @@ -151,12 +151,12 @@ class BTBTAGE : public TimedBaseBTBPredictor #endif // Update predictor state based on actual branch outcomes - void update(const FetchStream &entry) override; - bool canResolveUpdate(const FetchStream &entry) override; - void doResolveUpdate(const FetchStream &entry) override; + void update(const FetchTarget &entry) override; + bool canResolveUpdate(const FetchTarget &entry) override; + void doResolveUpdate(const FetchTarget &entry) override; #ifndef UNIT_TEST - void commitBranch(const FetchStream &stream, const DynInstPtr &inst) override; + void commitBranch(const FetchTarget &stream, const DynInstPtr &inst) override; #endif void setTrace() override; @@ -270,7 +270,7 @@ class BTBTAGE : public TimedBaseBTBPredictor unsigned instShiftAmt {1}; // use for microtage updatemispred counting - void checkUtageUpdateMisspred(const FetchStream &stream); + void checkUtageUpdateMisspred(const FetchTarget &stream); // Update prediction counter with saturation void updateCounter(bool taken, unsigned width, short &counter); @@ -417,13 +417,13 @@ private: const std::shared_ptr predMeta = nullptr); // Helper method to prepare BTB entries for update - std::vector prepareUpdateEntries(const FetchStream &stream); + std::vector prepareUpdateEntries(const FetchTarget &stream); // Helper method to update predictor state for a single entry bool updatePredictorStateAndCheckAllocation(const BTBEntry &entry, bool actual_taken, const TagePrediction &pred, - const FetchStream &stream); + const FetchTarget &stream); // Helper method to handle new entry allocation bool handleNewEntryAllocation(const Addr &startPC, diff --git a/src/cpu/pred/btb/btb_ubtb.cc b/src/cpu/pred/btb/btb_ubtb.cc index 36513a0099..755d8d8460 100644 --- a/src/cpu/pred/btb/btb_ubtb.cc +++ b/src/cpu/pred/btb/btb_ubtb.cc @@ -31,9 +31,9 @@ #include "base/intmath.hh" #include "base/trace.hh" +#include "common.hh" #include "cpu/o3/dyn_inst.hh" #include "debug/Fetch.hh" -#include "stream_struct.hh" namespace gem5 { @@ -283,7 +283,7 @@ void UBTB::updateNewEntry(UBTBIter oldEntryIter, const BTBEntry &takenEntry, con void -UBTB::update(const FetchStream &stream) +UBTB::update(const FetchTarget &stream) { auto meta = std::static_pointer_cast(stream.predMetas[getComponentIdx()]); // hit entries whose corresponding insts are acutally executed @@ -320,7 +320,7 @@ UBTB::update(const FetchStream &stream) } void -UBTB::commitBranch(const FetchStream &stream, const DynInstPtr &inst) +UBTB::commitBranch(const FetchTarget &stream, const DynInstPtr &inst) { auto meta = std::static_pointer_cast(stream.predMetas[getComponentIdx()]); auto &hit_entry = meta->hit_entry; diff --git a/src/cpu/pred/btb/btb_ubtb.hh b/src/cpu/pred/btb/btb_ubtb.hh index b36ddb8541..5c394ac9cc 100644 --- a/src/cpu/pred/btb/btb_ubtb.hh +++ b/src/cpu/pred/btb/btb_ubtb.hh @@ -51,7 +51,7 @@ #include "base/logging.hh" #include "base/types.hh" #include "config/the_isa.hh" -#include "cpu/pred/btb/stream_struct.hh" +#include "cpu/pred/btb/common.hh" #include "cpu/pred/btb/timed_base_pred.hh" #include "debug/UBTB.hh" #include "params/UBTB.hh" @@ -130,13 +130,13 @@ class UBTB : public TimedBaseBTBPredictor /** for statistics only * @param stream The fetch stream containing execution results and prediction metadata */ - void update(const FetchStream &stream) override; + void update(const FetchTarget &stream) override; /** for statistics only * @param stream The fetch stream containing execution results * @param inst The dynamic instruction being committed */ - void commitBranch(const FetchStream &stream, const DynInstPtr &inst) override; + void commitBranch(const FetchTarget &stream, const DynInstPtr &inst) override; /** Get prediction BTBMeta * @return Returns the prediction meta @@ -149,7 +149,7 @@ class UBTB : public TimedBaseBTBPredictor // the following methods are not used void specUpdateHist(const boost::dynamic_bitset<> &history, FullBTBPrediction &pred) override {} void recoverHist(const boost::dynamic_bitset<> &history, - const FetchStream &entry, int shamt, bool cond_taken) override{}; + const FetchTarget &entry, int shamt, bool cond_taken) override{}; void reset(); void setTrace() override; TraceManager *ubtbTrace; diff --git a/src/cpu/pred/btb/stream_struct.hh b/src/cpu/pred/btb/common.hh similarity index 99% rename from src/cpu/pred/btb/stream_struct.hh rename to src/cpu/pred/btb/common.hh index 76eb04c8e2..5d54902069 100644 --- a/src/cpu/pred/btb/stream_struct.hh +++ b/src/cpu/pred/btb/common.hh @@ -2,9 +2,9 @@ #define __CPU_PRED_BTB_STREAM_STRUCT_HH__ #include +#include #include -#include // #include "arch/generic/pcstate.hh" #include "base/types.hh" @@ -18,7 +18,8 @@ namespace branch_prediction { namespace btb_pred { -enum EndType { +enum EndType +{ END_CALL=0, END_RET, END_OTHER_TAKEN, @@ -27,7 +28,8 @@ enum EndType { END_NONE }; -enum SquashType { +enum SquashType +{ SQUASH_NONE=0, SQUASH_TRAP, SQUASH_CTRL, @@ -245,8 +247,6 @@ struct LFSR64 } }; - -using FetchStreamId = uint64_t; using FetchTargetId = uint64_t; // {branch pc -> istaken} maps @@ -273,10 +273,11 @@ using IndirectTargets = std::vector>; * - Loop and jump-ahead prediction state * - Statistics for profiling */ -struct FetchStream +struct FetchTarget { + ThreadID tid; Addr startPC; // start pc of the stream - bool predTaken; // whether the FetchStream has taken branch + bool predTaken; // whether the FetchTarget has taken branch Addr predEndPC; // predicted stream end pc (fall through pc) BranchInfo predBranchInfo; // predicted branch info @@ -321,7 +322,7 @@ struct FetchStream int s1Source; // which stage the prediction comes from int s3Source; // which stage the prediction comes from - FetchStream() + FetchTarget() : startPC(0), predTaken(false), predEndPC(0), diff --git a/src/cpu/pred/btb/decoupled_bpred.cc b/src/cpu/pred/btb/decoupled_bpred.cc index abee2cb08e..8869dec427 100644 --- a/src/cpu/pred/btb/decoupled_bpred.cc +++ b/src/cpu/pred/btb/decoupled_bpred.cc @@ -22,20 +22,16 @@ namespace btb_pred { void -DecoupledBPUWithBTB::consumeFetchTarget(unsigned ftq_id, unsigned fsq_id, - unsigned fetched_inst_num) +DecoupledBPUWithBTB::consumeFetchTarget(unsigned fetched_inst_num) { - // Legacy interface: keep ftqId = fsqId - 1 for now. - assert(ftq_id + 1 == fsq_id); - assert(fsq_id == fetchHeadFsqId); - assert(hasStream(fsq_id)); - getStream(fsq_id).fetchInstNum = fetched_inst_num; - fetchHeadFsqId++; + uint32_t ftq_id = ftqHeadId(); + getTarget(ftq_id).fetchInstNum = fetched_inst_num; + fetchHeadFtqId++; } DecoupledBPUWithBTB::DecoupledBPUWithBTB(const DecoupledBPUWithBTBParams &p) : BPredUnit(p), - fetchStreamQueueSize(p.fsq_size), + fetchTargetQueueSize(p.fsq_size), predictWidth(p.predictWidth), maxInstsNum(p.predictWidth / 2), historyBits(p.maxHistLen), @@ -137,7 +133,7 @@ DecoupledBPUWithBTB::tick() } // 1. Request new prediction if FSQ not full and we are idle - if (bpuState == BpuState::IDLE && !streamQueueFull()) { + if (bpuState == BpuState::IDLE && !targetQueueFull()) { if (blockPredictionPending) { DPRINTF(Override, "Prediction blocked to prioritize resolve update\n"); dbpBtbStats.predictionBlockedForUpdate++; @@ -212,7 +208,7 @@ DecoupledBPUWithBTB::requestNewPrediction() } // this function collects predictions from all stages and generate bubbles -// when loop buffer is active, predictions are from saved stream +// when loop buffer is active, predictions are from saved target unsigned DecoupledBPUWithBTB::generateFinalPredAndCreateBubbles() { @@ -306,8 +302,8 @@ DecoupledBPUWithBTB::generateFinalPredAndCreateBubbles() if (ubtb->isEnabled()) { ubtb->updateUsingS3Pred(predsOfEachStage[numStages - 1]); } - if (abtb->isEnabled() && hasStream(fsqId - 1)) { - auto previous_block_startpc = getStream(fsqId - 1).startPC; + if (abtb->isEnabled() && hasTarget(ftqId - 1)) { + auto previous_block_startpc = getTarget(ftqId - 1).startPC; abtb->updateUsingS3Pred(predsOfEachStage[numStages - 1], previous_block_startpc); } else if (abtb->isEnabled()) { abtb->updateUsingS3Pred(predsOfEachStage[numStages - 1], 0); @@ -339,13 +335,12 @@ DecoupledBPUWithBTB::generateFinalPredAndCreateBubbles() * * This function encapsulates the shared logic between different types of squashes: * - Setting squashing state - * - Finding and updating the stream + * - Finding and updating the target * - Recovering history information * - Clearing predictions * - Updating FTQ and FSQ state * * @param target_id ID of the target being squashed - * @param stream_id ID of the stream being squashed * @param squash_type Type of squash (CTRL/OTHER/TRAP) * @param squash_pc PC where the squash occurred * @param redirect_pc PC to redirect to after squash @@ -356,7 +351,6 @@ DecoupledBPUWithBTB::generateFinalPredAndCreateBubbles() */ void DecoupledBPUWithBTB::handleSquash(unsigned target_id, - unsigned stream_id, SquashType squash_type, const PCStateBase &squash_pc, Addr redirect_pc, @@ -365,56 +359,53 @@ DecoupledBPUWithBTB::handleSquash(unsigned target_id, const StaticInstPtr &static_inst, unsigned control_inst_size) { - // Legacy ID mapping (kept for now): ftqId = fsqId - 1. - assert(target_id + 1 == stream_id); - // Set squashing state squashing = true; - // Find the stream being squashed - if (!hasStream(stream_id)) { - assert(!fetchStreamQueue.empty()); - DPRINTF(DecoupleBP, "The squashing stream is insane, ignore squash on it"); + // Find the target being squashed + if (!hasTarget(target_id)) { + assert(!fetchTargetQueue.empty()); + DPRINTF(DecoupleBP, "The squashing target is insane, ignore squash on it"); return; } - // Get reference to the stream - auto &stream = getStream(stream_id); + // Get reference to the target + auto &target = getTarget(target_id); - // Update stream state - stream.resolved = true; - stream.exeTaken = actually_taken; - stream.squashPC = squash_pc.instAddr(); - stream.squashType = squash_type; + // Update target state + target.resolved = true; + target.exeTaken = actually_taken; + target.squashPC = squash_pc.instAddr(); + target.squashType = squash_type; // Special handling for control squash - create branch info if (squash_type == SQUASH_CTRL && static_inst) { // Use full branch info with static_inst if available - stream.exeBranchInfo = BranchInfo(squash_pc.instAddr(), redirect_pc, static_inst, control_inst_size); + target.exeBranchInfo = BranchInfo(squash_pc.instAddr(), redirect_pc, static_inst, control_inst_size); dumpFsq("Before control squash"); } - // Remove streams after the squashed one - squashStreamAfter(stream_id); + // Remove targets after the squashed one + squashTargetAfter(target_id); // Recover history using the extracted function - recoverHistoryForSquash(stream, stream_id, squash_pc, is_conditional, actually_taken, squash_type, redirect_pc); + recoverHistoryForSquash(target, target_id, squash_pc, is_conditional, actually_taken, squash_type, redirect_pc); // Clear predictions for next cycle clearPreds(); - // Update PC and stream ID + // Update PC and target ID s0PC = redirect_pc; - fsqId = stream_id + 1; - fetchHeadFsqId = stream_id + 1; + ftqId = target_id + 1; + fetchHeadFtqId = target_id + 1; DPRINTF(DecoupleBP, "After squash, fsqId(next alloc)=%lu, fetchHeadFsqId=%lu, s0pc=%#lx\n", - fsqId, fetchHeadFsqId, s0PC); + ftqId, fetchHeadFtqId, s0PC); } void -DecoupledBPUWithBTB::controlSquash(unsigned target_id, unsigned stream_id, +DecoupledBPUWithBTB::controlSquash(unsigned target_id, const PCStateBase &control_pc, const PCStateBase &corr_target, const StaticInstPtr &static_inst, @@ -434,118 +425,118 @@ DecoupledBPUWithBTB::controlSquash(unsigned target_id, unsigned stream_id, bool is_conditional = static_inst->isCondCtrl(); bool is_indirect = static_inst->isIndirectCtrl(); - if (!hasStream(stream_id)) { - DPRINTF(DecoupleBP, "The squashing stream is insane, ignore squash on it"); + if (!hasTarget(target_id)) { + DPRINTF(DecoupleBP, "The squashing target is insane, ignore squash on it"); return; } - auto &stream = getStream(stream_id); + auto &target = getTarget(target_id); // Get target address Addr real_target = corr_target.instAddr(); if (!fromCommit && static_inst->isReturn() && !static_inst->isNonSpeculative()) { // get ret addr from ras meta - real_target = ras->getTopAddrFromMetas(stream); + real_target = ras->getTopAddrFromMetas(target); // TODO: set real target to dynamic inst } // Detailed debugging for control squash DPRINTF(DecoupleBP, - "Control squash: ftq_id=%d, fsq_id=%d," + "Control squash: ftq_id=%d," " control_pc=%#lx, real_target=%#lx, is_conditional=%u, " "is_indirect=%u, actually_taken=%u, branch seq: %lu\n", - target_id, stream_id, control_pc.instAddr(), + target_id, control_pc.instAddr(), real_target, is_conditional, is_indirect, actually_taken, seq); // Call shared squash handling logic - handleSquash(target_id, stream_id, SQUASH_CTRL, control_pc, + handleSquash(target_id, SQUASH_CTRL, control_pc, real_target, is_conditional, actually_taken, static_inst, control_inst_size); } void -DecoupledBPUWithBTB::nonControlSquash(unsigned target_id, unsigned stream_id, +DecoupledBPUWithBTB::nonControlSquash(unsigned target_id, const PCStateBase &inst_pc, const InstSeqNum seq, ThreadID tid, const unsigned ¤tLoopIter) { dbpBtbStats.nonControlSquash++; DPRINTF(DecoupleBP, - "non control squash: target id: %d, stream id: %d, inst_pc: %#lx, " + "non control squash: target id: %d, inst_pc: %#lx, " "seq: %lu\n", - target_id, stream_id, inst_pc.instAddr(), seq); + target_id, inst_pc.instAddr(), seq); // Call shared squash handling logic - handleSquash(target_id, stream_id, SQUASH_OTHER, inst_pc, inst_pc.instAddr()); + handleSquash(target_id, SQUASH_OTHER, inst_pc, inst_pc.instAddr()); } void -DecoupledBPUWithBTB::trapSquash(unsigned target_id, unsigned stream_id, +DecoupledBPUWithBTB::trapSquash(unsigned target_id, Addr last_committed_pc, const PCStateBase &inst_pc, ThreadID tid, const unsigned ¤tLoopIter) { dbpBtbStats.trapSquash++; DPRINTF(DecoupleBP, - "Trap squash: target id: %d, stream id: %d, inst_pc: %#lx\n", - target_id, stream_id, inst_pc.instAddr()); + "Trap squash: target id: %d, inst_pc: %#lx\n", + target_id, inst_pc.instAddr()); // Call shared squash handling logic - handleSquash(target_id, stream_id, SQUASH_TRAP, inst_pc, inst_pc.instAddr()); + handleSquash(target_id, SQUASH_TRAP, inst_pc, inst_pc.instAddr()); } void -DecoupledBPUWithBTB::update(unsigned stream_id, ThreadID tid) +DecoupledBPUWithBTB::update(unsigned target_id, ThreadID tid) { // No need to dequeue when queue is empty - if (fetchStreamQueue.empty()) + if (fetchTargetQueue.empty()) return; - // Process all streams that have been committed (stream_id >= head stream id). - while (!fetchStreamQueue.empty() && stream_id >= frontStreamId()) { - auto &stream = fetchStreamQueue.front(); + // Process all targets that have been committed (target_id >= head target id). + while (!fetchTargetQueue.empty() && target_id >= frontTargetId()) { + auto &target = fetchTargetQueue.front(); DPRINTF(DecoupleBP, - "Commit stream start %#lx, which is predicted, " + "Commit target start %#lx, which is predicted, " "final br addr: %#lx, final target: %#lx, pred br addr: %#lx, " "pred target: %#lx\n", - stream.startPC, stream.exeBranchInfo.pc, stream.exeBranchInfo.target, stream.predBranchInfo.pc, - stream.predBranchInfo.target); + target.startPC, target.exeBranchInfo.pc, target.exeBranchInfo.target, target.predBranchInfo.pc, + target.predBranchInfo.target); // Update statistics - updateStatistics(stream); + updateStatistics(target); // Update predictor components - updatePredictorComponents(stream); + updatePredictorComponents(target); - fetchStreamQueue.pop_front(); - fetchStreamBaseId++; + fetchTargetQueue.pop_front(); + fetchTargetBaseId++; dbpBtbStats.fsqEntryCommitted++; } - DPRINTF(DecoupleBP, "after commit stream, fetchStreamQueue size: %lu\n", fetchStreamQueue.size()); + DPRINTF(DecoupleBP, "after commit target, fetchTargetQueue size: %lu\n", fetchTargetQueue.size()); - if (!fetchStreamQueue.empty()) - printStream(fetchStreamQueue.front()); + if (!fetchTargetQueue.empty()) + printTarget(fetchTargetQueue.front()); - historyManager.commit(stream_id); + historyManager.commit(target_id); } bool -DecoupledBPUWithBTB::resolveUpdate(unsigned &stream_id) +DecoupledBPUWithBTB::resolveUpdate(unsigned &target_id) { - if (!hasStream(stream_id)) { - DPRINTF(DecoupleBP, "Stream id %u not found in fetchStreamQueue, cannot update predictors\n", stream_id); + if (!hasTarget(target_id)) { + DPRINTF(DecoupleBP, "Target id %u not found in fetchTargetQueue, cannot update predictors\n", target_id); return true; } - auto &stream = getStream(stream_id); + auto &target = getTarget(target_id); - // Update predictor components only if the stream is hit or taken - if (!(stream.isHit || stream.exeTaken)) { + // Update predictor components only if the target is hit or taken + if (!(target.isHit || target.exeTaken)) { return true; } // Phase 1: probe all resolved-update components to ensure no blocker for (int i = 0; i < numComponents; ++i) { if (components[i]->getResolvedUpdate()) { - if (!components[i]->canResolveUpdate(stream)) { + if (!components[i]->canResolveUpdate(target)) { return false; } } @@ -554,7 +545,7 @@ DecoupledBPUWithBTB::resolveUpdate(unsigned &stream_id) // Phase 2: all clear, perform updates once for (int i = 0; i < numComponents; ++i) { if (components[i]->getResolvedUpdate()) { - components[i]->doResolveUpdate(stream); + components[i]->doResolveUpdate(target); } } @@ -584,61 +575,61 @@ DecoupledBPUWithBTB::blockPredictionOnce() } void -DecoupledBPUWithBTB::prepareResolveUpdateEntries(unsigned &stream_id) +DecoupledBPUWithBTB::prepareResolveUpdateEntries(unsigned &target_id) { - if (!hasStream(stream_id)) { - DPRINTF(DecoupleBP, "Stream id %u not found in fetchStreamQueue, cannot update predictors\n", stream_id); + if (!hasTarget(target_id)) { + DPRINTF(DecoupleBP, "Target id %u not found in fetchTargetQueue, cannot update predictors\n", target_id); return; } - auto &stream = getStream(stream_id); + auto &target = getTarget(target_id); - if (stream.isHit || stream.exeTaken) { - // Prepare stream for update - stream.setUpdateInstEndPC(predictWidth); - stream.setUpdateBTBEntries(); + if (target.isHit || target.exeTaken) { + // Prepare target for update + target.setUpdateInstEndPC(predictWidth); + target.setUpdateBTBEntries(); // only mbtb can generate new entry if (mbtb->isEnabled()) { - mbtb->getAndSetNewBTBEntry(stream); + mbtb->getAndSetNewBTBEntry(target); } } } void -DecoupledBPUWithBTB::markCFIResolved(unsigned &stream_id, uint64_t resolvedInstPC) +DecoupledBPUWithBTB::markCFIResolved(unsigned &target_id, uint64_t resolvedInstPC) { - if (!hasStream(stream_id)) { - DPRINTF(DecoupleBP, "Stream id %u not found in fetchStreamQueue, cannot update predictors\n", stream_id); + if (!hasTarget(target_id)) { + DPRINTF(DecoupleBP, "Target id %u not found in fetchTargetQueue, cannot update predictors\n", target_id); return; } - auto &stream = getStream(stream_id); + auto &target = getTarget(target_id); - if (stream.updateNewBTBEntry.pc == resolvedInstPC) { - stream.updateNewBTBEntry.resolved = true; + if (target.updateNewBTBEntry.pc == resolvedInstPC) { + target.updateNewBTBEntry.resolved = true; } - stream.markBTBEntryResolved(resolvedInstPC); + target.markBTBEntryResolved(resolvedInstPC); } void -DecoupledBPUWithBTB::updatePredictorComponents(FetchStream &stream) +DecoupledBPUWithBTB::updatePredictorComponents(FetchTarget &target) { - // Update predictor components only if the stream is hit or taken - if (stream.isHit || stream.exeTaken) { - // Prepare stream for update - stream.setUpdateInstEndPC(predictWidth); - stream.setUpdateBTBEntries(); + // Update predictor components only if the target is hit or taken + if (target.isHit || target.exeTaken) { + // Prepare target for update + target.setUpdateInstEndPC(predictWidth); + target.setUpdateBTBEntries(); // only mbtb can generate new entry if (mbtb->isEnabled()) { - mbtb->getAndSetNewBTBEntry(stream); + mbtb->getAndSetNewBTBEntry(target); } // Update predictor components for (int i = 0; i < numComponents; ++i) { if (!components[i]->getResolvedUpdate()) { - components[i]->update(stream); + components[i]->update(target); } } } @@ -646,17 +637,17 @@ DecoupledBPUWithBTB::updatePredictorComponents(FetchStream &stream) void -DecoupledBPUWithBTB::squashStreamAfter(unsigned squash_stream_id) +DecoupledBPUWithBTB::squashTargetAfter(unsigned squash_target_id) { - // Erase all streams after the squashed one (id > squash_stream_id). - while (!fetchStreamQueue.empty() && backStreamId() > squash_stream_id) { - auto id = backStreamId(); - auto &stream = fetchStreamQueue.back(); - DPRINTF(DecoupleBP || stream.startPC == ObservingPC, - "Erasing stream %lu when squashing %d\n", id, - squash_stream_id); - printStream(stream); - fetchStreamQueue.pop_back(); + // Erase all targets after the squashed one (id > squash_target_id). + while (!fetchTargetQueue.empty() && backTargetId() > squash_target_id) { + auto id = backTargetId(); + auto &target = fetchTargetQueue.back(); + DPRINTF(DecoupleBP || target.startPC == ObservingPC, + "Erasing target %lu when squashing %d\n", id, + squash_target_id); + printTarget(target); + fetchTargetQueue.pop_back(); } } @@ -664,10 +655,10 @@ bool DecoupledBPUWithBTB::validateFSQEnqueue() { // Monitor FSQ size for statistics - dbpBtbStats.fsqEntryDist.sample(fetchStreamQueue.size(), 1); - if (streamQueueFull()) { + dbpBtbStats.fsqEntryDist.sample(fetchTargetQueue.size(), 1); + if (targetQueueFull()) { dbpBtbStats.fsqFullCannotEnq++; - DPRINTF(Override, "FSQ is full (%lu entries)\n", fetchStreamQueue.size()); + DPRINTF(Override, "FSQ is full (%lu entries)\n", fetchTargetQueue.size()); return false; } @@ -691,7 +682,7 @@ DecoupledBPUWithBTB::validateFSQEnqueue() } // Ensure FSQ has space for the new entry - assert(!streamQueueFull()); + assert(!targetQueueFull()); return true; } @@ -725,15 +716,15 @@ DecoupledBPUWithBTB::pHistShiftIn(int shamt, bool taken, boost::dynamic_bitset<> } /** - * @brief Creates a new FetchStream entry with prediction information + * @brief Creates a new FetchTarget entry with prediction information * - * @return FetchStream The created fetch stream + * @return FetchTarget The created fetch target */ -FetchStream -DecoupledBPUWithBTB::createFetchStreamEntry() +FetchTarget +DecoupledBPUWithBTB::createFetchTargetEntry() { - // Create a new fetch stream entry - FetchStream entry; + // Create a new fetch target entry + FetchTarget entry; entry.startPC = s0PC; // Extract branch prediction information @@ -741,7 +732,7 @@ DecoupledBPUWithBTB::createFetchStreamEntry() Addr fallThroughAddr = finalPred.getFallThrough(predictWidth); Addr nextPC = finalPred.getTarget(predictWidth); - // Configure stream entry with prediction details + // Configure target entry with prediction details entry.isHit = !finalPred.btbEntries.empty(); entry.falseHit = false; entry.predBTBEntries = finalPred.btbEntries; @@ -781,7 +772,7 @@ DecoupledBPUWithBTB::createFetchStreamEntry() * @brief fill ahead pipeline entry.previousPCs */ void -DecoupledBPUWithBTB::fillAheadPipeline(FetchStream &entry) +DecoupledBPUWithBTB::fillAheadPipeline(FetchTarget &entry) { // Handle ahead pipelined predictors unsigned max_ahead_pipeline_stages = 0; @@ -789,13 +780,13 @@ DecoupledBPUWithBTB::fillAheadPipeline(FetchStream &entry) max_ahead_pipeline_stages = std::max(max_ahead_pipeline_stages, components[i]->aheadPipelinedStages); } - // Get previous PCs from fetchStreamQueue if needed + // Get previous PCs from fetchTargetQueue if needed if (max_ahead_pipeline_stages > 0) { for (int i = 0; i < max_ahead_pipeline_stages; i++) { - auto id = fsqId - max_ahead_pipeline_stages + i; - if (hasStream(id)) { + auto id = ftqId - max_ahead_pipeline_stages + i; + if (hasTarget(id)) { // FIXME: it may not work well with jump ahead predictor - entry.previousPCs.push(getStream(id).getRealStartPC()); + entry.previousPCs.push(getTarget(id).getRealStartPC()); } } } @@ -807,8 +798,8 @@ DecoupledBPUWithBTB::processNewPrediction() { DPRINTF(DecoupleBP, "Creating new prediction for PC %#lx\n", s0PC); - // 1. Create a new fetch stream entry with prediction information - FetchStream entry = createFetchStreamEntry(); + // 1. Create a new fetch target entry with prediction information + FetchTarget entry = createFetchTargetEntry(); // 2. Update global PC state to target or fall-through s0PC = finalPred.getTarget(predictWidth);; @@ -819,25 +810,25 @@ DecoupledBPUWithBTB::processNewPrediction() // 4. Fill ahead pipeline fillAheadPipeline(entry); - // 5. Add entry to fetch stream queue - assert(fsqId == fetchStreamBaseId + fetchStreamQueue.size()); - fetchStreamQueue.push_back(entry); + // 5. Add entry to fetch target queue + assert(ftqId == fetchTargetBaseId + fetchTargetQueue.size()); + fetchTargetQueue.push_back(entry); //printf("curr tick: %lu\n", entry.predTick); //printf("curr fsqId: %lu\n", fsqId); // 6. Record prediction to database if enabled if (enablePredFSQTrace) { - predTraceManager->write_record(PredictionTrace(fsqId, entry)); + predTraceManager->write_record(PredictionTrace(ftqId, entry)); } // 7. Debug output and update statistics - dumpFsq("after insert new stream"); - DPRINTF(DecoupleBP, "Inserted fetch stream %lu starting at PC %#lx\n", - fsqId, entry.startPC); + dumpFsq("after insert new target"); + DPRINTF(DecoupleBP, "Inserted fetch target %lu starting at PC %#lx\n", + ftqId, entry.startPC); // 8. Update FSQ ID and increment statistics - fsqId++; - printStream(entry); + ftqId++; + printTarget(entry); dbpBtbStats.fsqEntryEnqueued++; } @@ -900,8 +891,8 @@ Addr DecoupledBPUWithBTB::getPreservedReturnAddr(const DynInstPtr &dynInst) { DPRINTF(DecoupleBP, "acquiring reutrn address for inst pc %#lx from decode\n", dynInst->pcState().instAddr()); - auto fsqid = dynInst->getFsqId(); - auto retAddr = ras->getTopAddrFromMetas(getStream(fsqid)); + auto fsqid = dynInst->getFtqId(); + auto retAddr = ras->getTopAddrFromMetas(getTarget(fsqid)); DPRINTF(DecoupleBP, "get ret addr %#lx\n", retAddr); return retAddr; } @@ -909,10 +900,10 @@ DecoupledBPUWithBTB::getPreservedReturnAddr(const DynInstPtr &dynInst) /** * @brief Updates global history based on prediction results * - * @param entry The fetch stream entry to update history for + * @param entry The fetch target entry to update history for */ void -DecoupledBPUWithBTB::updateHistoryForPrediction(FetchStream &entry) +DecoupledBPUWithBTB::updateHistoryForPrediction(FetchTarget &entry) { // Update component-specific history, for TAGE/ITTAGE/MGSC for (int i = 0; i < numComponents; i++) { @@ -936,7 +927,7 @@ DecoupledBPUWithBTB::updateHistoryForPrediction(FetchStream &entry) // Update history manager and verify TAGE folded history historyManager.addSpeculativeHist( - entry.startPC, shamt, taken, entry.predBranchInfo, fsqId); + entry.startPC, shamt, taken, entry.predBranchInfo, ftqId); // Get prediction information for global backward history updates int bw_shamt; @@ -975,8 +966,8 @@ DecoupledBPUWithBTB::updateHistoryForPrediction(FetchStream &entry) /** * @brief Recovers branch history during a squash event * - * @param stream The stream being squashed - * @param stream_id ID of the stream being squashed + * @param target The target being squashed + * @param target_id ID of the target being squashed * @param squash_pc PC where the squash occurred * @param is_conditional Whether the branch is conditional * @param actually_taken Whether the branch was actually taken @@ -984,41 +975,41 @@ DecoupledBPUWithBTB::updateHistoryForPrediction(FetchStream &entry) */ void DecoupledBPUWithBTB::recoverHistoryForSquash( - FetchStream &stream, - unsigned stream_id, + FetchTarget &target, + unsigned target_id, const PCStateBase &squash_pc, bool is_conditional, bool actually_taken, SquashType squash_type, Addr redirect_pc) { - //printf("recover stream_id: %u\n", stream_id); - // Restore history from the stream - s0History = stream.history; - s0PHistory = stream.phistory; - s0BwHistory = stream.bwhistory; - s0LHistory = stream.lhistory; + //printf("recover target_id: %u\n", target_id); + // Restore history from the target + s0History = target.history; + s0PHistory = target.phistory; + s0BwHistory = target.bwhistory; + s0LHistory = target.lhistory; // Get actual history shift information int real_shamt; bool real_taken; - std::tie(real_shamt, real_taken) = stream.getHistInfoDuringSquash( + std::tie(real_shamt, real_taken) = target.getHistInfoDuringSquash( squash_pc.instAddr(), is_conditional, actually_taken); // Get actual history shift information int real_bw_shamt; bool real_bw_taken; - std::tie(real_bw_shamt, real_bw_taken) = stream.getBwHistInfoDuringSquash( + std::tie(real_bw_shamt, real_bw_taken) = target.getBwHistInfoDuringSquash( squash_pc.instAddr(), is_conditional, actually_taken, redirect_pc); // Recover component-specific history for (int i = 0; i < numComponents; ++i) { - components[i]->recoverHist(s0History, stream, real_shamt, real_taken); - if(components[i]->needMoreHistories){ - components[i]->recoverPHist(s0PHistory, stream, real_shamt, real_taken); - components[i]->recoverBwHist(s0BwHistory, stream, real_bw_shamt, real_bw_taken); - components[i]->recoverIHist(stream, real_bw_shamt, real_bw_taken); - components[i]->recoverLHist(s0LHistory, stream, real_shamt, real_taken); + components[i]->recoverHist(s0History, target, real_shamt, real_taken); + if (components[i]->needMoreHistories){ + components[i]->recoverPHist(s0PHistory, target, real_shamt, real_taken); + components[i]->recoverBwHist(s0BwHistory, target, real_bw_shamt, real_bw_taken); + components[i]->recoverIHist(target, real_bw_shamt, real_bw_taken); + components[i]->recoverLHist(s0LHistory, target, real_shamt, real_taken); } } @@ -1033,13 +1024,13 @@ DecoupledBPUWithBTB::recoverHistoryForSquash( // Update local history with actual outcome histShiftIn(real_shamt, real_taken, - s0LHistory[mgsc->getPcIndex(stream.startPC, log2(mgsc->getNumEntriesFirstLocalHistories()))]); + s0LHistory[mgsc->getPcIndex(target.startPC, log2(mgsc->getNumEntriesFirstLocalHistories()))]); // Update history manager with appropriate branch info if (squash_type == SQUASH_CTRL) { - historyManager.squash(stream_id, real_shamt, real_taken, stream.exeBranchInfo); + historyManager.squash(target_id, real_shamt, real_taken, target.exeBranchInfo); } else { - historyManager.squash(stream_id, real_shamt, real_taken, BranchInfo()); + historyManager.squash(target_id, real_shamt, real_taken, BranchInfo()); } // Perform history consistency checks when not a fast build variant diff --git a/src/cpu/pred/btb/decoupled_bpred.hh b/src/cpu/pred/btb/decoupled_bpred.hh index a57a5ca235..576b0fce39 100644 --- a/src/cpu/pred/btb/decoupled_bpred.hh +++ b/src/cpu/pred/btb/decoupled_bpred.hh @@ -15,17 +15,17 @@ #include "cpu/o3/dyn_inst_ptr.hh" #include "cpu/pred/bpred_unit.hh" #include "cpu/pred/btb/abtb.hh" -#include "cpu/pred/btb/mbtb.hh" #include "cpu/pred/btb/btb_ittage.hh" +#include "cpu/pred/btb/btb_mgsc.hh" #include "cpu/pred/btb/btb_tage.hh" #include "cpu/pred/btb/btb_ubtb.hh" -#include "cpu/pred/btb/btb_mgsc.hh" +#include "cpu/pred/btb/mbtb.hh" #include "cpu/pred/btb/ras.hh" #include "cpu/pred/general_arch_db.hh" // #include "cpu/pred/btb/uras.hh" +#include "cpu/pred/btb/common.hh" #include "cpu/pred/btb/history_manager.hh" -#include "cpu/pred/btb/stream_struct.hh" #include "cpu/pred/btb/timed_base_pred.hh" #include "debug/DBPBTBStats.hh" #include "debug/DecoupleBP.hh" @@ -51,7 +51,6 @@ using CPU = o3::CPU; * This predictor implements a decoupled front-end with: * - Multiple prediction stages (UBTB -> BTB/TAGE/ITTAGE) * - Fetch Target Queue (FTQ) for managing predicted targets - * - Fetch Stream Queue (FSQ) for managing instruction streams * - Support for loop prediction and jump-ahead prediction */ class DecoupledBPUWithBTB : public BPredUnit @@ -64,11 +63,11 @@ class DecoupledBPUWithBTB : public BPredUnit private: // FSQ storage: a simple FIFO queue with implicit IDs (baseId + index), // which is closer to RTL than std::map and makes "head" explicit. - std::deque fetchStreamQueue; - FetchStreamId fetchStreamBaseId{1}; // ID of fetchStreamQueue.front() - unsigned fetchStreamQueueSize; - FetchStreamId fsqId{1}; // next FSQ id to allocate (monotonic) - FetchStreamId fetchHeadFsqId{1}; // next FSQ id to be consumed by fetch + unsigned fetchTargetQueueSize; + std::deque fetchTargetQueue; + FetchTargetId fetchTargetBaseId{1}; // ID of fetchTargetQueue.front() + FetchTargetId ftqId{1}; // next FSQ id to allocate (monotonic) + FetchTargetId fetchHeadFtqId{1}; // next FSQ id to be consumed by fetch CPU *cpu; @@ -128,7 +127,7 @@ class DecoupledBPUWithBTB : public BPredUnit BpuState bpuState; Addr s0PC; ///< Current PC - // Addr s0StreamStartPC; + // Addr s0targetStartPC; boost::dynamic_bitset<> s0History; ///< global History bits boost::dynamic_bitset<> s0PHistory; ///< path History bits boost::dynamic_bitset<> s0BwHistory; ///< global backward History bits @@ -150,11 +149,11 @@ class DecoupledBPUWithBTB : public BPredUnit void processNewPrediction(); - FetchStream createFetchStreamEntry(); + FetchTarget createFetchTargetEntry(); - void updateHistoryForPrediction(FetchStream &entry); + void updateHistoryForPrediction(FetchTarget &entry); - void fillAheadPipeline(FetchStream &entry); + void fillAheadPipeline(FetchTarget &entry); // Tick helper functions void requestNewPrediction(); @@ -164,12 +163,12 @@ class DecoupledBPUWithBTB : public BPredUnit void pHistShiftIn(int shamt, bool taken, boost::dynamic_bitset<> &history, Addr pc, Addr target); - void printStream(const FetchStream &e) + void printTarget(const FetchTarget &e) { if (!e.resolved) { - DPRINTFR(DecoupleBPProbe, "FSQ Predicted stream: "); + DPRINTFR(DecoupleBPProbe, "FSQ Predicted target: "); } else { - DPRINTFR(DecoupleBPProbe, "FSQ Resolved stream: "); + DPRINTFR(DecoupleBPProbe, "FSQ Resolved target: "); } // TODO:fix this DPRINTFR(DecoupleBPProbe, @@ -178,7 +177,7 @@ class DecoupledBPUWithBTB : public BPredUnit e.getTakenTarget(), e.getTaken()); } - void printStreamFull(const FetchStream &e) + void printTargetFull(const FetchTarget &e) { // TODO: fix this // DPRINTFR( @@ -187,50 +186,43 @@ class DecoupledBPUWithBTB : public BPredUnit // e.startPC, e.predBranchPC, e.predEndPC, e.predTarget); // DPRINTFR( // DecoupleBP, - // "Resolved: %i, resolved stream:: %#lx-[%#lx, %#lx) --> %#lx\n", + // "Resolved: %i, resolved target:: %#lx-[%#lx, %#lx) --> %#lx\n", // e.exeEnded, e.startPC, e.exeBranchPC, e.exeEndPC, // e.exeTarget); } - bool streamQueueFull() const + bool targetQueueFull() const { - return fetchStreamQueue.size() >= fetchStreamQueueSize; + return fetchTargetQueue.size() >= fetchTargetQueueSize; } bool - hasStream(FetchStreamId id) const + hasTarget(FetchTargetId id) const { - return !fetchStreamQueue.empty() && - id >= fetchStreamBaseId && - id < fetchStreamBaseId + fetchStreamQueue.size(); + return !fetchTargetQueue.empty() && + id >= fetchTargetBaseId && + id < fetchTargetBaseId + fetchTargetQueue.size(); } - FetchStream& - getStream(FetchStreamId id) + FetchTarget& + getTarget(FetchTargetId id) { - assert(hasStream(id)); - return fetchStreamQueue[id - fetchStreamBaseId]; + assert(hasTarget(id)); + return fetchTargetQueue[id - fetchTargetBaseId]; } - const FetchStream& - getStream(FetchStreamId id) const + FetchTargetId + frontTargetId() const { - assert(hasStream(id)); - return fetchStreamQueue[id - fetchStreamBaseId]; + assert(!fetchTargetQueue.empty()); + return fetchTargetBaseId; } - FetchStreamId - frontStreamId() const + FetchTargetId + backTargetId() const { - assert(!fetchStreamQueue.empty()); - return fetchStreamBaseId; - } - - FetchStreamId - backStreamId() const - { - assert(!fetchStreamQueue.empty()); - return fetchStreamBaseId + fetchStreamQueue.size() - 1; + assert(!fetchTargetQueue.empty()); + return fetchTargetBaseId + fetchTargetQueue.size() - 1; } /** @@ -389,7 +381,7 @@ class DecoupledBPUWithBTB : public BPredUnit void setCpu(CPU *_cpu) { cpu = _cpu; } - void consumeFetchTarget(unsigned ftq_id, unsigned fsq_id, unsigned fetched_inst_num); + void consumeFetchTarget(unsigned fetched_inst_num); struct BpTrace : public Record { @@ -406,7 +398,7 @@ class DecoupledBPUWithBTB : public BPredUnit _uint64_data["source"] = source; _uint64_data["target"] = target; } - BpTrace(uint64_t fsqId, FetchStream &stream, const DynInstPtr &inst, bool mispred); + BpTrace(uint64_t fsqId, FetchTarget &target, const DynInstPtr &inst, bool mispred); }; // Prediction trace record for tracking prediction-time information @@ -425,7 +417,7 @@ class DecoupledBPUWithBTB : public BPredUnit _uint64_data["btbHit"] = btbHit; } - PredictionTrace(uint64_t id, const FetchStream &entry) { + PredictionTrace(uint64_t id, const FetchTarget &entry) { _tick = curTick(); set(id, entry.startPC, entry.predTaken, entry.predEndPC, entry.getControlPC(), entry.getTakenTarget(), @@ -433,8 +425,8 @@ class DecoupledBPUWithBTB : public BPredUnit } }; - // redirect the stream - void controlSquash(unsigned ftq_id, unsigned fsq_id, + // redirect the target + void controlSquash(unsigned fsq_id, const PCStateBase &control_pc, const PCStateBase &target_pc, const StaticInstPtr &static_inst, unsigned inst_bytes, @@ -442,25 +434,24 @@ class DecoupledBPUWithBTB : public BPredUnit ThreadID tid, const unsigned ¤tLoopIter, const bool fromCommit); - // keep the stream: original prediction might be right - // For memory violation, stream continues after squashing - void nonControlSquash(unsigned ftq_id, unsigned fsq_id, + // keep the target: original prediction might be right + // For memory violation, target continues after squashing + void nonControlSquash(unsigned fsq_id, const PCStateBase &inst_pc, const InstSeqNum seq, ThreadID tid, const unsigned ¤tLoopIter); - // Not a control. But stream is actually disturbed - void trapSquash(unsigned ftq_id, unsigned fsq_id, Addr last_committed_pc, + // Not a control. But target is actually disturbed + void trapSquash(unsigned fsq_id, Addr last_committed_pc, const PCStateBase &inst_pc, ThreadID tid, const unsigned ¤tLoopIter); void update(unsigned fsqID, ThreadID tid); - void squashStreamAfter(unsigned squash_stream_id); + void squashTargetAfter(unsigned squash_target_id); // Fetch-facing interface: consume FSQ head directly (RTL-like single queue). - bool fsqHasHead() const { return hasStream(fetchHeadFsqId); } - FetchStreamId fsqHeadId() const { assert(fsqHasHead()); return fetchHeadFsqId; } - const FetchStream &fsqHead() const { assert(fsqHasHead()); return getStream(fetchHeadFsqId); } - FetchTargetId fsqHeadFtqId() const { assert(fsqHasHead()); return fetchHeadFsqId - 1; } + bool ftqHasHead() const { return hasTarget(fetchHeadFtqId); } + FetchTargetId ftqHeadId() const { assert(ftqHasHead()); return fetchHeadFtqId; } + const FetchTarget &ftqHead() { assert(ftqHasHead()); return getTarget(fetchHeadFtqId); } void dumpFsq(const char *when); @@ -486,8 +477,6 @@ class DecoupledBPUWithBTB : public BPredUnit Addr getPreservedReturnAddr(const DynInstPtr &dynInst); - std::stack streamRAS; - std::unordered_map takenBranches; // branch address -> taken count std::unordered_map currentPhaseTakenBranches; std::unordered_map currentSubPhaseTakenBranches; @@ -744,8 +733,8 @@ class DecoupledBPUWithBTB : public BPredUnit // std::vector> takenBranchesBySubPhase; void recoverHistoryForSquash( - FetchStream &stream, - unsigned stream_id, + FetchTarget &target, + unsigned target_id, const PCStateBase &squash_pc, bool is_conditional, bool actually_taken, @@ -754,7 +743,6 @@ class DecoupledBPUWithBTB : public BPredUnit // Common logic for squash handling void handleSquash(unsigned target_id, - unsigned stream_id, SquashType squash_type, const PCStateBase &squash_pc, Addr redirect_pc, @@ -766,11 +754,11 @@ class DecoupledBPUWithBTB : public BPredUnit void resetPC(Addr new_pc); // Helper functions for update - bool resolveUpdate(unsigned &stream_id); - void prepareResolveUpdateEntries(unsigned &stream_id); - void markCFIResolved(unsigned &stream_id, uint64_t resolvedInstPC); - void updatePredictorComponents(FetchStream &stream); - void updateStatistics(const FetchStream &stream); + bool resolveUpdate(unsigned &target_id); + void prepareResolveUpdateEntries(unsigned &target_id); + void markCFIResolved(unsigned &target, uint64_t resolvedInstPC); + void updatePredictorComponents(FetchTarget &target); + void updateStatistics(const FetchTarget &target); void notifyResolveSuccess(); void notifyResolveFailure(); void blockPredictionOnce(); @@ -851,19 +839,19 @@ class DecoupledBPUWithBTB : public BPredUnit void commitBranch(const DynInstPtr &inst, bool miss); - void commitPredWrongSource(const FetchStream &entry); + void commitPredWrongSource(const FetchTarget &entry); /** * @brief Process branch misprediction, determine type and update statistics * - * @param entry The fetch stream entry + * @param entry The fetch target entry * @param branchAddr Branch instruction address * @param info Branch information * @param taken Whether the branch was taken * @param mispred Whether the branch was mispredicted */ void processMisprediction( - const FetchStream &entry, + const FetchTarget &entry, Addr branchAddr, const BranchInfo &info, bool taken, diff --git a/src/cpu/pred/btb/decoupled_bpred_stats.cc b/src/cpu/pred/btb/decoupled_bpred_stats.cc index 581aa56be6..cd6b625322 100644 --- a/src/cpu/pred/btb/decoupled_bpred_stats.cc +++ b/src/cpu/pred/btb/decoupled_bpred_stats.cc @@ -336,15 +336,15 @@ DecoupledBPUWithBTB::dumpStats() } } -DecoupledBPUWithBTB::BpTrace::BpTrace(uint64_t fsqId, FetchStream &stream, const DynInstPtr &inst, bool mispred) +DecoupledBPUWithBTB::BpTrace::BpTrace(uint64_t fsqId, FetchTarget &target, const DynInstPtr &inst, bool mispred) { _tick = curTick(); Addr pc = inst->pcState().instAddr(); const auto &rv_pc = inst->pcState().as(); - Addr target = rv_pc.npc(); + Addr targetpc = rv_pc.npc(); Addr fallThru = rv_pc.getFallThruPC(); - BranchInfo info(pc, target, inst->staticInst, fallThru-pc); - set(fsqId, stream.startPC, pc, info.getType(), inst->branching(), mispred, fallThru, stream.predSource, target); + BranchInfo info(pc, targetpc, inst->staticInst, fallThru-pc); + set(fsqId, target.startPC, pc, info.getType(), inst->branching(), mispred, fallThru, target.predSource, targetpc); // for (auto it = _uint64_data.begin(); it != _uint64_data.end(); it++) { // printf("%s: %ld\n", it->first.c_str(), it->second); // } @@ -421,7 +421,7 @@ DecoupledBPUWithBTB::DBPBTBStats::DBPBTBStats( ADD_STAT(overrideBubbleNum, statistics::units::Count::get(), "the number of override bubbles"), ADD_STAT(overrideCount, statistics::units::Count::get(), "the number of overrides"), ADD_STAT(commitPredsFromEachStage, statistics::units::Count::get(), - "the number of preds of each stage that account for a committed stream"), + "the number of preds of each stage that account for a committed target"), ADD_STAT(commitOverrideBubbleNum, statistics::units::Count::get(), "the number of override bubbles, on the commit path"), ADD_STAT(commitOverrideCount, statistics::units::Count::get(), "the number of overrides, on the commit path"), @@ -626,10 +626,10 @@ void DecoupledBPUWithBTB::dumpFsq(const char *when) { DPRINTF(DecoupleBPProbe, "dumping fsq entries %s...\n", when); - for (size_t i = 0; i < fetchStreamQueue.size(); ++i) { - DPRINTFR(DecoupleBPProbe, "StreamID %lu, ", - static_cast(fetchStreamBaseId + i)); - printStream(fetchStreamQueue[i]); + for (size_t i = 0; i < fetchTargetQueue.size(); ++i) { + DPRINTFR(DecoupleBPProbe, "TargetID %lu, ", + static_cast(fetchTargetBaseId + i)); + printTarget(fetchTargetQueue[i]); } } @@ -692,82 +692,82 @@ DecoupledBPUWithBTB::addControlSquashCommitStat(BranchClass cls) } void -DecoupledBPUWithBTB::updateStatistics(const FetchStream &stream) +DecoupledBPUWithBTB::updateStatistics(const FetchTarget &target) { - // Check if this stream was mispredicted - bool miss_predicted = stream.squashType == SQUASH_CTRL; + // Check if this target was mispredicted + bool miss_predicted = target.squashType == SQUASH_CTRL; // Track indirect mispredictions - if (miss_predicted && stream.exeBranchInfo.isIndirect) { - topMispredIndirect[stream.startPC]++; + if (miss_predicted && target.exeBranchInfo.isIndirect) { + topMispredIndirect[target.startPC]++; } // --- BTB Statistics --- - if (stream.isHit) { + if (target.isHit) { // Count BTB hits dbpBtbStats.btbHit++; } else { // Count BTB misses for taken branches - if (stream.exeTaken) { + if (target.exeTaken) { dbpBtbStats.btbMiss++; - DPRINTF(BTB, "BTB miss detected when update, stream start %#lx, predTick %lu, printing branch info:\n", - stream.startPC, stream.predTick); - auto &slot = stream.exeBranchInfo; + DPRINTF(BTB, "BTB miss detected when update, target start %#lx, predTick %lu, printing branch info:\n", + target.startPC, target.predTick); + auto &slot = target.exeBranchInfo; DPRINTF(BTB, " pc:%#lx, size:%d, target:%#lx, cond:%d, indirect:%d, call:%d, return:%d\n", slot.pc, slot.size, slot.target, slot.isCond, slot.isIndirect, slot.isCall, slot.isReturn); } // Count false hits - if (stream.falseHit) { + if (target.falseHit) { dbpBtbStats.commitFalseHit++; } } - if (stream.isHit || stream.exeTaken) { + if (target.isHit || target.exeTaken) { // Update BTB entry statistics - auto it = totalBTBEntries.find(stream.startPC); + auto it = totalBTBEntries.find(target.startPC); if (it == totalBTBEntries.end()) { - auto &btb_entry = stream.updateNewBTBEntry; - totalBTBEntries[stream.startPC] = std::make_pair(btb_entry, 1); + auto &btb_entry = target.updateNewBTBEntry; + totalBTBEntries[target.startPC] = std::make_pair(btb_entry, 1); dbpBtbStats.btbEntriesWithDifferentStart++; } else { it->second.second++; - it->second.first = stream.updateNewBTBEntry; + it->second.first = target.updateNewBTBEntry; } } // Track which predictor stage was used - dbpBtbStats.commitPredsFromEachStage[stream.predSource]++; - overrideStats(stream.overrideReason); + dbpBtbStats.commitPredsFromEachStage[target.predSource]++; + overrideStats(target.overrideReason); // --- Instruction Statistics --- // Track committed instruction counts - dbpBtbStats.commitFsqEntryHasInsts.sample(stream.commitInstNum, 1); - if (stream.commitInstNum >= 0 && stream.commitInstNum <= maxInstsNum) { - commitFsqEntryHasInstsVector[stream.commitInstNum]++; - if (stream.commitInstNum == 1 && stream.exeBranchInfo.isUncond()) { + dbpBtbStats.commitFsqEntryHasInsts.sample(target.commitInstNum, 1); + if (target.commitInstNum >= 0 && target.commitInstNum <= maxInstsNum) { + commitFsqEntryHasInstsVector[target.commitInstNum]++; + if (target.commitInstNum == 1 && target.exeBranchInfo.isUncond()) { dbpBtbStats.commitFsqEntryOnlyHasOneJump++; } } // Track fetched instruction counts - dbpBtbStats.commitFsqEntryFetchedInsts.sample(stream.fetchInstNum, 1); - if (stream.fetchInstNum >= 0 && stream.fetchInstNum <= maxInstsNum) { - commitFsqEntryFetchedInstsVector[stream.fetchInstNum]++; + dbpBtbStats.commitFsqEntryFetchedInsts.sample(target.fetchInstNum, 1); + if (target.fetchInstNum >= 0 && target.fetchInstNum <= maxInstsNum) { + commitFsqEntryFetchedInstsVector[target.fetchInstNum]++; } // --- Misprediction Statistics --- // Track control squashes (mispredictions) - if (stream.squashType == SQUASH_CTRL) { + if (target.squashType == SQUASH_CTRL) { // Record mispredict pair (start PC, branch PC) - auto find_it = topMispredicts.find(std::make_pair(stream.startPC, stream.exeBranchInfo.pc)); + auto find_it = topMispredicts.find(std::make_pair(target.startPC, target.exeBranchInfo.pc)); if (find_it == topMispredicts.end()) { - topMispredicts[std::make_pair(stream.startPC, stream.exeBranchInfo.pc)] = 1; + topMispredicts[std::make_pair(target.startPC, target.exeBranchInfo.pc)] = 1; } else { find_it->second++; } // Track history pattern for mispredictions - auto hist(stream.history); + auto hist(target.history); hist.resize(18); uint64_t pattern = hist.to_ulong(); auto find_it_hist = topMispredHist.find(pattern); @@ -798,12 +798,12 @@ DecoupledBPUWithBTB::commitBranch(const DynInstPtr &inst, bool mispred) auto branchClass = classifyBranch(inst); addBranchClassStat(branchClass, mispred); - // ---------- Find corresponding fetch stream entry ---------- - auto entry = getStream(inst->fsqId); + // ---------- Find corresponding fetch target entry ---------- + auto entry = getTarget(inst->ftqId); // Record branch trace if enabled if (enableBranchTrace) { - bptrace->write_record(BpTrace(inst->fsqId, entry, inst, mispred)); + bptrace->write_record(BpTrace(inst->ftqId, entry, inst, mispred)); } // ---------- Extract branch information ---------- @@ -835,7 +835,7 @@ DecoupledBPUWithBTB::commitBranch(const DynInstPtr &inst, bool mispred) } void -DecoupledBPUWithBTB::commitPredWrongSource(const FetchStream &entry) +DecoupledBPUWithBTB::commitPredWrongSource(const FetchTarget &entry) { int ubtbid = ubtb->getComponentIdx(); int abtbid = abtb->getComponentIdx(); @@ -912,15 +912,15 @@ DecoupledBPUWithBTB::commitPredWrongSource(const FetchStream &entry) void DecoupledBPUWithBTB::notifyInstCommit(const DynInstPtr &inst) { - // Update committed instruction count for stream - getStream(inst->fsqId).commitInstNum++; + // Update committed instruction count for target + getTarget(inst->ftqId).commitInstNum++; // Update global committed instruction count numInstCommitted++; DPRINTF(Profiling, "notifyInstCommit, inst=%s, commitInstNum=%d\n", inst->staticInst->disassemble(inst->pcState().instAddr()), - getStream(inst->fsqId).commitInstNum); + getTarget(inst->ftqId).commitInstNum); // ----------------------- Main Phase Processing ------------------------- if (numInstCommitted % phaseSizeByInst == 0) { @@ -963,7 +963,7 @@ DecoupledBPUWithBTB::notifyInstCommit(const DynInstPtr &inst) /** * @brief Process branch misprediction, determine type and update statistics * - * @param entry The fetch stream entry + * @param entry The fetch target entry * @param branchAddr Branch instruction address * @param info Branch information * @param taken Whether the branch was taken @@ -971,7 +971,7 @@ DecoupledBPUWithBTB::notifyInstCommit(const DynInstPtr &inst) */ void DecoupledBPUWithBTB::processMisprediction( - const FetchStream &entry, + const FetchTarget &entry, Addr branchAddr, const BranchInfo &info, bool taken, diff --git a/src/cpu/pred/btb/docs/RAS.md b/src/cpu/pred/btb/docs/RAS.md index f7eaa96376..8b761f6ba9 100644 --- a/src/cpu/pred/btb/docs/RAS.md +++ b/src/cpu/pred/btb/docs/RAS.md @@ -111,7 +111,7 @@ void specUpdateHist(const boost::dynamic_bitset<> &history, FullBTBPrediction &p ### 3. Recovery Phase (`recoverHist`) ```cpp -void recoverHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, +void recoverHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) ``` @@ -122,7 +122,7 @@ void recoverHist(const boost::dynamic_bitset<> &history, const FetchStream &entr ### 4. Commit Phase (`update`) ```cpp -void update(const FetchStream &entry) +void update(const FetchTarget &entry) ``` - **For Call Instructions**: Executes `push_stack(retAddr)` diff --git a/src/cpu/pred/btb/docs/btb.md b/src/cpu/pred/btb/docs/btb.md index 34a008d586..74e1904b7a 100644 --- a/src/cpu/pred/btb/docs/btb.md +++ b/src/cpu/pred/btb/docs/btb.md @@ -168,7 +168,7 @@ The update process: - For indirect branches, update target ```cpp -void update(const FetchStream &stream) { +void update(const FetchTarget &stream) { // 1. Process old entries auto old_entries = processOldEntries(stream); @@ -221,7 +221,7 @@ auto meta = btb->getPredictionMeta(); ### 5.2 Update Phase ```cpp // Setup update stream -FetchStream stream; +FetchTarget stream; stream.startPC = pc; stream.predMetas[0] = meta; diff --git a/src/cpu/pred/btb/docs/btb_tage.md b/src/cpu/pred/btb/docs/btb_tage.md index 616358b141..77e79a01e6 100644 --- a/src/cpu/pred/btb/docs/btb_tage.md +++ b/src/cpu/pred/btb/docs/btb_tage.md @@ -136,7 +136,7 @@ The update process involves: 4. Allocating new entries on mispredictions ```cpp -void update(const FetchStream &stream) { +void update(const FetchTarget &stream) { Addr startAddr = stream.getRealStartPC(); // Prepare entries to update @@ -195,7 +195,7 @@ void specUpdateHist(const boost::dynamic_bitset<> &history, FullBTBPrediction &p doUpdateHist(history, shamt, cond_taken); } -void recoverHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, bool cond_taken) { +void recoverHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) { std::shared_ptr predMeta = std::static_pointer_cast( entry.predMetas[getComponentIdx()]); @@ -317,7 +317,7 @@ When the branch is resolved and found to be correctly predicted: ```cpp // Setup update stream with actual outcome -FetchStream stream; +FetchTarget stream; stream.startPC = pc; stream.exeBranchInfo = branch_info; stream.exeTaken = actual_taken; @@ -332,7 +332,7 @@ When a misprediction is detected, history must be recovered: ```cpp // Setup recovery stream -FetchStream recoverStream; +FetchTarget recoverStream; recoverStream.startPC = pc; recoverStream.exeBranchInfo = branch_info; recoverStream.exeTaken = actual_taken; diff --git a/src/cpu/pred/btb/docs/decoupled_bpred.md b/src/cpu/pred/btb/docs/decoupled_bpred.md index d9c6a940df..2f993ca9b9 100644 --- a/src/cpu/pred/btb/docs/decoupled_bpred.md +++ b/src/cpu/pred/btb/docs/decoupled_bpred.md @@ -63,10 +63,10 @@ struct FullBTBPrediction { ### 4. Fetch Management Structures -#### FetchStream +#### FetchTarget Manages prediction and execution information for a continuous instruction sequence: ```cpp -struct FetchStream { +struct FetchTarget { // Basic information Addr startPC; // Start address Addr predEndPC; // Predicted end address @@ -95,7 +95,7 @@ struct FtqEntry { Addr takenPC; // Branch instruction address bool taken; // Branch taken flag Addr target; // Jump target - FetchStreamId fsqID; // Corresponding fetch stream ID + FetchTargetId fsqID; // Corresponding fetch stream ID // Loop related bool inLoop; // In loop flag @@ -107,7 +107,7 @@ struct FtqEntry { ### 5. Queue Management - `FetchTargetQueue`: Manages fetch targets (FTQ) -- `std::map fetchStreamQueue`: Manages fetch streams (FSQ) +- `std::map FetchTargetQueue`: Manages fetch streams (FSQ) ## Key Functions @@ -127,7 +127,7 @@ Main prediction cycle function that: - Calculates necessary bubbles - Updates prediction state -#### `tryEnqFetchStream()` +#### `tryEnqFetchTarget()` - Checks for new prediction results - Creates new fetch streams - Updates prediction state @@ -135,7 +135,7 @@ Main prediction cycle function that: #### `processNewPrediction()` - Uses various predictor components for prediction - Integrates prediction results -- Creates new FetchStream entries +- Creates new FetchTarget entries #### `tryEnqFetchTarget()` - Adds prediction results to FTQ @@ -211,9 +211,9 @@ In each clock cycle: - Stores results in `finalPred` - Sets `receivedPred = true` -3. **FSQ enqueue stage** (`tryEnqFetchStream`) - - Creates new `FetchStream` entries - - Adds entries to `fetchStreamQueue`, assigns `fsqId` +3. **FSQ enqueue stage** (`tryEnqFetchTarget`) + - Creates new `FetchTarget` entries + - Adds entries to `FetchTargetQueue`, assigns `fsqId` - Updates global history based on predictions - Resets `receivedPred = false` - Increments `fsqId` for the next stream diff --git a/src/cpu/pred/btb/folded_hist.hh b/src/cpu/pred/btb/folded_hist.hh index 5fb7d40d26..1306443659 100644 --- a/src/cpu/pred/btb/folded_hist.hh +++ b/src/cpu/pred/btb/folded_hist.hh @@ -8,7 +8,7 @@ #include "base/types.hh" #include "cpu/inst_seq.hh" -#include "cpu/pred/btb/stream_struct.hh" +#include "cpu/pred/btb/common.hh" namespace gem5 { diff --git a/src/cpu/pred/btb/history_manager.hh b/src/cpu/pred/btb/history_manager.hh index 7eb6d7192c..2c2da59146 100644 --- a/src/cpu/pred/btb/history_manager.hh +++ b/src/cpu/pred/btb/history_manager.hh @@ -3,7 +3,7 @@ #include -#include "cpu/pred/btb/stream_struct.hh" +#include "cpu/pred/btb/common.hh" #ifdef UNIT_TEST #include "cpu/pred/btb/test/test_dprintf.hh" diff --git a/src/cpu/pred/btb/mbtb.cc b/src/cpu/pred/btb/mbtb.cc index d08c87924f..4ab8445677 100644 --- a/src/cpu/pred/btb/mbtb.cc +++ b/src/cpu/pred/btb/mbtb.cc @@ -322,7 +322,7 @@ void MBTB::specUpdateHist(const boost::dynamic_bitset<> &history, FullBTBPrediction &pred) {} void -MBTB::recoverHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, bool cond_taken) +MBTB::recoverHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) { // MBTB doesn't support ahead-pipelined stages, nothing to recover } @@ -416,7 +416,7 @@ MBTB::lookup(Addr block_pc, std::shared_ptr meta) * Note: This is only called in L1 BTB during update */ void -MBTB::getAndSetNewBTBEntry(FetchStream &stream) +MBTB::getAndSetNewBTBEntry(FetchTarget &stream) { DPRINTF(BTB, "getAndSetNewBTBEntry called for pc %#lx\n", stream.startPC); // Get prediction metadata from previous stages @@ -469,7 +469,7 @@ MBTB::getAndSetNewBTBEntry(FetchStream &stream) * Also check BTB prediction status */ void -MBTB::checkPredictionHit(const FetchStream &stream, const BTBMeta* meta) +MBTB::checkPredictionHit(const FetchTarget &stream, const BTBMeta* meta) { bool pred_branch_hit = false; for (auto &e : meta->hit_entries) { @@ -497,7 +497,7 @@ MBTB::checkPredictionHit(const FetchStream &stream, const BTBMeta* meta) * 5. Update MRU information */ void -MBTB::updateBTBEntry(const BTBEntry& entry, const FetchStream &stream) +MBTB::updateBTBEntry(const BTBEntry& entry, const FetchTarget &stream) { btbStats.updateTotal++; // Select SRAM based on entry PC's 32B-aligned address @@ -556,7 +556,7 @@ MBTB::updateBTBEntry(const BTBEntry& entry, const FetchStream &stream) BTBEntry MBTB::buildUpdatedEntry(const BTBEntry& req_entry, const BTBEntry* existing_entry, - const FetchStream &stream) + const FetchTarget &stream) { // For conditional branches, prefer the existing entry to preserve up-to-date ctr auto entry_to_write = (req_entry.isCond && existing_entry) @@ -681,7 +681,7 @@ MBTB::commitToVictimCache(int vc_idx, const TickedBTBEntry &ticked_entry) * 5. Update MRU information */ void -MBTB::update(const FetchStream &stream) +MBTB::update(const FetchTarget &stream) { DPRINTF(BTB, "BTB: update called for pc %#lx\n", stream.startPC); // 1. Check prediction hit status, for stats recording @@ -695,7 +695,7 @@ MBTB::update(const FetchStream &stream) } std::vector -MBTB::prepareUpdateEntries(const FetchStream &stream) { +MBTB::prepareUpdateEntries(const FetchTarget &stream) { auto all_entries = stream.updateBTBEntries; // Add potential new BTB entry if it's a btb miss during prediction @@ -802,7 +802,7 @@ MBTB::insertVictimCache(const TickedBTBEntry& evicted_entry) #ifndef UNIT_TEST void -MBTB::commitBranch(const FetchStream &stream, const DynInstPtr &inst) +MBTB::commitBranch(const FetchTarget &stream, const DynInstPtr &inst) { auto meta = std::static_pointer_cast(stream.predMetas[getComponentIdx()]); auto &hit_entries = meta->hit_entries; diff --git a/src/cpu/pred/btb/mbtb.hh b/src/cpu/pred/btb/mbtb.hh index 91c3d8b65a..d736d0f55c 100644 --- a/src/cpu/pred/btb/mbtb.hh +++ b/src/cpu/pred/btb/mbtb.hh @@ -43,7 +43,7 @@ #include #include "base/types.hh" -#include "cpu/pred/btb/stream_struct.hh" +#include "cpu/pred/btb/common.hh" #include "cpu/pred/btb/timed_base_pred.hh" // Conditional includes based on build mode @@ -125,7 +125,7 @@ class MBTB : public TimedBaseBTBPredictor void tick() override; - void commitBranch(const FetchStream &stream, const DynInstPtr &inst) override; + void commitBranch(const FetchTarget &stream, const DynInstPtr &inst) override; void setTrace() override; TraceManager *btbTrace; #endif @@ -153,7 +153,7 @@ class MBTB : public TimedBaseBTBPredictor void specUpdateHist(const boost::dynamic_bitset<> &history, FullBTBPrediction &pred) override; void recoverHist(const boost::dynamic_bitset<> &history, - const FetchStream &entry, int shamt, bool cond_taken) override; + const FetchTarget &entry, int shamt, bool cond_taken) override; /** * @brief derive new btb entry from old ones and set updateNewBTBEntry field in stream @@ -161,7 +161,7 @@ class MBTB : public TimedBaseBTBPredictor * * @param stream */ - void getAndSetNewBTBEntry(FetchStream &stream); + void getAndSetNewBTBEntry(FetchTarget &stream); /** Updates the BTB with the branch info of a block and execution result. * This function: @@ -169,9 +169,9 @@ class MBTB : public TimedBaseBTBPredictor * 2. Adds new entries if necessary * 3. Updates MRU information */ - void update(const FetchStream &stream) override; + void update(const FetchTarget &stream) override; - std::vector prepareUpdateEntries(const FetchStream &stream); + std::vector prepareUpdateEntries(const FetchTarget &stream); void printBTBEntry(const BTBEntry &e, uint64_t tick = 0) { DPRINTF(BTB, "BTB entry: valid %d, pc:%#lx, tag: %#lx, size:%d, target:%#lx, \ @@ -274,19 +274,19 @@ class MBTB : public TimedBaseBTBPredictor * @param stream Fetch stream containing execution results * @param meta BTB metadata from prediction */ - void checkPredictionHit(const FetchStream &stream, + void checkPredictionHit(const FetchTarget &stream, const BTBMeta* meta); /** Update or replace BTB entry * @param entry Entry to update/replace (PC used to select SRAM and calculate index/tag) * @param stream Fetch stream with update info */ - void updateBTBEntry(const BTBEntry& entry, const FetchStream &stream); + void updateBTBEntry(const BTBEntry& entry, const FetchTarget &stream); // Helper: build updated entry (ctr/alwaysTaken/indirect target/tag) BTBEntry buildUpdatedEntry(const BTBEntry& req_entry, const BTBEntry* existing_entry, - const FetchStream &stream); + const FetchTarget &stream); // Helper: update an existing entry in SRAM set void updateExistingInSRAMSet(Addr btb_idx, diff --git a/src/cpu/pred/btb/ras.cc b/src/cpu/pred/btb/ras.cc index 33b47190a3..4dabf6dabf 100644 --- a/src/cpu/pred/btb/ras.cc +++ b/src/cpu/pred/btb/ras.cc @@ -150,7 +150,7 @@ BTBRAS::specUpdateHist(const boost::dynamic_bitset<> &history, FullBTBPrediction } void -BTBRAS::recoverHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, bool cond_taken) +BTBRAS::recoverHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) { auto takenEntry = entry.exeBranchInfo; /* @@ -192,7 +192,7 @@ BTBRAS::recoverHist(const boost::dynamic_bitset<> &history, const FetchStream &e } void -BTBRAS::update(const FetchStream &entry) +BTBRAS::update(const FetchTarget &entry) { auto meta_ptr = std::static_pointer_cast(entry.predMetas[getComponentIdx()]); auto takenEntry = entry.exeBranchInfo; @@ -426,14 +426,14 @@ BTBRAS::getTop_meta() { } Addr -BTBRAS::getTopAddrFromMetas(const FetchStream &stream) +BTBRAS::getTopAddrFromMetas(const FetchTarget &stream) { auto meta_ptr = std::static_pointer_cast(stream.predMetas[getComponentIdx()]); return meta_ptr->target; } void -BTBRAS::commitBranch(const FetchStream &stream, const DynInstPtr &inst) +BTBRAS::commitBranch(const FetchTarget &stream, const DynInstPtr &inst) { if (!inst->isReturn() || inst->isNop()) { // ras only cares about return instructions diff --git a/src/cpu/pred/btb/ras.hh b/src/cpu/pred/btb/ras.hh index 9a4a63a1be..0055446013 100644 --- a/src/cpu/pred/btb/ras.hh +++ b/src/cpu/pred/btb/ras.hh @@ -3,7 +3,7 @@ #include "base/types.hh" #include "cpu/inst_seq.hh" -#include "cpu/pred/btb/stream_struct.hh" +#include "cpu/pred/btb/common.hh" // Conditional includes based on build mode #ifdef UNIT_TEST @@ -98,18 +98,18 @@ namespace btb_pred { void specUpdateHist(const boost::dynamic_bitset<> &history, FullBTBPrediction &pred) override; - void recoverHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, bool cond_taken) override; + void recoverHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) override; - void update(const FetchStream &entry) override; + void update(const FetchTarget &entry) override; // commitBranch method - override only in production mode #ifdef UNIT_TEST - void commitBranch(const FetchStream &stream, const DynInstPtr &inst); + void commitBranch(const FetchTarget &stream, const DynInstPtr &inst); #else - void commitBranch(const FetchStream &stream, const DynInstPtr &inst) override; + void commitBranch(const FetchTarget &stream, const DynInstPtr &inst) override; #endif - Addr getTopAddrFromMetas(const FetchStream &stream); + Addr getTopAddrFromMetas(const FetchTarget &stream); private: diff --git a/src/cpu/pred/btb/test/README.md b/src/cpu/pred/btb/test/README.md index 2dab974fe0..4c2b663800 100644 --- a/src/cpu/pred/btb/test/README.md +++ b/src/cpu/pred/btb/test/README.md @@ -88,7 +88,7 @@ tage->checkFoldedHist(s0History, "speculative update"); 2. Update Phase: ```cpp // Setup update stream -FetchStream stream; +FetchTarget stream; stream.startPC = pc; stream.exeBranchInfo = entry; stream.exeTaken = taken; @@ -101,7 +101,7 @@ tage->update(stream); 3. control squash/Recovery Phase: ```cpp // set up recover stream -FetchStream recoverStream; +FetchTarget recoverStream; recoverStream.startPC = pc; recoverStream.exeBranchInfo = entry; recoverStream.exeTaken = taken; @@ -149,7 +149,7 @@ auto meta = btb->getPredictionMeta(); 2. Update Phase: ```cpp // Setup update stream -FetchStream stream; +FetchTarget stream; stream.startPC = pc; stream.predMetas[0] = meta; diff --git a/src/cpu/pred/btb/test/abtb.test.cc b/src/cpu/pred/btb/test/abtb.test.cc index 737a3dd840..36c7cc1bd4 100644 --- a/src/cpu/pred/btb/test/abtb.test.cc +++ b/src/cpu/pred/btb/test/abtb.test.cc @@ -17,8 +17,8 @@ namespace test { -FetchStream createStream(Addr startPC, FullBTBPrediction &pred, AheadBTB *abtb) { - FetchStream stream; +FetchTarget createStream(Addr startPC, FullBTBPrediction &pred, AheadBTB *abtb) { + FetchTarget stream; stream.startPC = startPC; Addr fallThroughAddr = pred.getFallThrough(abtb->predictWidth); stream.isHit = pred.btbEntries.size() > 0; // TODO: fix isHit and falseHit @@ -30,7 +30,7 @@ FetchStream createStream(Addr startPC, FullBTBPrediction &pred, AheadBTB *abtb) return stream; } -void resolveStream(FetchStream &stream, bool taken, Addr brPc, Addr target, bool isCond, int size=4) { +void resolveStream(FetchTarget &stream, bool taken, Addr brPc, Addr target, bool isCond, int size=4) { stream.resolved = true; stream.exeBranchInfo.pc = brPc; stream.exeBranchInfo.target = target; @@ -46,7 +46,7 @@ FullBTBPrediction makePrediction(Addr startPC, AheadBTB *abtb) { return stagePreds[1]; } -void updateBTB(FetchStream &stream, AheadBTB *abtb, MBTB *mbtb) { +void updateBTB(FetchTarget &stream, AheadBTB *abtb, MBTB *mbtb) { mbtb->getAndSetNewBTBEntry(stream); // usually called by mbtb, here for testing purpose abtb->update(stream); } diff --git a/src/cpu/pred/btb/test/btb.test.cc b/src/cpu/pred/btb/test/btb.test.cc index f4b104bd68..7950fa8a67 100644 --- a/src/cpu/pred/btb/test/btb.test.cc +++ b/src/cpu/pred/btb/test/btb.test.cc @@ -1,7 +1,8 @@ -#include #include +#include + +#include "cpu/pred/btb/common.hh" #include "cpu/pred/btb/mbtb.hh" -#include "cpu/pred/btb/stream_struct.hh" namespace gem5 { @@ -44,18 +45,18 @@ BranchInfo createBranchInfo(Addr pc, Addr target, bool isCond = false, } /** - * @brief Setup a FetchStream with common parameters for BTB update + * @brief Setup a FetchTarget with common parameters for BTB update * * @param startPC Start address of the fetch block * @param branch Branch information * @param taken Whether the branch was taken * @param meta Prediction metadata from previous prediction * @param endInstPC Last executed instruction PC, used for filtering entries - * @return FetchStream Initialized fetch stream + * @return FetchTarget Initialized fetch stream */ -FetchStream setupStream(Addr startPC, const BranchInfo& branch, bool taken, +FetchTarget setupStream(Addr startPC, const BranchInfo& branch, bool taken, std::shared_ptr meta, Addr endInstPC) { - FetchStream stream; + FetchTarget stream; stream.startPC = startPC; stream.resolved = true; stream.exeBranchInfo = branch; @@ -125,7 +126,7 @@ predictUpdateCycle(MBTB* btb, auto meta = btb->getPredictionMeta(); // Update phase - FetchStream stream = setupStream(startPC, branch, taken, meta, endInstPC); + FetchTarget stream = setupStream(startPC, branch, taken, meta, endInstPC); // Populate predicted BTB entries in stream from stage predictions // Use entries from the first valid stage (delay) if (btb->getDelay() < stagePreds.size()) { @@ -365,7 +366,7 @@ TEST_F(BTBTest, MultipleBranchPrediction) { mbtb->putPCHistory(0x1000, history, tempPreds); auto meta = mbtb->getPredictionMeta(); - FetchStream stream = setupStream(0x1000, branch2, true, meta, 0x1008); + FetchTarget stream = setupStream(0x1000, branch2, true, meta, 0x1008); mbtb->getAndSetNewBTBEntry(stream); mbtb->update(stream); diff --git a/src/cpu/pred/btb/test/btb_mgsc.test.cc b/src/cpu/pred/btb/test/btb_mgsc.test.cc index 67679c4ff1..9cb241912b 100644 --- a/src/cpu/pred/btb/test/btb_mgsc.test.cc +++ b/src/cpu/pred/btb/test/btb_mgsc.test.cc @@ -295,7 +295,7 @@ struct MgscHarness bwhr = bwhr_before; lhr = lhr_before; - FetchStream recover_stream; + FetchTarget recover_stream; recover_stream.startPC = start_pc; recover_stream.predMetas[mgsc.getComponentIdx()] = meta; recover_stream.resolved = true; @@ -318,7 +318,7 @@ struct MgscHarness } // Training update using prediction meta - FetchStream update_stream; + FetchTarget update_stream; update_stream.startPC = start_pc; update_stream.updateBTBEntries = {entry}; update_stream.updateIsOldEntry = true; @@ -506,7 +506,7 @@ TEST(BTBMGSCTest, UpdateOnlyOnWrongOrLowMargin) // Update with correct outcome (taken): should NOT train because abs(sum) >= total_thres and prediction correct. { - FetchStream stream; + FetchTarget stream; stream.startPC = start_pc; stream.updateBTBEntries = {entry}; stream.updateIsOldEntry = true; @@ -520,7 +520,7 @@ TEST(BTBMGSCTest, UpdateOnlyOnWrongOrLowMargin) // Update with wrong outcome (not taken): should train (decrement signed counter). { - FetchStream stream; + FetchTarget stream; stream.startPC = start_pc; stream.updateBTBEntries = {entry}; stream.updateIsOldEntry = true; diff --git a/src/cpu/pred/btb/test/btb_tage.test.cc b/src/cpu/pred/btb/test/btb_tage.test.cc index 54b5352f91..a6289ec4e9 100644 --- a/src/cpu/pred/btb/test/btb_tage.test.cc +++ b/src/cpu/pred/btb/test/btb_tage.test.cc @@ -5,8 +5,8 @@ #include "base/types.hh" #include "cpu/pred/btb/btb_tage.hh" +#include "cpu/pred/btb/common.hh" #include "cpu/pred/btb/folded_hist.hh" -#include "cpu/pred/btb/stream_struct.hh" namespace gem5 { @@ -54,11 +54,11 @@ BTBEntry createBTBEntry(Addr pc, bool isCond = true, bool valid = true, * @param taken Actual outcome (taken/not taken) * @param meta Prediction metadata from prediction phase * @param squashType Type of squash (control or non-control) - * @return FetchStream Initialized stream for update or recovery + * @return FetchTarget Initialized stream for update or recovery */ -FetchStream createStream(Addr startPC, const BTBEntry& entry, bool taken, +FetchTarget createStream(Addr startPC, const BTBEntry& entry, bool taken, std::shared_ptr meta) { - FetchStream stream; + FetchTarget stream; stream.startPC = startPC; stream.exeBranchInfo = entry; stream.exeTaken = taken; @@ -71,7 +71,7 @@ FetchStream createStream(Addr startPC, const BTBEntry& entry, bool taken, return stream; } -FetchStream setMispredStream(FetchStream stream) { +FetchTarget setMispredStream(FetchTarget stream) { stream.squashType = SquashType::SQUASH_CTRL; stream.squashPC = stream.exeBranchInfo.pc; return stream; @@ -176,7 +176,7 @@ bool predictUpdateCycle(BTBTAGE* tage, Addr startPC, tage->checkFoldedHist(history, "speculative update"); // 5. Create update stream - FetchStream stream = createStream(startPC, entry, actual_taken, meta); + FetchTarget stream = createStream(startPC, entry, actual_taken, meta); // 6. Handle possible misprediction if (predicted_taken != actual_taken) { @@ -385,7 +385,7 @@ TEST_F(BTBTAGETest, UsefulBitMechanism) { auto meta = tage->getPredictionMeta(); // Update with actual outcome matching main prediction (taken) - FetchStream stream = createStream(0x1000, entry, true, meta); + FetchTarget stream = createStream(0x1000, entry, true, meta); tage->update(stream); // Verify useful bit is set (main prediction was correct and differed from alt) @@ -432,7 +432,7 @@ TEST_F(BTBTAGETest, EntryAllocationAndReplacement) { // Create a stream for entry2 with opposite outcome to force allocation // Although it has the same PC, we'll treat it as a different branch context // by setting a specific tag that doesn't match existing entries - FetchStream stream = createStream(0x1000, entry2, !predicted, meta); + FetchTarget stream = createStream(0x1000, entry2, !predicted, meta); stream.squashType = SquashType::SQUASH_CTRL; // Mark as control misprediction stream.squashPC = 0x1000; @@ -475,7 +475,7 @@ TEST_F(BTBTAGETest, HistoryRecoveryCorrectness) { } // Create a recovery stream with opposite outcome - FetchStream stream = createStream(0x1000, entry, !predicted_taken, meta); + FetchTarget stream = createStream(0x1000, entry, !predicted_taken, meta); stream = setMispredStream(stream); // Recover to pre-speculative state and update with correct outcome @@ -520,11 +520,11 @@ TEST_F(BTBTAGETest, MultipleBranchSequence) { } // Update first branch (correct prediction), no allocation - FetchStream stream1 = createStream(0x1000, btbEntries[0], first_pred, meta); + FetchTarget stream1 = createStream(0x1000, btbEntries[0], first_pred, meta); tage->update(stream1); // Update second branch (incorrect prediction), allocate 1 entry - FetchStream stream2 = createStream(0x1000, btbEntries[1], !second_pred, meta); + FetchTarget stream2 = createStream(0x1000, btbEntries[1], !second_pred, meta); stream2.squashType = SquashType::SQUASH_CTRL; stream2.squashPC = 0x1004; tage->update(stream2); @@ -551,7 +551,7 @@ TEST_F(BTBTAGETest, CounterUpdateMechanism) { predictTAGE(tage, 0x1000, {entry}, history, stagePreds); auto meta = tage->getPredictionMeta(); - FetchStream stream = createStream(0x1000, entry, true, meta); + FetchTarget stream = createStream(0x1000, entry, true, meta); tage->update(stream); } @@ -564,7 +564,7 @@ TEST_F(BTBTAGETest, CounterUpdateMechanism) { predictTAGE(tage, 0x1000, {entry}, history, stagePreds); auto meta = tage->getPredictionMeta(); - FetchStream stream = createStream(0x1000, entry, false, meta); + FetchTarget stream = createStream(0x1000, entry, false, meta); tage->update(stream); } @@ -897,7 +897,7 @@ TEST_F(BTBTAGETest, BankConflict) { EXPECT_TRUE(bankTage->predBankValid); auto meta = bankTage->getPredictionMeta(); - FetchStream stream = createStream(0xa0, createBTBEntry(0xa0), true, meta); + FetchTarget stream = createStream(0xa0, createBTBEntry(0xa0), true, meta); setupTageEntry(bankTage, 0xa0, 0, 1, false); uint64_t conflicts_before = bankTage->tageStats.updateBankConflict; @@ -916,7 +916,7 @@ TEST_F(BTBTAGETest, BankConflict) { bankTage->putPCHistory(0x100, testHistory, testStagePreds); auto meta = bankTage->getPredictionMeta(); - FetchStream stream = createStream(0x104, createBTBEntry(0x104), true, meta); + FetchTarget stream = createStream(0x104, createBTBEntry(0x104), true, meta); uint64_t conflicts_before = bankTage->tageStats.updateBankConflict; bool can_update = bankTage->canResolveUpdate(stream); @@ -935,7 +935,7 @@ TEST_F(BTBTAGETest, BankConflict) { bankTage->putPCHistory(0x20, testHistory, testStagePreds); auto meta = bankTage->getPredictionMeta(); - FetchStream stream = createStream(0xa0, createBTBEntry(0xa0), true, meta); + FetchTarget stream = createStream(0xa0, createBTBEntry(0xa0), true, meta); setupTageEntry(bankTage, 0xa0, 0, 1, false); uint64_t conflicts_before = bankTage->tageStats.updateBankConflict; diff --git a/src/cpu/pred/btb/test/ras_test.cc b/src/cpu/pred/btb/test/ras_test.cc index 9da0590356..3c57e00089 100644 --- a/src/cpu/pred/btb/test/ras_test.cc +++ b/src/cpu/pred/btb/test/ras_test.cc @@ -7,8 +7,8 @@ #include #include "base/types.hh" +#include "cpu/pred/btb/common.hh" #include "cpu/pred/btb/ras.hh" -#include "cpu/pred/btb/stream_struct.hh" namespace gem5 { namespace branch_prediction { @@ -77,9 +77,9 @@ class RASTest : public ::testing::Test } // Helper function to create a commit stream for call instructions - FetchStream createCallCommitStream(Addr startPC, Addr branchPC, unsigned size, + FetchTarget createCallCommitStream(Addr startPC, Addr branchPC, unsigned size, std::shared_ptr meta, bool taken = true) { - FetchStream stream; + FetchTarget stream; stream.startPC = startPC; stream.exeTaken = taken; stream.exeBranchInfo.pc = branchPC; @@ -91,9 +91,9 @@ class RASTest : public ::testing::Test } // Helper function to create a commit stream for return instructions - FetchStream createReturnCommitStream(Addr startPC, Addr branchPC, unsigned size, + FetchTarget createReturnCommitStream(Addr startPC, Addr branchPC, unsigned size, std::shared_ptr meta, bool taken = true) { - FetchStream stream; + FetchTarget stream; stream.startPC = startPC; stream.exeTaken = taken; stream.exeBranchInfo.pc = branchPC; @@ -105,9 +105,9 @@ class RASTest : public ::testing::Test } // Helper function to create a recovery stream - FetchStream createRecoveryStream(Addr startPC, Addr branchPC, bool isCall, unsigned size, + FetchTarget createRecoveryStream(Addr startPC, Addr branchPC, bool isCall, unsigned size, std::shared_ptr meta, bool taken = false) { - FetchStream stream; + FetchTarget stream; stream.startPC = startPC; stream.exeTaken = taken; stream.exeBranchInfo.pc = branchPC; @@ -222,7 +222,7 @@ TEST_F(RASTest, BasicRecovery) { ras->specUpdateHist(history, callPred); // Create recovery stream - FetchStream recoverStream; + FetchTarget recoverStream; recoverStream.startPC = 0x1000; recoverStream.exeTaken = false; // Not taken, so no actual call recoverStream.predMetas[0] = initialMeta; @@ -405,7 +405,7 @@ TEST_F(RASTest, ComplexRecovery) { checkReturnTarget(0x4000, 0x3004); // Recover to the state after first call (simulate misprediction) - FetchStream recoverStream; + FetchTarget recoverStream; recoverStream.startPC = 0x2000; recoverStream.exeTaken = true; // The first call was actually taken recoverStream.exeBranchInfo.pc = 0x1000; diff --git a/src/cpu/pred/btb/test/uras_test.cc b/src/cpu/pred/btb/test/uras_test.cc index 4855360801..e8ca0c29ad 100644 --- a/src/cpu/pred/btb/test/uras_test.cc +++ b/src/cpu/pred/btb/test/uras_test.cc @@ -4,7 +4,7 @@ #include #include #include "base/types.hh" -#include "cpu/pred/btb/stream_struct.hh" +#include "cpu/pred/btb/common.hh" namespace gem5 { namespace branch_prediction { @@ -100,7 +100,7 @@ class MockuRAS { // two steps: // 1. recover sp and tos from entry.predMetas[0] // 2. do push & pops on control squash based on the actual branch type (call/return) - void recoverHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, bool cond_taken) + void recoverHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) { auto &stack = specStack; auto &sp = specSp; @@ -381,8 +381,8 @@ TEST_F(URASTest, SpecUpdateHistCallReturn) { // Test basic recovery functionality TEST_F(URASTest, RecoverHistBasic) { boost::dynamic_bitset<> history(8, 0); - FetchStream entry; - + FetchTarget entry; + // initial state auto& stack = uras->getSpecStack(); auto& sp = uras->getSpecSp(); @@ -405,8 +405,8 @@ TEST_F(URASTest, RecoverHistBasic) { // Test recovery with return instruction TEST_F(URASTest, RecoverHistReturn) { boost::dynamic_bitset<> history(8, 0); - FetchStream entry; - + FetchTarget entry; + // 设置初始状态 auto& stack = uras->getSpecStack(); auto& sp = uras->getSpecSp(); @@ -434,8 +434,8 @@ TEST_F(URASTest, RecoverHistReturn) { // Test recovery with call instruction TEST_F(URASTest, RecoverHistCall) { boost::dynamic_bitset<> history(8, 0); - FetchStream entry; - + FetchTarget entry; + // 设置初始状态 auto& stack = uras->getSpecStack(); auto& sp = uras->getSpecSp(); @@ -463,8 +463,8 @@ TEST_F(URASTest, RecoverHistCall) { // Test recovery with call-return sequence TEST_F(URASTest, RecoverHistCallReturn) { boost::dynamic_bitset<> history(8, 0); - FetchStream entry1, entry2; - + FetchTarget entry1, entry2; + auto& stack = uras->getSpecStack(); auto& sp = uras->getSpecSp(); @@ -504,4 +504,4 @@ TEST_F(URASTest, RecoverHistCallReturn) { } // namespace btb_pred } // namespace branch_prediction -} // namespace gem5 \ No newline at end of file +} // namespace gem5 diff --git a/src/cpu/pred/btb/timed_base_pred.hh b/src/cpu/pred/btb/timed_base_pred.hh index 880d160f9e..fce1a6aef1 100644 --- a/src/cpu/pred/btb/timed_base_pred.hh +++ b/src/cpu/pred/btb/timed_base_pred.hh @@ -7,13 +7,13 @@ // Conditional includes based on build mode #ifdef UNIT_TEST #include "base/types.hh" - #include "cpu/pred/btb/stream_struct.hh" + #include "cpu/pred/btb/common.hh" #else #include "base/statistics.hh" #include "base/types.hh" #include "cpu/inst_seq.hh" #include "cpu/o3/dyn_inst_ptr.hh" - #include "cpu/pred/btb/stream_struct.hh" + #include "cpu/pred/btb/common.hh" #include "sim/sim_object.hh" #include "params/TimedBaseBTBPredictor.hh" #endif @@ -68,20 +68,20 @@ class TimedBaseBTBPredictor: public SimObject virtual void specUpdateBwHist(const boost::dynamic_bitset<> &history, FullBTBPrediction &pred) {} virtual void specUpdateIHist(FullBTBPrediction &pred) {} virtual void specUpdateLHist(const std::vector> &history, FullBTBPrediction &pred) {} - virtual void recoverHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, bool cond_taken) {} - virtual void recoverPHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, bool cond_taken) {} - virtual void recoverBwHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, bool cond_taken) {} - virtual void recoverIHist(const FetchStream &entry, int shamt, bool cond_taken) {} - virtual void recoverLHist(const std::vector> &history, const FetchStream &entry, int shamt, bool cond_taken) {} - virtual void update(const FetchStream &entry) {} + virtual void recoverHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) {} + virtual void recoverPHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) {} + virtual void recoverBwHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) {} + virtual void recoverIHist(const FetchTarget &entry, int shamt, bool cond_taken) {} + virtual void recoverLHist(const std::vector> &history, const FetchTarget &entry, int shamt, bool cond_taken) {} + virtual void update(const FetchTarget &entry) {} virtual unsigned getDelay() {return numDelay;} virtual bool getResolvedUpdate() {return resolvedUpdate;} // Two-phase resolved update: probe first, then apply - virtual bool canResolveUpdate(const FetchStream &entry) { return true; } - virtual void doResolveUpdate(const FetchStream &entry) { update(entry); } + virtual bool canResolveUpdate(const FetchTarget &entry) { return true; } + virtual void doResolveUpdate(const FetchTarget &entry) { update(entry); } #ifndef UNIT_TEST // do some statistics on a per-branch and per-predictor basis - virtual void commitBranch(const FetchStream &entry, const DynInstPtr &inst) {} + virtual void commitBranch(const FetchTarget &entry, const DynInstPtr &inst) {} #endif int componentIdx{0}; diff --git a/src/cpu/pred/btb/uras.cc b/src/cpu/pred/btb/uras.cc index 8fe0387989..c507956d0e 100644 --- a/src/cpu/pred/btb/uras.cc +++ b/src/cpu/pred/btb/uras.cc @@ -124,7 +124,7 @@ BTBuRAS::specUpdateHist(const boost::dynamic_bitset<> &history, FullBTBPredictio } void -BTBuRAS::recoverHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, bool cond_taken) +BTBuRAS::recoverHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) { auto &stack = specStack; auto &sp = specSp; @@ -163,7 +163,7 @@ BTBuRAS::recoverHist(const boost::dynamic_bitset<> &history, const FetchStream & } void -BTBuRAS::update(const FetchStream &entry) +BTBuRAS::update(const FetchTarget &entry) { auto &stack = nonSpecStack; auto &sp = nonSpecSp; diff --git a/src/cpu/pred/btb/uras.hh b/src/cpu/pred/btb/uras.hh index 3138fb79ab..cdcde96b54 100644 --- a/src/cpu/pred/btb/uras.hh +++ b/src/cpu/pred/btb/uras.hh @@ -3,7 +3,7 @@ #include "base/types.hh" #include "cpu/inst_seq.hh" -#include "cpu/pred/btb/stream_struct.hh" +#include "cpu/pred/btb/common.hh" #include "cpu/pred/btb/timed_base_pred.hh" #include "debug/URAS.hh" #include "params/BTBuRAS.hh" @@ -49,9 +49,9 @@ class BTBuRAS : public TimedBaseBTBPredictor unsigned getDelay() override {return 0;} - void recoverHist(const boost::dynamic_bitset<> &history, const FetchStream &entry, int shamt, bool cond_taken) override; + void recoverHist(const boost::dynamic_bitset<> &history, const FetchTarget &entry, int shamt, bool cond_taken) override; - void update(const FetchStream &entry) override; + void update(const FetchTarget &entry) override; int getSp() {return specSp;} diff --git a/src/cpu/pred/ftb/decoupled_bpred.cc b/src/cpu/pred/ftb/decoupled_bpred.cc index 8e278f5451..208877819c 100644 --- a/src/cpu/pred/ftb/decoupled_bpred.cc +++ b/src/cpu/pred/ftb/decoupled_bpred.cc @@ -1848,10 +1848,10 @@ DecoupledBPUWithFTB::commitBranch(const DynInstPtr &inst, bool miss) // break down into each predictor and each stage // find corresponding fsq entry first - auto it = fetchStreamQueue.find(inst->fsqId); + auto it = fetchStreamQueue.find(inst->ftqId); // TRACE MODE FIX: Bypass assertion for missing FSQ entries in trace mode if (it == fetchStreamQueue.end() && cpu->isTraceMode()) { - DPRINTF(FTB, "Missing FSQ entry for trace mode branch commit [fsqId:%lu], skipping\n", inst->fsqId); + DPRINTF(FTB, "Missing FSQ entry for trace mode branch commit [fsqId:%lu], skipping\n", inst->ftqId); return; } assert(it != fetchStreamQueue.end()); @@ -1951,7 +1951,7 @@ DecoupledBPUWithFTB::commitBranch(const DynInstPtr &inst, bool miss) } } entry.commitMispredictions[branchAddr] = miss; - DPRINTF(DBPFTBStats, "commit branchAddr %#lx, miss %d, fsqID %d\n", branchAddr, miss, inst->fsqId); + DPRINTF(DBPFTBStats, "commit branchAddr %#lx, miss %d, fsqID %d\n", branchAddr, miss, inst->ftqId); LoopTrace rec; LoopEntry predLoopEntry = LoopEntry(); @@ -2000,7 +2000,7 @@ DecoupledBPUWithFTB::commitBranch(const DynInstPtr &inst, bool miss) void DecoupledBPUWithFTB::notifyInstCommit(const DynInstPtr &inst) { - auto it = fetchStreamQueue.find(inst->fsqId); + auto it = fetchStreamQueue.find(inst->ftqId); // In trace mode, instructions bypass fetch stream creation, so fsqId may not be valid if (cpu->isTraceMode()) { if (it == fetchStreamQueue.end()) { @@ -2680,7 +2680,7 @@ Addr DecoupledBPUWithFTB::getPreservedReturnAddr(const DynInstPtr &dynInst) { DPRINTF(DecoupleBP, "acquiring reutrn address for inst pc %#lx from decode\n", dynInst->pcState().instAddr()); - auto fsqid = dynInst->getFsqId(); + auto fsqid = dynInst->getFtqId(); auto it = fetchStreamQueue.find(fsqid); auto retAddr = ras->getTopAddrFromMetas(it->second); DPRINTF(DecoupleBP, "get ret addr %#lx\n", retAddr);