diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc index 27f121fc86..cb6861045d 100644 --- a/src/mem/cache/base.cc +++ b/src/mem/cache/base.cc @@ -125,7 +125,8 @@ BaseCache::BaseCache(const BaseCacheParams &p, unsigned blk_size) // forward snoops is overridden in init() once we can query // whether the connected requestor is actually snooping or not - tempBlock = new TempCacheBlk(blkSize, tags->params().indexing_policy); + tempBlock = new TempCacheBlk(blkSize, + genTagExtractor(tags->params().indexing_policy)); tags->tagsInit(); if (prefetcher) diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh index aa9414ac3c..2b24828259 100644 --- a/src/mem/cache/cache_blk.hh +++ b/src/mem/cache/cache_blk.hh @@ -153,7 +153,7 @@ class CacheBlk : public TaggedEntry std::list lockList; public: - CacheBlk() : TaggedEntry(nullptr) + CacheBlk() : TaggedEntry() { invalidate(); } @@ -526,11 +526,10 @@ class TempCacheBlk final : public CacheBlk * Creates a temporary cache block, with its own storage. * @param size The size (in bytes) of this cache block. */ - TempCacheBlk(unsigned size, TaggedIndexingPolicy *ip) : CacheBlk() + TempCacheBlk(unsigned size, TagExtractor ext) : CacheBlk() { data = new uint8_t[size]; - - setIndexingPolicy(ip); + registerTagExtractor(ext); } TempCacheBlk(const TempCacheBlk&) = delete; using CacheBlk::operator=; diff --git a/src/mem/cache/prefetch/access_map_pattern_matching.cc b/src/mem/cache/prefetch/access_map_pattern_matching.cc index 34e9c48dd4..56ca942bfa 100644 --- a/src/mem/cache/prefetch/access_map_pattern_matching.cc +++ b/src/mem/cache/prefetch/access_map_pattern_matching.cc @@ -56,7 +56,7 @@ AccessMapPatternMatching::AccessMapPatternMatching( p.access_map_table_replacement_policy, p.access_map_table_indexing_policy, AccessMapEntry(hotZoneSize / blkSize, - p.access_map_table_indexing_policy)), + genTagExtractor(p.access_map_table_indexing_policy))), numGoodPrefetches(0), numTotalPrefetches(0), numRawCacheMisses(0), numRawCacheHits(0), degree(startDegree), usefulDegree(startDegree), epochEvent([this]{ processEpochEvent(); }, name()) diff --git a/src/mem/cache/prefetch/access_map_pattern_matching.hh b/src/mem/cache/prefetch/access_map_pattern_matching.hh index 90ffdc6634..17d25184d3 100644 --- a/src/mem/cache/prefetch/access_map_pattern_matching.hh +++ b/src/mem/cache/prefetch/access_map_pattern_matching.hh @@ -95,9 +95,10 @@ class AccessMapPatternMatching : public ClockedObject /** vector containing the state of the cachelines in this zone */ std::vector states; - AccessMapEntry(size_t num_entries, TaggedIndexingPolicy *ip) - : TaggedEntry(ip), states(num_entries, AM_INIT) + AccessMapEntry(size_t num_entries, TagExtractor ext) + : TaggedEntry(), states(num_entries, AM_INIT) { + registerTagExtractor(ext); } void diff --git a/src/mem/cache/prefetch/indirect_memory.cc b/src/mem/cache/prefetch/indirect_memory.cc index ea52023008..a87320376c 100644 --- a/src/mem/cache/prefetch/indirect_memory.cc +++ b/src/mem/cache/prefetch/indirect_memory.cc @@ -49,12 +49,12 @@ IndirectMemory::IndirectMemory(const IndirectMemoryPrefetcherParams &p) p.pt_table_replacement_policy, p.pt_table_indexing_policy, PrefetchTableEntry(p.num_indirect_counter_bits, - p.pt_table_indexing_policy)), + genTagExtractor(p.pt_table_indexing_policy))), ipd((name() + ".IPD").c_str(), p.ipd_table_entries, p.ipd_table_assoc, p.ipd_table_replacement_policy, p.ipd_table_indexing_policy, IndirectPatternDetectorEntry(p.addr_array_len, shiftValues.size(), - p.ipd_table_indexing_policy)), + genTagExtractor(p.ipd_table_indexing_policy))), ipdEntryTrackingMisses(nullptr), byteOrder(p.sys->getGuestByteOrder()) { } diff --git a/src/mem/cache/prefetch/indirect_memory.hh b/src/mem/cache/prefetch/indirect_memory.hh index 5693b0955a..92b010d4ab 100644 --- a/src/mem/cache/prefetch/indirect_memory.hh +++ b/src/mem/cache/prefetch/indirect_memory.hh @@ -99,13 +99,14 @@ class IndirectMemory : public Queued */ bool increasedIndirectCounter; - PrefetchTableEntry(unsigned indirect_counter_bits, - TaggedIndexingPolicy *ip) - : TaggedEntry(ip), address(0), secure(false), streamCounter(0), + PrefetchTableEntry(unsigned indirect_counter_bits, TagExtractor ext) + : TaggedEntry(), address(0), secure(false), streamCounter(0), enabled(false), index(0), baseAddr(0), shift(0), indirectCounter(indirect_counter_bits), increasedIndirectCounter(false) - {} + { + registerTagExtractor(ext); + } void invalidate() override @@ -145,11 +146,12 @@ class IndirectMemory : public Queued IndirectPatternDetectorEntry(unsigned int num_addresses, unsigned int num_shifts, - TaggedIndexingPolicy *ip) - : TaggedEntry(ip), idx1(0), idx2(0), secondIndexSet(false), + TagExtractor ext) + : TaggedEntry(), idx1(0), idx2(0), secondIndexSet(false), numMisses(0), baseAddr(num_addresses, std::vector(num_shifts)) { + registerTagExtractor(ext); } void diff --git a/src/mem/cache/prefetch/irregular_stream_buffer.cc b/src/mem/cache/prefetch/irregular_stream_buffer.cc index ce1f78d0c8..30323a8c15 100644 --- a/src/mem/cache/prefetch/irregular_stream_buffer.cc +++ b/src/mem/cache/prefetch/irregular_stream_buffer.cc @@ -44,25 +44,27 @@ IrregularStreamBuffer::IrregularStreamBuffer( prefetchCandidatesPerEntry(p.prefetch_candidates_per_entry), degree(p.degree), trainingUnit((name() + ".TrainingUnit").c_str(), - p.training_unit_entries, - p.training_unit_assoc, - p.training_unit_replacement_policy, - p.training_unit_indexing_policy, - TrainingUnitEntry(p.training_unit_indexing_policy)), + p.training_unit_entries, + p.training_unit_assoc, + p.training_unit_replacement_policy, + p.training_unit_indexing_policy, + TrainingUnitEntry(genTagExtractor(p.training_unit_indexing_policy))), psAddressMappingCache((name() + ".PSAddressMappingCache").c_str(), p.address_map_cache_entries, p.address_map_cache_assoc, p.ps_address_map_cache_replacement_policy, p.ps_address_map_cache_indexing_policy, AddressMappingEntry(prefetchCandidatesPerEntry, - p.num_counter_bits, p.ps_address_map_cache_indexing_policy)), + p.num_counter_bits, + genTagExtractor(p.ps_address_map_cache_indexing_policy))), spAddressMappingCache((name() + ".SPAddressMappingCache").c_str(), p.address_map_cache_entries, p.address_map_cache_assoc, p.sp_address_map_cache_replacement_policy, p.sp_address_map_cache_indexing_policy, AddressMappingEntry(prefetchCandidatesPerEntry, - p.num_counter_bits, p.sp_address_map_cache_indexing_policy)), + p.num_counter_bits, + genTagExtractor(p.sp_address_map_cache_indexing_policy))), structuralAddressCounter(0) { assert(isPowerOf2(prefetchCandidatesPerEntry)); diff --git a/src/mem/cache/prefetch/irregular_stream_buffer.hh b/src/mem/cache/prefetch/irregular_stream_buffer.hh index a67bb7b143..8f6018b958 100644 --- a/src/mem/cache/prefetch/irregular_stream_buffer.hh +++ b/src/mem/cache/prefetch/irregular_stream_buffer.hh @@ -67,9 +67,11 @@ class IrregularStreamBuffer : public Queued */ struct TrainingUnitEntry : public TaggedEntry { - TrainingUnitEntry(TaggedIndexingPolicy *ip) - : TaggedEntry(ip), lastAddress(0), lastAddressSecure(false) - {} + TrainingUnitEntry(TagExtractor ext) + : TaggedEntry(), lastAddress(0), lastAddressSecure(false) + { + registerTagExtractor(ext); + } Addr lastAddress; bool lastAddressSecure; }; @@ -93,9 +95,10 @@ class IrregularStreamBuffer : public Queued { std::vector mappings; AddressMappingEntry(size_t num_mappings, unsigned counter_bits, - TaggedIndexingPolicy *ip) - : TaggedEntry(ip), mappings(num_mappings, counter_bits) + TagExtractor ext) + : TaggedEntry(), mappings(num_mappings, counter_bits) { + registerTagExtractor(ext); } void diff --git a/src/mem/cache/prefetch/pif.cc b/src/mem/cache/prefetch/pif.cc index cd3e90aa72..70dec5eb02 100644 --- a/src/mem/cache/prefetch/pif.cc +++ b/src/mem/cache/prefetch/pif.cc @@ -48,7 +48,7 @@ PIF::PIF(const PIFPrefetcherParams &p) index((name() + ".PIFIndex").c_str(), p.index_entries, p.index_assoc, p.index_replacement_policy, p.index_indexing_policy, - IndexEntry(p.index_indexing_policy)), + IndexEntry(genTagExtractor(p.index_indexing_policy))), streamAddressBuffer(p.stream_address_buffer_entries), listenersPC() { diff --git a/src/mem/cache/prefetch/pif.hh b/src/mem/cache/prefetch/pif.hh index 673c257e58..00b25c5d5a 100644 --- a/src/mem/cache/prefetch/pif.hh +++ b/src/mem/cache/prefetch/pif.hh @@ -137,7 +137,12 @@ class PIF : public Queued struct IndexEntry : public TaggedEntry { - using TaggedEntry::TaggedEntry; + IndexEntry(TagExtractor ext) + : TaggedEntry() + { + registerTagExtractor(ext); + } + HistoryBuffer::iterator historyIt; }; diff --git a/src/mem/cache/prefetch/signature_path.cc b/src/mem/cache/prefetch/signature_path.cc index 640ffd5110..6d159588c0 100644 --- a/src/mem/cache/prefetch/signature_path.cc +++ b/src/mem/cache/prefetch/signature_path.cc @@ -48,18 +48,18 @@ SignaturePath::SignaturePath(const SignaturePathPrefetcherParams &p) prefetchConfidenceThreshold(p.prefetch_confidence_threshold), lookaheadConfidenceThreshold(p.lookahead_confidence_threshold), signatureTable((name() + ".SignatureTable").c_str(), - p.signature_table_entries, - p.signature_table_assoc, - p.signature_table_replacement_policy, - p.signature_table_indexing_policy, - SignatureEntry(p.signature_table_indexing_policy)), + p.signature_table_entries, + p.signature_table_assoc, + p.signature_table_replacement_policy, + p.signature_table_indexing_policy, + SignatureEntry(genTagExtractor(p.signature_table_indexing_policy))), patternTable((name() + ".PatternTable").c_str(), - p.pattern_table_entries, - p.pattern_table_assoc, - p.pattern_table_replacement_policy, - p.pattern_table_indexing_policy, - PatternEntry(stridesPerPatternEntry, p.num_counter_bits, - p.pattern_table_indexing_policy)) + p.pattern_table_entries, + p.pattern_table_assoc, + p.pattern_table_replacement_policy, + p.pattern_table_indexing_policy, + PatternEntry(stridesPerPatternEntry, p.num_counter_bits, + genTagExtractor(p.pattern_table_indexing_policy))) { fatal_if(prefetchConfidenceThreshold < 0, "The prefetch confidence threshold must be greater than 0\n"); diff --git a/src/mem/cache/prefetch/signature_path.hh b/src/mem/cache/prefetch/signature_path.hh index e2dacd5448..1b3a91845e 100644 --- a/src/mem/cache/prefetch/signature_path.hh +++ b/src/mem/cache/prefetch/signature_path.hh @@ -80,9 +80,11 @@ class SignaturePath : public Queued signature_t signature; /** Last accessed block within a page */ stride_t lastBlock; - SignatureEntry(TaggedIndexingPolicy *ip) - : TaggedEntry(ip), signature(0), lastBlock(0) - {} + SignatureEntry(TagExtractor ext) + : TaggedEntry(), signature(0), lastBlock(0) + { + registerTagExtractor(ext); + } }; /** Signature table */ AssociativeCache signatureTable; @@ -105,10 +107,11 @@ class SignaturePath : public Queued /** use counter, used by SPPv2 */ SatCounter8 counter; PatternEntry(size_t num_strides, unsigned counter_bits, - TaggedIndexingPolicy *ip) - : TaggedEntry(ip), strideEntries(num_strides, counter_bits), + TagExtractor ext) + : TaggedEntry(), strideEntries(num_strides, counter_bits), counter(counter_bits) { + registerTagExtractor(ext); } /** Reset the entries to their initial values */ diff --git a/src/mem/cache/prefetch/signature_path_v2.cc b/src/mem/cache/prefetch/signature_path_v2.cc index 2725b8f800..394003f9f8 100644 --- a/src/mem/cache/prefetch/signature_path_v2.cc +++ b/src/mem/cache/prefetch/signature_path_v2.cc @@ -54,12 +54,12 @@ namespace prefetch SignaturePathV2::SignaturePathV2(const SignaturePathPrefetcherV2Params &p) : SignaturePath(p), globalHistoryRegister((name() + ".GlobalHistoryRegister").c_str(), - p.global_history_register_entries, - p.global_history_register_entries, - p.global_history_register_replacement_policy, - p.global_history_register_indexing_policy, - GlobalHistoryEntry( - p.global_history_register_indexing_policy)) + p.global_history_register_entries, + p.global_history_register_entries, + p.global_history_register_replacement_policy, + p.global_history_register_indexing_policy, + GlobalHistoryEntry( + genTagExtractor(p.global_history_register_indexing_policy))) { } diff --git a/src/mem/cache/prefetch/signature_path_v2.hh b/src/mem/cache/prefetch/signature_path_v2.hh index f2b727716b..8e068e341e 100644 --- a/src/mem/cache/prefetch/signature_path_v2.hh +++ b/src/mem/cache/prefetch/signature_path_v2.hh @@ -62,10 +62,12 @@ class SignaturePathV2 : public SignaturePath double confidence; stride_t lastBlock; stride_t delta; - GlobalHistoryEntry(TaggedIndexingPolicy *ip) - : TaggedEntry(ip), signature(0), confidence(0.0), lastBlock(0), + GlobalHistoryEntry(TagExtractor ext) + : TaggedEntry(), signature(0), confidence(0.0), lastBlock(0), delta(0) - {} + { + registerTagExtractor(ext); + } }; /** Global History Register */ AssociativeCache globalHistoryRegister; diff --git a/src/mem/cache/prefetch/spatio_temporal_memory_streaming.cc b/src/mem/cache/prefetch/spatio_temporal_memory_streaming.cc index cc69bfc4b1..dadda26327 100644 --- a/src/mem/cache/prefetch/spatio_temporal_memory_streaming.cc +++ b/src/mem/cache/prefetch/spatio_temporal_memory_streaming.cc @@ -42,21 +42,21 @@ STeMS::STeMS(const STeMSPrefetcherParams &p) spatialRegionSizeBits(floorLog2(p.spatial_region_size)), reconstructionEntries(p.reconstruction_entries), activeGenerationTable((name() + ".ActiveGenerationTable").c_str(), - p.active_generation_table_entries, - p.active_generation_table_assoc, - p.active_generation_table_replacement_policy, - p.active_generation_table_indexing_policy, - ActiveGenerationTableEntry( - spatialRegionSize / blkSize, - p.active_generation_table_indexing_policy)), + p.active_generation_table_entries, + p.active_generation_table_assoc, + p.active_generation_table_replacement_policy, + p.active_generation_table_indexing_policy, + ActiveGenerationTableEntry( + spatialRegionSize / blkSize, + genTagExtractor(p.active_generation_table_indexing_policy))), patternSequenceTable((name() + ".PatternSequenceTable").c_str(), - p.pattern_sequence_table_entries, - p.pattern_sequence_table_assoc, - p.pattern_sequence_table_replacement_policy, - p.pattern_sequence_table_indexing_policy, - ActiveGenerationTableEntry( - spatialRegionSize / blkSize, - p.pattern_sequence_table_indexing_policy)), + p.pattern_sequence_table_entries, + p.pattern_sequence_table_assoc, + p.pattern_sequence_table_replacement_policy, + p.pattern_sequence_table_indexing_policy, + ActiveGenerationTableEntry( + spatialRegionSize / blkSize, + genTagExtractor(p.pattern_sequence_table_indexing_policy))), rmob(p.region_miss_order_buffer_entries), addDuplicateEntriesToRMOB(p.add_duplicate_entries_to_rmob), lastTriggerCounter(0) diff --git a/src/mem/cache/prefetch/spatio_temporal_memory_streaming.hh b/src/mem/cache/prefetch/spatio_temporal_memory_streaming.hh index 641fb86a14..b5ee66856f 100644 --- a/src/mem/cache/prefetch/spatio_temporal_memory_streaming.hh +++ b/src/mem/cache/prefetch/spatio_temporal_memory_streaming.hh @@ -94,11 +94,11 @@ class STeMS : public Queued /** Sequence of accesses */ std::vector sequence; - ActiveGenerationTableEntry(int num_positions, - TaggedIndexingPolicy *ip) - : TaggedEntry(ip), paddress(0), pc(0), + ActiveGenerationTableEntry(int num_positions, TagExtractor ext) + : TaggedEntry(), paddress(0), pc(0), seqCounter(0), sequence(num_positions) { + registerTagExtractor(ext); } void diff --git a/src/mem/cache/prefetch/stride.cc b/src/mem/cache/prefetch/stride.cc index aaa9ea42a7..323e7125ef 100644 --- a/src/mem/cache/prefetch/stride.cc +++ b/src/mem/cache/prefetch/stride.cc @@ -63,9 +63,10 @@ namespace prefetch { Stride::StrideEntry::StrideEntry(const SatCounter8& init_confidence, - TaggedIndexingPolicy *ip) - : TaggedEntry(ip), confidence(init_confidence) + TagExtractor ext) + : TaggedEntry(), confidence(init_confidence) { + registerTagExtractor(ext); invalidate(); } @@ -114,7 +115,8 @@ Stride::allocateNewContext(int context) pcTableInfo.assoc, pcTableInfo.replacementPolicy, pcTableInfo.indexingPolicy, - StrideEntry(initConfidence, pcTableInfo.indexingPolicy))); + StrideEntry(initConfidence, + genTagExtractor(pcTableInfo.indexingPolicy)))); DPRINTF(HWPrefetch, "Adding context %i with stride entries\n", context); diff --git a/src/mem/cache/prefetch/stride.hh b/src/mem/cache/prefetch/stride.hh index a0ccb3f0c4..7dda838179 100644 --- a/src/mem/cache/prefetch/stride.hh +++ b/src/mem/cache/prefetch/stride.hh @@ -136,8 +136,7 @@ class Stride : public Queued /** Tagged by hashed PCs. */ struct StrideEntry : public TaggedEntry { - StrideEntry(const SatCounter8& init_confidence, - TaggedIndexingPolicy *ip); + StrideEntry(const SatCounter8& init_confidence, TagExtractor ext); void invalidate() override; diff --git a/src/mem/cache/tags/base_set_assoc.cc b/src/mem/cache/tags/base_set_assoc.cc index a4e046344a..e97c8a1193 100644 --- a/src/mem/cache/tags/base_set_assoc.cc +++ b/src/mem/cache/tags/base_set_assoc.cc @@ -84,7 +84,7 @@ BaseSetAssoc::tagsInit() blk->replacementData = replacementPolicy->instantiateEntry(); // This is not used as of now but we set it for security - blk->setIndexingPolicy(indexingPolicy); + blk->registerTagExtractor(genTagExtractor(indexingPolicy)); } } diff --git a/src/mem/cache/tags/sector_blk.cc b/src/mem/cache/tags/sector_blk.cc index 891abac2a6..b3f341486c 100644 --- a/src/mem/cache/tags/sector_blk.cc +++ b/src/mem/cache/tags/sector_blk.cc @@ -112,7 +112,7 @@ SectorSubBlk::print() const } SectorBlk::SectorBlk() - : TaggedEntry(nullptr), _validCounter(0) + : TaggedEntry(), _validCounter(0) { } diff --git a/src/mem/cache/tags/tagged_entry.hh b/src/mem/cache/tags/tagged_entry.hh index 1302d26eef..1a1d773371 100644 --- a/src/mem/cache/tags/tagged_entry.hh +++ b/src/mem/cache/tags/tagged_entry.hh @@ -112,12 +112,19 @@ class TaggedEntry : public ReplaceableEntry public: using KeyType = TaggedTypes::KeyType; using IndexingPolicy = TaggedIndexingPolicy; + using TagExtractor = std::function; - TaggedEntry(IndexingPolicy *ip) - : _valid(false), _secure(false), _tag(MaxAddr), indexingPolicy(ip) + TaggedEntry() + : _valid(false), _secure(false), _tag(MaxAddr) {} ~TaggedEntry() = default; + void + registerTagExtractor(TagExtractor ext) + { + extractTag = ext; + } + /** * Checks if the entry is valid. * @@ -177,12 +184,6 @@ class TaggedEntry : public ReplaceableEntry clearSecure(); } - void - setIndexingPolicy(IndexingPolicy *ip) - { - indexingPolicy = ip; - } - std::string print() const override { @@ -201,11 +202,8 @@ class TaggedEntry : public ReplaceableEntry /** Set secure bit. */ virtual void setSecure() { _secure = true; } - Addr - extractTag(Addr addr) const - { - return indexingPolicy->extractTag(addr); - } + /** Clear secure bit. Should be only used by the invalidation function. */ + void clearSecure() { _secure = false; } /** Set valid bit. The block must be invalid beforehand. */ virtual void @@ -215,6 +213,9 @@ class TaggedEntry : public ReplaceableEntry _valid = true; } + /** Callback used to extract the tag from the entry */ + TagExtractor extractTag; + private: /** * Valid bit. The contents of this entry are only valid if this bit is set. @@ -231,14 +232,22 @@ class TaggedEntry : public ReplaceableEntry /** The entry's tag. */ Addr _tag; - - /** Reference to the indexing policy */ - IndexingPolicy *indexingPolicy; - - /** Clear secure bit. Should be only used by the invalidation function. */ - void clearSecure() { _secure = false; } }; +/** + * This helper generates an a tag extractor function object + * which will be typically used by Replaceable entries indexed + * with the TaggedIndexingPolicy. + * It allows to "decouple" indexing from tagging. Those entries + * would call the functor without directly holding a pointer + * to the indexing policy which should reside in the cache. + */ +static constexpr auto +genTagExtractor(TaggedIndexingPolicy *ip) +{ + return [ip] (Addr addr) { return ip->extractTag(addr); }; +} + } // namespace gem5 #endif//__CACHE_TAGGED_ENTRY_HH__