Hello Giacomo Travaglini, Andreas Sandberg,

I'd like you to do a code review. Please visit

    https://gem5-review.googlesource.com/c/public/gem5/+/14416

to review the following change.


Change subject: mem-cache: virtual address support for prefetchers
......................................................................

mem-cache: virtual address support for prefetchers

Prefetchers can be configured to operate with virtual or physical addreses.
The option can be configured through the "use_va" parameter of the
Prefetcher object.

Change-Id: I4f8c3687988afecc8a91c3c5b2d44cc0580f72aa
---
M src/mem/cache/prefetch/Prefetcher.py
M src/mem/cache/prefetch/base.cc
M src/mem/cache/prefetch/base.hh
M src/mem/cache/prefetch/queued.cc
M src/mem/cache/prefetch/queued.hh
M src/mem/cache/prefetch/stride.cc
M src/mem/cache/prefetch/stride.hh
M src/mem/cache/prefetch/tagged.cc
M src/mem/cache/prefetch/tagged.hh
9 files changed, 410 insertions(+), 99 deletions(-)



diff --git a/src/mem/cache/prefetch/Prefetcher.py b/src/mem/cache/prefetch/Prefetcher.py
index bae235d..cd25571 100644
--- a/src/mem/cache/prefetch/Prefetcher.py
+++ b/src/mem/cache/prefetch/Prefetcher.py
@@ -94,6 +94,7 @@
         if len(probeNames) <= 0:
             raise TypeError("probeNames must have at least one element")
         self.addEvent(HWPProbeEvent(self, simObj, *probeNames))
+    use_va  = Param.Bool(False, "Use VA for prefetching")

 class QueuedPrefetcher(BasePrefetcher):
     type = "QueuedPrefetcher"
diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc
index 53260ae..4295d33 100644
--- a/src/mem/cache/prefetch/base.cc
+++ b/src/mem/cache/prefetch/base.cc
@@ -56,6 +56,59 @@
 #include "params/BasePrefetcher.hh"
 #include "sim/system.hh"

+
+BasePrefetcher::PrefetcherAddressBase::PrefetcherAddressBase(PacketPtr pkt,
+ unsigned blkSize)
+  : PrefetcherAddress(pkt),
+    paddress(pkt->req->hasPaddr() ?
+        pkt->req->getPaddr() & ~((Addr)blkSize - 1) : 0),
+    vaddress(pkt->req->hasVaddr() ?
+        pkt->req->getVaddr() & ~((Addr)blkSize - 1) : 0),
+    validPA(pkt->req->hasPaddr()), validVA(pkt->req->hasVaddr())
+{
+}
+
+BasePrefetcher::PrefetcherAddressBase::PrefetcherAddressBase(
+ PrefetcherAddressBase const &pfa, Addr addr)
+    : PrefetcherAddress(pfa), validPA(pfa.validPA), validVA(pfa.validVA)
+{
+    if (addr >= pfa.getAddr()) {
+        //positive stride
+        Addr stride = addr - pfa.getAddr();
+        paddress = pfa.validPA ? (pfa.paddress + stride) : 0;
+        vaddress = pfa.validVA ? (pfa.vaddress + stride) : 0;
+    } else {
+        //negative stride
+        Addr stride = pfa.getAddr() - addr;
+        paddress = pfa.validPA ? (pfa.paddress - stride) : 0;
+        vaddress = pfa.validVA ? (pfa.vaddress - stride) : 0;
+    }
+}
+
+Addr
+BasePrefetcher::PrefetcherVirtualAddress::getAddr() const
+{
+    return this->getVaddr();
+}
+
+BasePrefetcher::PrefetcherAddressBase *
+BasePrefetcher::PrefetcherVirtualAddress::makePrefetcherAddress(Addr a) const
+{
+    return new PrefetcherVirtualAddress(*this, a);
+}
+
+Addr
+BasePrefetcher::PrefetcherPhysicalAddress::getAddr() const
+{
+    return this->getPaddr();
+}
+
+BasePrefetcher::PrefetcherAddressBase *
+BasePrefetcher::PrefetcherPhysicalAddress::makePrefetcherAddress(Addr a) const
+{
+    return new PrefetcherPhysicalAddress(*this, a);
+}
+
 void
 BasePrefetcher::PrefetchListener::notify(const PacketPtr &pkt)
 {
@@ -67,7 +120,7 @@
       lBlkSize(floorLog2(blkSize)), onMiss(p->on_miss), onRead(p->on_read),
       onWrite(p->on_write), onData(p->on_data), onInst(p->on_inst),
masterId(p->sys->getMasterId(this)), pageBytes(p->sys->getPageBytes()),
-      prefetchOnAccess(p->prefetch_on_access)
+      prefetchOnAccess(p->prefetch_on_access), useVa(p->use_va)
 {
 }

@@ -175,7 +228,20 @@
     if (pkt->cmd.isSWPrefetch()) return;
     if (pkt->req->isCacheMaintenance()) return;
     if (pkt->isWrite() && cache != nullptr && cache->coalesce()) return;
-    notify(pkt);
+
+    // Verify this access type is observed by prefetcher
+    if (observeAccess(pkt)) {
+        PrefetcherAddressBase* pfa = nullptr;
+        if (useVa && pkt->req->hasVaddr() && pkt->req->hasPaddr()) {
+            pfa = new PrefetcherVirtualAddress(pkt, blkSize);
+        } else if (!useVa && pkt->req->hasPaddr()) {
+            pfa = new PrefetcherPhysicalAddress(pkt, blkSize);
+        }
+        if (pfa != nullptr) {
+            notify(*pfa);
+        }
+        delete pfa;
+    }
 }

 void
diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh
index 813d1b9..2455f42 100644
--- a/src/mem/cache/prefetch/base.hh
+++ b/src/mem/cache/prefetch/base.hh
@@ -76,8 +76,232 @@
     };

     std::vector<PrefetchListener *> listeners;
+
   protected:

+    /**
+     * Abstract interface that represents a PrefetcherAddress, an address
+     * used by the prefetcher to calculate new prefetch requests.
+     */
+    class PrefetcherAddress {
+        /** The program counter that generated this address. */
+        const Addr pc;
+        /** The requestor ID that generated this address. */
+        const MasterID masterId;
+        /** Validity bit for the PC of this address. */
+        const bool validPC;
+        /** Whether this address targets the secure memory space. */
+        const bool secure;
+      protected:
+        /**
+         * Create a PrefetcherAddress using a PacketPtr
+         * @param pkt PacketPtr used to create the PrefetcherAddress
+         */
+        PrefetcherAddress(PacketPtr pkt) :
+            pc(pkt->req->hasPC() ? pkt->req->getPC() : 0),
+            masterId(pkt->req->masterId()), validPC(pkt->req->hasPC()),
+            secure(pkt->isSecure()) {}
+        /** Copy constructor */
+        PrefetcherAddress(const PrefetcherAddress &pfa) :
+            pc(pfa.validPC ? pfa.pc : 0), masterId(pfa.masterId),
+            validPC(pfa.validPC), secure(pfa.secure) {}
+      public:
+        /**
+         * Obtains the address value of this Prefetcher address.
+         * @return the addres value.
+         */
+        virtual Addr getAddr() const = 0;
+
+        /**
+         * Returns true if the address targets the secure memory space.
+         * @return true if the address targets the secure memory space.
+         */
+        bool isSecure() const
+        {
+            return secure;
+        }
+
+        /**
+         * Returns the program counter that generated this request.
+         * @return the pc value
+         */
+        Addr getPC() const
+        {
+            return pc;
+        }
+
+        /**
+         * Returns true if the associated program counter is valid
+         * @return true if the program counter has a valid value
+         */
+        bool hasPC() const
+        {
+            return validPC;
+        }
+
+        /**
+         * Gets the requestor ID that generated this address
+         * @return the requestor ID that generated this address
+         */
+        MasterID getMasterId() const
+        {
+            return masterId;
+        }
+
+    };
+
+    /**
+ * Implementation of a PrefetcherAddress, it is designed to be specialized
+     * to hold Virtual or Physical addresses. This class holds the common
+     * information to both specializations.
+     */
+    class PrefetcherAddressBase : public PrefetcherAddress {
+        /** The physical address. */
+        Addr paddress;
+        /** The virtual address itself */
+        Addr vaddress;
+        /** Validity bit of the physical address. */
+        bool validPA;
+        /** Validity bit of the virtual address. */
+        bool validVA;
+
+      public:
+        virtual ~PrefetcherAddressBase() {}
+
+        /**
+         * Returns the physical address value
+         * @return the physical address value
+         */
+        virtual Addr getPaddr() const
+        {
+            return paddress;
+        }
+
+        /**
+         * Returns whether the physical address value is valid or not
+         * @return true if the physical address is valid
+         */
+        bool validPaddr() const
+        {
+            return validPA;
+        }
+
+        /**
+         * Returns the virtual address value
+         * @return the virtual address value
+         */
+        virtual Addr getVaddr() const
+        {
+            return vaddress;
+        }
+
+        /**
+         * Returns whether the virtual address value is valid or not
+         * @return true if the virtual address is valid
+         */
+        bool validVaddr() const
+        {
+            return validVA;
+        }
+
+        /**
+         * Check for equality
+         * @param pfa PrefetcherAddressBase to compare against
+         * @return True if this object and the provided one are equal
+         */
+        bool sameAddr(PrefetcherAddressBase const &pfa) const
+        {
+            return this->getAddr() == pfa.getAddr() &&
+                this->isSecure() == pfa.isSecure();
+        }
+
+        /**
+ * Creates a new PrefetcherAddressBase object from this one, Used for
+         * generating prefetch requests from this prefetch address.
+ * @param addr address value of the new PrefetcherAddressBase object
+         * @return a pointer to the newly PrefetcherAddressBase object
+         */
+ virtual PrefetcherAddressBase *makePrefetcherAddress(Addr) const = 0;
+
+      protected:
+        /**
+ * Constructs a PrefetcherAddressBase using a PacketPtr, the address
+         * is aligned to the block size of the prefetcher.
+         * @param pkt PacketPtr used to generate the PrefetcherAddressBase
+         * @param blkSize block size used by the prefetcher
+         */
+        PrefetcherAddressBase(PacketPtr pkt, unsigned blkSize);
+
+        /**
+         * Constructs a PrefetcherAddressBase using a new address value and
+         * another PrefetcherAddressBase as a reference.
+ * @param pfa PrefetcherAddressBase used to generate this new object
+         * @param addr the address value of the new object
+         */
+        PrefetcherAddressBase(PrefetcherAddressBase const &pfa, Addr addr);
+    };
+
+  private:
+    /**
+     * Specialization of a PrefetcherAddressBase to hold a virtual address.
+     * A virtual address may have an associated phisical address.
+     */
+    class PrefetcherVirtualAddress : public PrefetcherAddressBase {
+        /**
+ * Private constructor using an already existing PrefetcherAddressBase.
+         * @param pfa PrefetcherAddressBase used to build this object
+         * @param addr virtual address of the new object
+         */
+ PrefetcherVirtualAddress(PrefetcherAddressBase const &pfa, Addr vaddr)
+          : PrefetcherAddressBase(pfa, vaddr) {}
+
+      public:
+        /**
+         * Public constructor used to build a PrefetcherVirtualAddress from
+ * a newly received probe event, using a PacketPtr and the block size
+         * of the prefetcher.
+         * @param pkt the memory packet triggering the prefetch event
+         * @param blkSize operating block size of the prefetcher
+         */
+        PrefetcherVirtualAddress(PacketPtr pkt, unsigned blkSize)
+          : PrefetcherAddressBase(pkt, blkSize) {}
+        virtual ~PrefetcherVirtualAddress() {}
+
+        Addr getAddr() const override;
+ PrefetcherAddressBase *makePrefetcherAddress(Addr addr) const override;
+    };
+
+    /**
+ * Specialization of a PrefetcherAddressBase to hold a physical address.
+     * A physical address may have an associated virtual address.
+     */
+    class PrefetcherPhysicalAddress : public PrefetcherAddressBase {
+
+        /**
+ * Private constructor using an already existing PrefetcherAddressBase.
+         * @param pfa PrefetcherAddressBase used to build this object
+         * @param paddr physical address of the new object
+         */
+ PrefetcherPhysicalAddress(PrefetcherAddressBase const &pfa, Addr paddr)
+          : PrefetcherAddressBase(pfa, paddr) {}
+
+      public:
+        /**
+ * Public constructor used to build a PrefetcherPhysicalAddress from + * a newly received probe event, using a PacketPtr and the block size
+         * of the prefetcher.
+         * @param pkt the memory packet triggering the prefetch event
+         * @param blkSize operating block size of the prefetcher
+         */
+        PrefetcherPhysicalAddress(PacketPtr pkt, unsigned blkSize)
+          : PrefetcherAddressBase(pkt, blkSize) {}
+        virtual ~PrefetcherPhysicalAddress() {}
+
+        Addr getAddr() const override;
+ PrefetcherAddressBase *makePrefetcherAddress(Addr addr) const override;
+    };
+
+  protected:
     // PARAMETERS

     /** Pointr to the parent cache. */
@@ -112,6 +336,9 @@
     /** Prefetch on every access, not just misses */
     const bool prefetchOnAccess;

+    /** Use VA for prefetching */
+    const bool useVa;
+
     /** Determine if this access should be observed */
     bool observeAccess(const PacketPtr &pkt) const;

@@ -149,7 +376,7 @@
      * Notify prefetcher of cache access (may be any access or just
      * misses, depending on cache parameters.)
      */
-    virtual void notify(const PacketPtr &pkt) = 0;
+    virtual void notify(const PrefetcherAddressBase &pfa) = 0;

     virtual PacketPtr getPacket() = 0;

diff --git a/src/mem/cache/prefetch/queued.cc b/src/mem/cache/prefetch/queued.cc
index ba4c940..8ded10e 100644
--- a/src/mem/cache/prefetch/queued.cc
+++ b/src/mem/cache/prefetch/queued.cc
@@ -60,53 +60,48 @@
     // Delete the queued prefetch packets
     for (DeferredPacket &p : pfq) {
         delete p.pkt;
+        delete p.address;
     }
 }

 void
-QueuedPrefetcher::notify(const PacketPtr &pkt)
+QueuedPrefetcher::notify(const PrefetcherAddressBase &pfa)
 {
-    // Verify this access type is observed by prefetcher
-    if (observeAccess(pkt)) {
-        Addr blk_addr = pkt->getBlockAddr(blkSize);
-        bool is_secure = pkt->isSecure();
-
-        // Squash queued prefetches if demand miss to same line
-        if (queueSquash) {
-            auto itr = pfq.begin();
-            while (itr != pfq.end()) {
-                if (itr->pkt->getAddr() == blk_addr &&
-                    itr->pkt->isSecure() == is_secure) {
-                    delete itr->pkt;
-                    itr = pfq.erase(itr);
-                } else {
-                    ++itr;
-                }
+    // Squash queued prefetches if demand miss to same line
+    if (queueSquash) {
+        auto itr = pfq.begin();
+        while (itr != pfq.end()) {
+            if (pfa.sameAddr(itr->getAddr())) {
+                delete itr->pkt;
+                delete itr->address;
+                itr = pfq.erase(itr);
+            } else {
+                ++itr;
             }
         }
+    }

-        // Calculate prefetches given this access
-        std::vector<AddrPriority> addresses;
-        calculatePrefetch(pkt, addresses);
+    // Calculate prefetches given this access
+    std::vector<AddrPriority> addresses;
+    calculatePrefetch(pfa, addresses);

-        // Queue up generated prefetches
-        for (AddrPriority& pf_info : addresses) {
-            // Block align prefetch address
-            pf_info.first = blockAddress(pf_info.first);
+    // Queue up generated prefetches
+    for (AddrPriority& pf_info : addresses) {

-            pfIdentified++;
-            DPRINTF(HWPrefetch, "Found a pf candidate addr: %#x, "
-                    "inserting into prefetch queue.\n", pf_info.first);
+        // Block align prefetch address
+        pf_info.first = blockAddress(pf_info.first);

-            // Create and insert the request
-            PacketPtr pf_pkt = insert(pf_info, is_secure);
+        PrefetcherAddressBase *newpfa =
+            pfa.makePrefetcherAddress(pf_info.first);

-            if (pf_pkt != nullptr) {
-                if (tagPrefetch && pkt->req->hasPC()) {
-                    // Tag prefetch packet with  accessing pc
-                    pf_pkt->req->setPC(pkt->req->getPC());
-                }
-            }
+        pfIdentified++;
+        DPRINTF(HWPrefetch, "Found a pf candidate paddr:%#x (vaddr:%#x)"
+                "inserting into prefetch queue.\n", newpfa->getPaddr(),
+                newpfa->getVaddr());
+
+        // Create and insert the request
+        if (!insert(*newpfa, pf_info.second)) {
+            delete newpfa;
         }
     }
 }
@@ -121,32 +116,33 @@
         return nullptr;
     }

-    PacketPtr pkt = pfq.begin()->pkt;
+    PacketPtr pkt = pfq.front().pkt;
+    PrefetcherAddressBase *pfa = pfq.front().address;
     pfq.pop_front();

     pfIssued++;
     assert(pkt != nullptr);
-    DPRINTF(HWPrefetch, "Generating prefetch for %#x.\n", pkt->getAddr());
+    DPRINTF(HWPrefetch, "Generating prefetch for paddr:%#x (vaddr:%#x).\n",
+            pfa->getPaddr(), pfa->getVaddr());
+    delete pfa;
     return pkt;
 }

 QueuedPrefetcher::const_iterator
-QueuedPrefetcher::inPrefetch(Addr address, bool is_secure) const
+QueuedPrefetcher::inPrefetch(const PrefetcherAddressBase &pfa) const
 {
     for (const_iterator dp = pfq.begin(); dp != pfq.end(); dp++) {
-        if ((*dp).pkt->getAddr() == address &&
-            (*dp).pkt->isSecure() == is_secure) return dp;
+        if (dp->getAddr().sameAddr(pfa)) return dp;
     }

     return pfq.end();
 }

 QueuedPrefetcher::iterator
-QueuedPrefetcher::inPrefetch(Addr address, bool is_secure)
+QueuedPrefetcher::inPrefetch(const PrefetcherAddressBase &pfa)
 {
     for (iterator dp = pfq.begin(); dp != pfq.end(); dp++) {
-        if (dp->pkt->getAddr() == address &&
-            dp->pkt->isSecure() == is_secure) return dp;
+        if (dp->getAddr().sameAddr(pfa)) return dp;
     }

     return pfq.end();
@@ -178,17 +174,17 @@
         .desc("number of prefetches not generated due to page crossing");
 }

-PacketPtr
-QueuedPrefetcher::insert(AddrPriority &pf_info, bool is_secure)
+bool
+QueuedPrefetcher::insert(PrefetcherAddressBase &new_pfa, int32_t priority)
 {
     if (queueFilter) {
-        iterator it = inPrefetch(pf_info.first, is_secure);
+        iterator it = inPrefetch(new_pfa);
/* If the address is already in the queue, update priority and leave */
         if (it != pfq.end()) {
             pfBufferHit++;
-            if (it->priority < pf_info.second) {
+            if (it->priority < priority) {
                 /* Update priority value and position in the queue */
-                it->priority = pf_info.second;
+                it->priority = priority;
                 iterator prev = it;
                 bool cont = true;
                 while (cont && prev != pfq.begin()) {
@@ -205,28 +201,24 @@
                 DPRINTF(HWPrefetch, "Prefetch addr already in "
                     "prefetch queue\n");
             }
-            return nullptr;
+            return false;
         }
     }

-    if (cacheSnoop && (inCache(pf_info.first, is_secure) ||
-                inMissQueue(pf_info.first, is_secure))) {
+    if (cacheSnoop && new_pfa.validPaddr() &&
+            (inCache(new_pfa.getPaddr(), new_pfa.isSecure()) ||
+            inMissQueue(new_pfa.getPaddr(), new_pfa.isSecure()))) {
         pfInCache++;
         DPRINTF(HWPrefetch, "Dropping redundant in "
-                "cache/MSHR prefetch addr:%#x\n", pf_info.first);
-        return nullptr;
+                "cache/MSHR prefetch paddr:%#x (vaddr:%#x)\n",
+                new_pfa.getPaddr(), new_pfa.getVaddr());
+        return false;
     }

     /* Create a prefetch memory request */
-    RequestPtr pf_req =
-        std::make_shared<Request>(pf_info.first, blkSize, 0, masterId);
-
-    if (is_secure) {
-        pf_req->setFlags(Request::SECURE);
-    }
-    pf_req->taskId(ContextSwitchTaskId::Prefetcher);
-    PacketPtr pf_pkt = new Packet(pf_req, MemCmd::HardPFReq);
-    pf_pkt->allocate();
+    Tick pf_time = curTick() + clockPeriod() * latency;
+    DeferredPacket dpp(&new_pfa, pf_time, priority, blkSize, masterId,
+                       tagPrefetch);

     /* Verify prefetch buffer space for request */
     if (pfq.size() == queueSize) {
@@ -243,24 +235,25 @@
         while (cont && prev != pfq.begin()) {
             prev--;
             /* While at the same level of priority */
-            cont = (*prev).priority == (*it).priority;
+            cont = prev->priority == it->priority;
             if (cont)
                 /* update pointer */
                 it = prev;
         }
DPRINTF(HWPrefetch, "Prefetch queue full, removing lowest priority " - "oldest packet, addr: %#x", it->pkt->getAddr());
+                           "oldest packet, paddr:%#x (vaddr:%#x)",
+ it->address->getPaddr(), it->address->getVaddr());
         delete it->pkt;
+        delete it->address;
         pfq.erase(it);
     }

-    Tick pf_time = curTick() + clockPeriod() * latency;
+
     DPRINTF(HWPrefetch, "Prefetch queued. "
-            "addr:%#x priority: %3d tick:%lld.\n",
-            pf_info.first, pf_info.second, pf_time);
+            "addr:%#x (vaddr:%#x) priority: %3d tick:%lld.\n",
+            new_pfa.getPaddr(), new_pfa.getVaddr(), priority, pf_time);

     /* Create the packet and find the spot to insert it */
-    DeferredPacket dpp(pf_time, pf_pkt, pf_info.second);
     if (pfq.size() == 0) {
         pfq.emplace_back(dpp);
     } else {
@@ -274,6 +267,5 @@
             it++;
         pfq.insert(it, dpp);
     }
-
-    return pf_pkt;
+    return true;
 }
diff --git a/src/mem/cache/prefetch/queued.hh b/src/mem/cache/prefetch/queued.hh
index 774e6ed..d855219 100644
--- a/src/mem/cache/prefetch/queued.hh
+++ b/src/mem/cache/prefetch/queued.hh
@@ -55,11 +55,20 @@
 {
   protected:
     struct DeferredPacket {
+        PrefetcherAddressBase *address;
         Tick tick;
         PacketPtr pkt;
         int32_t priority;
-        DeferredPacket(Tick t, PacketPtr p, int32_t pr) : tick(t), pkt(p),
-                                                        priority(pr)  {}
+        DeferredPacket(PrefetcherAddressBase *pfa, Tick t, int32_t pr,
+                       unsigned blks, MasterID mid, bool tagPrefetch)
+                     : address(pfa), tick(t), pkt(nullptr), priority(pr) {
+            if (address->validPaddr()) {
+                createPkt(blks, mid, tagPrefetch);
+            }
+        }
+
+        PrefetcherAddressBase const &getAddr() const { return *address; }
+        ~DeferredPacket() {}
         bool operator>(const DeferredPacket& that) const
         {
             return priority > that.priority;
@@ -72,6 +81,21 @@
         {
             return !(*this > that);
         }
+        void createPkt(unsigned blks, MasterID mid, bool tagPrefetch) {
+            RequestPtr req =
+ std::make_shared<Request>(address->getPaddr(), blks, 0, mid);
+
+            if (address->isSecure()) {
+                req->setFlags(Request::SECURE);
+            }
+            req->taskId(ContextSwitchTaskId::Prefetcher);
+            pkt = new Packet(req, MemCmd::HardPFReq);
+            pkt->allocate();
+            if (tagPrefetch && address->hasPC()) {
+                // Tag prefetch packet with  accessing pc
+                pkt->req->setPC(address->getPC());
+            }
+        }
     };
     using AddrPriority = std::pair<Addr, int32_t>;

@@ -98,9 +122,9 @@
     const bool tagPrefetch;

     using const_iterator = std::list<DeferredPacket>::const_iterator;
-    const_iterator inPrefetch(Addr address, bool is_secure) const;
+    const_iterator inPrefetch(const PrefetcherAddressBase &pfa) const;
     using iterator = std::list<DeferredPacket>::iterator;
-    iterator inPrefetch(Addr address, bool is_secure);
+    iterator inPrefetch(const PrefetcherAddressBase &pfa);

     // STATS
     Stats::Scalar pfIdentified;
@@ -113,11 +137,12 @@
     QueuedPrefetcher(const QueuedPrefetcherParams *p);
     virtual ~QueuedPrefetcher();

-    void notify(const PacketPtr &pkt) override;
+    void notify(const PrefetcherAddressBase &pfa) override;

-    PacketPtr insert(AddrPriority& info, bool is_secure);
+    bool insert(PrefetcherAddressBase &new_pfa, int32_t priority);

-    virtual void calculatePrefetch(const PacketPtr &pkt,
+ // Note: This should really be pure virtual, but doesnt go well with params
+    virtual void calculatePrefetch(const PrefetcherAddress &pkt,
std::vector<AddrPriority> &addresses) = 0;
     PacketPtr getPacket() override;

diff --git a/src/mem/cache/prefetch/stride.cc b/src/mem/cache/prefetch/stride.cc
index 44849cd..257183a 100644
--- a/src/mem/cache/prefetch/stride.cc
+++ b/src/mem/cache/prefetch/stride.cc
@@ -138,19 +138,19 @@
 }

 void
-StridePrefetcher::calculatePrefetch(const PacketPtr &pkt,
+StridePrefetcher::calculatePrefetch(const PrefetcherAddress &pfa,
                                     std::vector<AddrPriority> &addresses)
 {
-    if (!pkt->req->hasPC()) {
+    if (!pfa.hasPC()) {
         DPRINTF(HWPrefetch, "Ignoring request with no PC.\n");
         return;
     }

     // Get required packet info
-    Addr pkt_addr = pkt->getAddr();
-    Addr pc = pkt->req->getPC();
-    bool is_secure = pkt->isSecure();
-    MasterID master_id = useMasterId ? pkt->req->masterId() : 0;
+    Addr pfa_addr = pfa.getAddr();
+    Addr pc = pfa.getPC();
+    bool is_secure = pfa.isSecure();
+    MasterID master_id = useMasterId ? pfa.getMasterId() : 0;

     // Get corresponding pc table
     PCTable* pcTable = findTable(master_id);
@@ -160,7 +160,7 @@

     if (entry != nullptr) {
         // Hit in table
-        int new_stride = pkt_addr - entry->lastAddr;
+        int new_stride = pfa_addr - entry->lastAddr;
         bool stride_match = (new_stride == entry->stride);

         // Adjust confidence for stride entry
@@ -175,12 +175,12 @@
                 entry->stride = new_stride;
         }

-        DPRINTF(HWPrefetch, "Hit: PC %x pkt_addr %x (%s) stride %d (%s), "
- "conf %d\n", pc, pkt_addr, is_secure ? "s" : "ns", new_stride,
-                stride_match ? "match" : "change",
+        DPRINTF(HWPrefetch, "Hit: PC %x addr:%#x (%s) stride %d (%s), "
+                "conf %d\n", pc, pfa.getAddr(), is_secure ? "s" : "ns",
+                new_stride, stride_match ? "match" : "change",
                 entry->confidence);

-        entry->lastAddr = pkt_addr;
+        entry->lastAddr = pfa_addr;

         // Abort prefetch generation if below confidence threshold
         if (entry->confidence < threshConf)
@@ -194,8 +194,8 @@
                 prefetch_stride = (new_stride < 0) ? -blkSize : blkSize;
             }

-            Addr new_addr = pkt_addr + d * prefetch_stride;
-            if (samePage(pkt_addr, new_addr)) {
+            Addr new_addr = pfa_addr + d * prefetch_stride;
+            if (samePage(pfa_addr, new_addr)) {
DPRINTF(HWPrefetch, "Queuing prefetch to %#x.\n", new_addr);
                 addresses.push_back(AddrPriority(new_addr, 0));
             } else {
@@ -207,7 +207,7 @@
         }
     } else {
         // Miss in table
-        DPRINTF(HWPrefetch, "Miss: PC %x pkt_addr %x (%s)\n", pc, pkt_addr,
+ DPRINTF(HWPrefetch, "Miss: PC %x addr:%#x (%s)\n", pc, pfa.getAddr(),
                 is_secure ? "s" : "ns");

         StrideEntry* entry = pcTable->findVictim(pc);
@@ -218,7 +218,7 @@

         // Insert new entry's data
         entry->instAddr = pc;
-        entry->lastAddr = pkt_addr;
+        entry->lastAddr = pfa_addr;
         entry->isSecure = is_secure;
         entry->confidence = startConf;
         replacementPolicy->reset(entry->replacementData);
diff --git a/src/mem/cache/prefetch/stride.hh b/src/mem/cache/prefetch/stride.hh
index aa02287..3a3ef75 100644
--- a/src/mem/cache/prefetch/stride.hh
+++ b/src/mem/cache/prefetch/stride.hh
@@ -172,7 +172,7 @@
   public:
     StridePrefetcher(const StridePrefetcherParams *p);

-    void calculatePrefetch(const PacketPtr &pkt,
+    void calculatePrefetch(const PrefetcherAddress &pkt,
                            std::vector<AddrPriority> &addresses) override;
 };

diff --git a/src/mem/cache/prefetch/tagged.cc b/src/mem/cache/prefetch/tagged.cc
index 7561633..cffa6b7 100644
--- a/src/mem/cache/prefetch/tagged.cc
+++ b/src/mem/cache/prefetch/tagged.cc
@@ -44,10 +44,10 @@
 }

 void
-TaggedPrefetcher::calculatePrefetch(const PacketPtr &pkt,
+TaggedPrefetcher::calculatePrefetch(const PrefetcherAddress &pkt,
         std::vector<AddrPriority> &addresses)
 {
-    Addr blkAddr = pkt->getBlockAddr(blkSize);
+    Addr blkAddr = pkt.getAddr();

     for (int d = 1; d <= degree; d++) {
         Addr newAddr = blkAddr + d*(blkSize);
diff --git a/src/mem/cache/prefetch/tagged.hh b/src/mem/cache/prefetch/tagged.hh
index 8dd8b77..80f4ee6 100644
--- a/src/mem/cache/prefetch/tagged.hh
+++ b/src/mem/cache/prefetch/tagged.hh
@@ -51,7 +51,7 @@

     ~TaggedPrefetcher() {}

-    void calculatePrefetch(const PacketPtr &pkt,
+    void calculatePrefetch(const PrefetcherAddress &pkt,
                            std::vector<AddrPriority> &addresses) override;
 };


--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/14416
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I4f8c3687988afecc8a91c3c5b2d44cc0580f72aa
Gerrit-Change-Number: 14416
Gerrit-PatchSet: 1
Gerrit-Owner: Javier Bueno Hedo <[email protected]>
Gerrit-Reviewer: Andreas Sandberg <[email protected]>
Gerrit-Reviewer: Giacomo Travaglini <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to