From 4f4df671485aaea459b78ea1da86683fa1938e08 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 3 Mar 2021 01:31:14 -0800 Subject: [PATCH] cpu: Remove the MemDepPred template parameter from MemDepUnit. Hard code this to StoreSet, the only value ever used with this parameter. If the dependency predictor needs to be updatable, there should be a well defined interface for it which can be connected at run time. Change-Id: Ie30a742eac98220cc39679d26ada5d08099659a0 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/42104 Tested-by: kokoro Reviewed-by: Nathanael Premillieu Maintainer: Gabe Black --- src/cpu/o3/inst_queue.hh | 2 +- src/cpu/o3/mem_dep_unit.cc | 15 ++--- src/cpu/o3/mem_dep_unit.hh | 5 +- src/cpu/o3/mem_dep_unit_impl.hh | 108 ++++++++++++++++---------------- 4 files changed, 63 insertions(+), 67 deletions(-) diff --git a/src/cpu/o3/inst_queue.hh b/src/cpu/o3/inst_queue.hh index 7791cdcf7d..e261d8fd2c 100644 --- a/src/cpu/o3/inst_queue.hh +++ b/src/cpu/o3/inst_queue.hh @@ -292,7 +292,7 @@ class InstructionQueue /** The memory dependence unit, which tracks/predicts memory dependences * between instructions. */ - MemDepUnit memDepUnit[O3MaxThreads]; + MemDepUnit memDepUnit[O3MaxThreads]; /** The queue to the execute stage. Issued instructions will be written * into it. diff --git a/src/cpu/o3/mem_dep_unit.cc b/src/cpu/o3/mem_dep_unit.cc index 21c91d73d2..963d614b31 100644 --- a/src/cpu/o3/mem_dep_unit.cc +++ b/src/cpu/o3/mem_dep_unit.cc @@ -28,20 +28,15 @@ #include "cpu/o3/isa_specific.hh" #include "cpu/o3/mem_dep_unit_impl.hh" -#include "cpu/o3/store_set.hh" #ifdef DEBUG template <> -int -MemDepUnit::MemDepEntry::memdep_count = 0; +int MemDepUnit::MemDepEntry::memdep_count = 0; template <> -int -MemDepUnit::MemDepEntry::memdep_insert = 0; +int MemDepUnit::MemDepEntry::memdep_insert = 0; template <> -int -MemDepUnit::MemDepEntry::memdep_erase = 0; +int MemDepUnit::MemDepEntry::memdep_erase = 0; #endif -// Force instantation of memory dependency unit using store sets and -// O3CPUImpl. -template class MemDepUnit; +// Force instantation of memory dependency unit using O3CPUImpl. +template class MemDepUnit; diff --git a/src/cpu/o3/mem_dep_unit.hh b/src/cpu/o3/mem_dep_unit.hh index 3874e5fa32..744d736ae1 100644 --- a/src/cpu/o3/mem_dep_unit.hh +++ b/src/cpu/o3/mem_dep_unit.hh @@ -51,6 +51,7 @@ #include "cpu/inst_seq.hh" #include "cpu/o3/dyn_inst_ptr.hh" #include "cpu/o3/limits.hh" +#include "cpu/o3/store_set.hh" #include "debug/MemDepUnit.hh" struct SNHash @@ -82,7 +83,7 @@ class FullO3CPU; * utilize. Thus this class should be most likely be rewritten for other * dependence prediction schemes. */ -template +template class MemDepUnit { protected: @@ -259,7 +260,7 @@ class MemDepUnit * this unit what instruction the newly added instruction is dependent * upon. */ - MemDepPred depPred; + StoreSet depPred; /** Sequence numbers of outstanding load barriers. */ std::unordered_set loadBarrierSNs; diff --git a/src/cpu/o3/mem_dep_unit_impl.hh b/src/cpu/o3/mem_dep_unit_impl.hh index ce1aa2639b..f77fe4f2d0 100644 --- a/src/cpu/o3/mem_dep_unit_impl.hh +++ b/src/cpu/o3/mem_dep_unit_impl.hh @@ -53,15 +53,15 @@ #include "debug/MemDepUnit.hh" #include "params/DerivO3CPU.hh" -template -MemDepUnit::MemDepUnit() +template +MemDepUnit::MemDepUnit() : iqPtr(NULL), stats(nullptr) { } -template -MemDepUnit::MemDepUnit(const DerivO3CPUParams ¶ms) +template +MemDepUnit::MemDepUnit(const DerivO3CPUParams ¶ms) : _name(params.name + ".memdepunit"), depPred(params.store_set_clear_period, params.SSITSize, params.LFSTSize), @@ -71,8 +71,8 @@ MemDepUnit::MemDepUnit(const DerivO3CPUParams ¶ms) DPRINTF(MemDepUnit, "Creating MemDepUnit object.\n"); } -template -MemDepUnit::~MemDepUnit() +template +MemDepUnit::~MemDepUnit() { for (ThreadID tid = 0; tid < O3MaxThreads; tid++) { @@ -96,9 +96,9 @@ MemDepUnit::~MemDepUnit() #endif } -template +template void -MemDepUnit::init( +MemDepUnit::init( const DerivO3CPUParams ¶ms, ThreadID tid, FullO3CPU *cpu) { DPRINTF(MemDepUnit, "Creating MemDepUnit %i object.\n",tid); @@ -113,8 +113,8 @@ MemDepUnit::init( cpu->addStatGroup(stats_group_name.c_str(), &stats); } -template -MemDepUnit:: +template +MemDepUnit:: MemDepUnitStats::MemDepUnitStats(Stats::Group *parent) : Stats::Group(parent), ADD_STAT(insertedLoads, Stats::Units::Count::get(), @@ -128,9 +128,9 @@ MemDepUnitStats::MemDepUnitStats(Stats::Group *parent) { } -template +template bool -MemDepUnit::isDrained() const +MemDepUnit::isDrained() const { bool drained = instsToReplay.empty() && memDepHash.empty() @@ -141,9 +141,9 @@ MemDepUnit::isDrained() const return drained; } -template +template void -MemDepUnit::drainSanityCheck() const +MemDepUnit::drainSanityCheck() const { assert(instsToReplay.empty()); assert(memDepHash.empty()); @@ -153,9 +153,9 @@ MemDepUnit::drainSanityCheck() const assert(memDepHash.empty()); } -template +template void -MemDepUnit::takeOverFrom() +MemDepUnit::takeOverFrom() { // Be sure to reset all state. loadBarrierSNs.clear(); @@ -163,16 +163,16 @@ MemDepUnit::takeOverFrom() depPred.clear(); } -template +template void -MemDepUnit::setIQ(InstructionQueue *iq_ptr) +MemDepUnit::setIQ(InstructionQueue *iq_ptr) { iqPtr = iq_ptr; } -template +template void -MemDepUnit::insertBarrierSN(const O3DynInstPtr &barr_inst) +MemDepUnit::insertBarrierSN(const O3DynInstPtr &barr_inst) { InstSeqNum barr_sn = barr_inst->seqNum; @@ -203,9 +203,9 @@ MemDepUnit::insertBarrierSN(const O3DynInstPtr &barr_inst) } } -template +template void -MemDepUnit::insert(const O3DynInstPtr &inst) +MemDepUnit::insert(const O3DynInstPtr &inst) { ThreadID tid = inst->threadNumber; @@ -314,9 +314,9 @@ MemDepUnit::insert(const O3DynInstPtr &inst) } } -template +template void -MemDepUnit::insertNonSpec(const O3DynInstPtr &inst) +MemDepUnit::insertNonSpec(const O3DynInstPtr &inst) { insertBarrier(inst); @@ -336,9 +336,9 @@ MemDepUnit::insertNonSpec(const O3DynInstPtr &inst) } } -template +template void -MemDepUnit::insertBarrier(const O3DynInstPtr &barr_inst) +MemDepUnit::insertBarrier(const O3DynInstPtr &barr_inst) { ThreadID tid = barr_inst->threadNumber; @@ -359,9 +359,9 @@ MemDepUnit::insertBarrier(const O3DynInstPtr &barr_inst) insertBarrierSN(barr_inst); } -template +template void -MemDepUnit::regsReady(const O3DynInstPtr &inst) +MemDepUnit::regsReady(const O3DynInstPtr &inst) { DPRINTF(MemDepUnit, "Marking registers as ready for " "instruction PC %s [sn:%lli].\n", @@ -382,9 +382,9 @@ MemDepUnit::regsReady(const O3DynInstPtr &inst) } } -template +template void -MemDepUnit::nonSpecInstReady(const O3DynInstPtr &inst) +MemDepUnit::nonSpecInstReady(const O3DynInstPtr &inst) { DPRINTF(MemDepUnit, "Marking non speculative " "instruction PC %s as ready [sn:%lli].\n", @@ -395,16 +395,16 @@ MemDepUnit::nonSpecInstReady(const O3DynInstPtr &inst) moveToReady(inst_entry); } -template +template void -MemDepUnit::reschedule(const O3DynInstPtr &inst) +MemDepUnit::reschedule(const O3DynInstPtr &inst) { instsToReplay.push_back(inst); } -template +template void -MemDepUnit::replay() +MemDepUnit::replay() { O3DynInstPtr temp_inst; @@ -423,9 +423,9 @@ MemDepUnit::replay() } } -template +template void -MemDepUnit::completed(const O3DynInstPtr &inst) +MemDepUnit::completed(const O3DynInstPtr &inst) { DPRINTF(MemDepUnit, "Completed mem instruction PC %s [sn:%lli].\n", inst->pcState(), inst->seqNum); @@ -447,9 +447,9 @@ MemDepUnit::completed(const O3DynInstPtr &inst) #endif } -template +template void -MemDepUnit::completeInst(const O3DynInstPtr &inst) +MemDepUnit::completeInst(const O3DynInstPtr &inst) { wakeDependents(inst); completed(inst); @@ -479,9 +479,9 @@ MemDepUnit::completeInst(const O3DynInstPtr &inst) } } -template +template void -MemDepUnit::wakeDependents(const O3DynInstPtr &inst) +MemDepUnit::wakeDependents(const O3DynInstPtr &inst) { // Only stores, atomics and barriers have dependents. if (!inst->isStore() && !inst->isAtomic() && !inst->isReadBarrier() && @@ -516,9 +516,9 @@ MemDepUnit::wakeDependents(const O3DynInstPtr &inst) inst_entry->dependInsts.clear(); } -template +template void -MemDepUnit::squash(const InstSeqNum &squashed_num, +MemDepUnit::squash(const InstSeqNum &squashed_num, ThreadID tid) { if (!instsToReplay.empty()) { @@ -568,9 +568,9 @@ MemDepUnit::squash(const InstSeqNum &squashed_num, depPred.squash(squashed_num, tid); } -template +template void -MemDepUnit::violation(const O3DynInstPtr &store_inst, +MemDepUnit::violation(const O3DynInstPtr &store_inst, const O3DynInstPtr &violating_load) { DPRINTF(MemDepUnit, "Passing violating PCs to store sets," @@ -580,9 +580,9 @@ MemDepUnit::violation(const O3DynInstPtr &store_inst, depPred.violation(store_inst->instAddr(), violating_load->instAddr()); } -template +template void -MemDepUnit::issue(const O3DynInstPtr &inst) +MemDepUnit::issue(const O3DynInstPtr &inst) { DPRINTF(MemDepUnit, "Issuing instruction PC %#x [sn:%lli].\n", inst->instAddr(), inst->seqNum); @@ -590,9 +590,9 @@ MemDepUnit::issue(const O3DynInstPtr &inst) depPred.issued(inst->instAddr(), inst->seqNum, inst->isStore()); } -template -inline typename MemDepUnit::MemDepEntryPtr & -MemDepUnit::findInHash(const O3DynInstConstPtr &inst) +template +typename MemDepUnit::MemDepEntryPtr & +MemDepUnit::findInHash(const O3DynInstConstPtr &inst) { MemDepHashIt hash_it = memDepHash.find(inst->seqNum); @@ -601,9 +601,9 @@ MemDepUnit::findInHash(const O3DynInstConstPtr &inst) return (*hash_it).second; } -template -inline void -MemDepUnit::moveToReady(MemDepEntryPtr &woken_inst_entry) +template +void +MemDepUnit::moveToReady(MemDepEntryPtr &woken_inst_entry) { DPRINTF(MemDepUnit, "Adding instruction [sn:%lli] " "to the ready list.\n", woken_inst_entry->inst->seqNum); @@ -614,9 +614,9 @@ MemDepUnit::moveToReady(MemDepEntryPtr &woken_inst_entry) } -template +template void -MemDepUnit::dumpLists() +MemDepUnit::dumpLists() { for (ThreadID tid = 0; tid < O3MaxThreads; tid++) { cprintf("Instruction list %i size: %i\n",