cpu: Factor the page size out of the decode cache.
authorGabe Black <gabeblack@google.com>
Sat, 22 Aug 2020 05:29:47 +0000 (22:29 -0700)
committerGabe Black <gabeblack@google.com>
Fri, 28 Aug 2020 07:21:07 +0000 (07:21 +0000)
There isn't anything special about using the page size, and it creates
an artificial dependence on the ISA. Instead of being based on pages,
the cache is now based on "chunks" who's size is a template parameter.
It defaults to 4K which is a common page size, but it can be tuned
arbitrarily if necessary.

Some unnecessary includes have been trimmed out as well.

Change-Id: I9fe59a5668d702433a800884fbfbdce20e0ade97
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/33204
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/cpu/decode_cache.hh

index a4ce349040310f221e7dc2d3e74e80ce8612dfd5..20b6783d2d79d2f4fb4995e589426cbe72622f61 100644 (file)
 
 #include <unordered_map>
 
-#include "arch/isa_traits.hh"
-#include "arch/types.hh"
-#include "config/the_isa.hh"
+#include "base/bitfield.hh"
 #include "cpu/static_inst_fwd.hh"
 
-namespace TheISA
-{
-    class Decoder;
-}
-
 namespace DecodeCache
 {
 
@@ -49,78 +42,92 @@ template <typename EMI>
 using InstMap = std::unordered_map<EMI, StaticInstPtr>;
 
 /// A sparse map from an Addr to a Value, stored in page chunks.
-template<class Value>
+template<class Value, Addr CacheChunkShift = 12>
 class AddrMap
 {
   protected:
-    // A pages worth of cache entries.
-    struct CachePage {
-        Value items[TheISA::PageBytes];
+    static constexpr Addr CacheChunkBytes = 1ULL << CacheChunkShift;
+
+    static constexpr Addr
+    chunkOffset(Addr addr)
+    {
+        return addr & (CacheChunkBytes - 1);
+    }
+
+    static constexpr Addr
+    chunkStart(Addr addr)
+    {
+        return addr & ~(CacheChunkBytes - 1);
+    }
+
+    // A chunk of cache entries.
+    struct CacheChunk
+    {
+        Value items[CacheChunkBytes];
     };
-    // A map of cache pages which allows a sparse mapping.
-    typedef typename std::unordered_map<Addr, CachePage *> PageMap;
-    typedef typename PageMap::iterator PageIt;
+    // A map of cache chunks which allows a sparse mapping.
+    typedef typename std::unordered_map<Addr, CacheChunk *> ChunkMap;
+    typedef typename ChunkMap::iterator ChunkIt;
     // Mini cache of recent lookups.
-    PageIt recent[2];
-    PageMap pageMap;
+    ChunkIt recent[2];
+    ChunkMap chunkMap;
 
     /// Update the mini cache of recent lookups.
     /// @param recentest The most recent result;
     void
-    update(PageIt recentest)
+    update(ChunkIt recentest)
     {
         recent[1] = recent[0];
         recent[0] = recentest;
     }
 
-    /// Attempt to find the CacheePage which goes with a particular
+    /// Attempt to find the CacheChunk which goes with a particular
     /// address. First check the small cache of recent results, then
     /// actually look in the hash map.
     /// @param addr The address to look up.
-    CachePage *
-    getPage(Addr addr)
+    CacheChunk *
+    getChunk(Addr addr)
     {
-        Addr page_addr = addr & ~(TheISA::PageBytes - 1);
+        Addr chunk_addr = chunkStart(addr);
 
         // Check against recent lookups.
-        if (recent[0] != pageMap.end()) {
-            if (recent[0]->first == page_addr)
+        if (recent[0] != chunkMap.end()) {
+            if (recent[0]->first == chunk_addr)
                 return recent[0]->second;
-            if (recent[1] != pageMap.end() &&
-                    recent[1]->first == page_addr) {
+            if (recent[1] != chunkMap.end() &&
+                    recent[1]->first == chunk_addr) {
                 update(recent[1]);
                 // recent[1] has just become recent[0].
                 return recent[0]->second;
             }
         }
 
-        // Actually look in the has_map.
-        PageIt it = pageMap.find(page_addr);
-        if (it != pageMap.end()) {
+        // Actually look in the hash_map.
+        ChunkIt it = chunkMap.find(chunk_addr);
+        if (it != chunkMap.end()) {
             update(it);
             return it->second;
         }
 
-        // Didn't find an existing page, so add a new one.
-        CachePage *newPage = new CachePage;
-        page_addr = page_addr & ~(TheISA::PageBytes - 1);
-        typename PageMap::value_type to_insert(page_addr, newPage);
-        update(pageMap.insert(to_insert).first);
-        return newPage;
+        // Didn't find an existing chunk, so add a new one.
+        CacheChunk *newChunk = new CacheChunk;
+        typename ChunkMap::value_type to_insert(chunk_addr, newChunk);
+        update(chunkMap.insert(to_insert).first);
+        return newChunk;
     }
 
   public:
     /// Constructor
     AddrMap()
     {
-        recent[0] = recent[1] = pageMap.end();
+        recent[0] = recent[1] = chunkMap.end();
     }
 
     Value &
     lookup(Addr addr)
     {
-        CachePage *page = getPage(addr);
-        return page->items[addr & (TheISA::PageBytes - 1)];
+        CacheChunk *chunk = getChunk(addr);
+        return chunk->items[chunkOffset(addr)];
     }
 };