mem-cache: ReplacementPolicy specific replacement data
[gem5.git] / src / mem / cache / tags / base_set_assoc.hh
index 3bc275b281191036004ea3ad42d8f82b62e79fc9..5a3e832c15e356bb02631f22ecac79fa3216e35a 100644 (file)
 
 #include <cassert>
 #include <cstring>
-#include <memory>
 #include <vector>
 
+#include "debug/CacheRepl.hh"
 #include "mem/cache/base.hh"
 #include "mem/cache/blk.hh"
+#include "mem/cache/replacement_policies/base.hh"
 #include "mem/cache/tags/base.hh"
 #include "mem/cache/tags/cacheset.hh"
 #include "mem/packet.hh"
@@ -105,7 +106,6 @@ class BaseSetAssoc : public BaseTags
     BaseReplacementPolicy *replacementPolicy;
 
   public:
-
     /** Convenience typedef. */
      typedef BaseSetAssocParams Params;
 
@@ -119,6 +119,14 @@ class BaseSetAssoc : public BaseTags
      */
     virtual ~BaseSetAssoc() {};
 
+    /**
+     * This function updates the tags when a block is invalidated but does
+     * not invalidate the block itself. It also updates the replacement data.
+     *
+     * @param blk The block to invalidate.
+     */
+    void invalidate(CacheBlk *blk) override;
+
     /**
      * Find the cache block given set and way
      * @param set The set of the block.
@@ -165,8 +173,11 @@ class BaseSetAssoc : public BaseTags
                 accessLatency;
             }
 
+            // Update number of references to accessed block
+            blk->refCount++;
+
             // Update replacement data of accessed block
-            replacementPolicy->touch(blk);
+            replacementPolicy->touch(blk->replacementData);
         } else {
             // If a cache miss
             lat = lookupLatency;
@@ -193,8 +204,18 @@ class BaseSetAssoc : public BaseTags
      */
     CacheBlk* findVictim(Addr addr) override
     {
+        // Get possible locations for the victim block
+        std::vector<CacheBlk*> locations = getPossibleLocations(addr);
+
         // Choose replacement victim from replacement candidates
-        return replacementPolicy->getVictim(getPossibleLocations(addr));
+        CacheBlk* victim = static_cast<CacheBlk*>(replacementPolicy->getVictim(
+                               std::vector<ReplaceableEntry*>(
+                                   locations.begin(), locations.end())));
+
+        DPRINTF(CacheRepl, "set %x, way %x: selecting blk for replacement\n",
+            victim->set, victim->way);
+
+        return victim;
     }
 
     /**
@@ -212,55 +233,19 @@ class BaseSetAssoc : public BaseTags
     }
 
     /**
-     * Insert the new block into the cache.
+     * Insert the new block into the cache and update replacement data.
+     *
      * @param pkt Packet holding the address to update
      * @param blk The block to update.
      */
-     void insertBlock(PacketPtr pkt, CacheBlk *blk) override
-     {
-         Addr addr = pkt->getAddr();
-         MasterID master_id = pkt->req->masterId();
-         uint32_t task_id = pkt->req->taskId();
-
-         if (!blk->isTouched) {
-             if (!warmedUp && tagsInUse.value() >= warmupBound) {
-                 warmedUp = true;
-                 warmupCycle = curTick();
-             }
-         }
-
-         // If we're replacing a block that was previously valid update
-         // stats for it. This can't be done in findBlock() because a
-         // found block might not actually be replaced there if the
-         // coherence protocol says it can't be.
-         if (blk->isValid()) {
-             replacements[0]++;
-             totalRefs += blk->refCount;
-             ++sampledRefs;
-
-             invalidate(blk);
-             blk->invalidate();
-         }
-
-         // Previous block, if existed, has been removed, and now we have
-         // to insert the new one
-         tagsInUse++;
-
-         // Set tag for new block.  Caller is responsible for setting status.
-         blk->tag = extractTag(addr);
-
-         // deal with what we are bringing in
-         assert(master_id < cache->system->maxMasters());
-         occupancies[master_id]++;
-         blk->srcMasterId = master_id;
-         blk->task_id = task_id;
-
-         // We only need to write into one tag and one data block.
-         tagAccesses += 1;
-         dataAccesses += 1;
-
-         replacementPolicy->reset(blk);
-     }
+    void insertBlock(PacketPtr pkt, CacheBlk *blk) override
+    {
+        // Insert block
+        BaseTags::insertBlock(pkt, blk);
+
+        // Update replacement policy
+        replacementPolicy->reset(blk->replacementData);
+    }
 
     /**
      * Limit the allocation for the cache ways.
@@ -340,8 +325,8 @@ class BaseSetAssoc : public BaseTags
      * \param visitor Visitor to call on each block.
      */
     void forEachBlk(CacheBlkVisitor &visitor) override {
-        for (unsigned i = 0; i < numSets * assoc; ++i) {
-            if (!visitor(blks[i]))
+        for (CacheBlk& blk : blks) {
+            if (!visitor(blk))
                 return;
         }
     }