mem-cache: Add move assign and delete move constr of blk
authorDaniel R. Carvalho <odanrc@yahoo.com.br>
Fri, 24 May 2019 09:33:11 +0000 (11:33 +0200)
committerDaniel Carvalho <odanrc@yahoo.com.br>
Thu, 12 Nov 2020 21:46:43 +0000 (21:46 +0000)
Some cache techniques may need to move a block's metadata information
into another block. This must have some limitations to avoid mistakes:
- The destination entry must be invalid, otherwise the replacement
  policy steps would be skipped.
- The source entry must be valid, otherwise there would be no point
  in moving their metadata contents.
- The entries locations (set, way, offset...) must not be moved, since
  they are fixed. The same principle is applied to the location specific
  variables, such as the replacement pointer

Why it would be used:
For example, when using compression, and a block goes from uncompressed
to compressed state due to an overwrite, after the tag lookup
(sequential access) it can be decided whether to store the new data in
the old location, or, since we might have already found the block's co-
allocatable blocks, move it to co-allocate.

Other examples of techniques that could use this functionality are
Skewed Compressed Caches, and ZCaches.

Change-Id: I96e4f8cc8c992c4b01f315251d1a75d51c28692c
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/36575
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/mem/cache/cache_blk.hh
src/mem/cache/tags/sector_blk.hh
src/mem/cache/tags/super_blk.cc
src/mem/cache/tags/super_blk.hh

index bcd5c4b1b51db14b11504f08f0a057ab625f5a74..2d866a8cc864f446107ca960ece6b57200be13e3 100644 (file)
@@ -155,6 +155,39 @@ class CacheBlk : public TaggedEntry
 
     CacheBlk(const CacheBlk&) = delete;
     CacheBlk& operator=(const CacheBlk&) = delete;
+    CacheBlk(const CacheBlk&&) = delete;
+    /**
+     * Move assignment operator.
+     * This should only be used to move an existing valid entry into an
+     * invalid one, not to create a new entry. In the end the valid entry
+     * will become invalid, and the invalid, valid. All location related
+     * variables will remain the same, that is, an entry cannot move its
+     * data, just its metadata contents.
+     */
+    virtual CacheBlk&
+    operator=(CacheBlk&& other)
+    {
+        // Copying an entry into a valid one would imply in skipping all
+        // replacement steps, so it cannot be allowed
+        assert(!isValid());
+        assert(other.isValid());
+
+        insert(other.getTag(), other.isSecure());
+
+        if (other.wasPrefetched()) {
+            setPrefetched();
+        }
+        setCoherenceBits(other.coherence);
+        setTaskId(other.getTaskId());
+        setWhenReady(curTick());
+        setRefCount(other.getRefCount());
+        setSrcRequestorId(other.getSrcRequestorId());
+        std::swap(lockList, other.lockList);
+
+        other.invalidate();
+
+        return *this;
+    }
     virtual ~CacheBlk() {};
 
     /**
@@ -168,7 +201,7 @@ class CacheBlk : public TaggedEntry
         clearCoherenceBits(AllBits);
 
         setTaskId(ContextSwitchTaskId::Unknown);
-        whenReady = MaxTick;
+        setWhenReady(MaxTick);
         setRefCount(0);
         setSrcRequestorId(Request::invldRequestorId);
         lockList.clear();
index ea3c79aa9a225ade573f8498ae88207607bdf2ef..2d649cd427dba70a62a5fc147fae6c046b22a6d3 100644 (file)
@@ -62,7 +62,17 @@ class SectorSubBlk : public CacheBlk
     SectorSubBlk() : CacheBlk(), _sectorBlk(nullptr), _sectorOffset(0) {}
     SectorSubBlk(const SectorSubBlk&) = delete;
     SectorSubBlk& operator=(const SectorSubBlk&) = delete;
-    ~SectorSubBlk() {};
+    SectorSubBlk(SectorSubBlk&&) = delete;
+    /**
+     * Move assignment operator.
+     * This should only be used to move an existing valid entry into an
+     * invalid one, not to create a new entry. In the end the valid entry
+     * will become invalid, and the invalid, valid. All location related
+     * variables will remain the same, that is, an entry cannot change
+     * its sector block nor its offset.
+     */
+    SectorSubBlk& operator=(SectorSubBlk&& other) = default;
+    ~SectorSubBlk() = default;
 
     /**
      * Set sector block associated to this block.
index 0f570f947923f072c69a062a83d41457700504f8..a6d8afb8162417be9507df5d0984311d9916a7af 100644 (file)
@@ -41,6 +41,30 @@ CompressionBlk::CompressionBlk()
 {
 }
 
+CacheBlk&
+CompressionBlk::operator=(CacheBlk&& other)
+{
+    operator=(std::move(static_cast<CompressionBlk&&>(other)));
+    return *this;
+}
+
+CompressionBlk&
+CompressionBlk::operator=(CompressionBlk&& other)
+{
+    // Copy internal variables; if moving, that means we had an expansion or
+    // contraction, and therefore the size is no longer valid, so it is not
+    // moved
+    setDecompressionLatency(other.getDecompressionLatency());
+    if (other.isCompressed()) {
+        setCompressed();
+    } else {
+        setUncompressed();
+    }
+
+    CacheBlk::operator=(std::move(other));
+    return *this;
+}
+
 bool
 CompressionBlk::isCompressed() const
 {
index bca32662fc6966bc52fe368703e998205afb40c9..d7abe18723a75479045e8079fefef43bee714959 100644 (file)
@@ -66,7 +66,17 @@ class CompressionBlk : public SectorSubBlk
     CompressionBlk();
     CompressionBlk(const CompressionBlk&) = delete;
     CompressionBlk& operator=(const CompressionBlk&) = delete;
-    ~CompressionBlk() {};
+    CompressionBlk(CompressionBlk&&) = delete;
+    /**
+     * Move assignment operator.
+     * This should only be used to move an existing valid entry into an
+     * invalid one, not to create a new entry. In the end the valid entry
+     * will become invalid, and the invalid, valid. All location related
+     * variables will remain the same.
+     */
+    CompressionBlk& operator=(CompressionBlk&& other);
+    CacheBlk& operator=(CacheBlk&& other);
+    ~CompressionBlk() = default;
 
     /**
      * Check if this block holds compressed data.