cpu: Fix the usage of const DynInstPtr

Summary: Usage of const DynInstPtr& when possible and introduction of
move operators to RefCountingPtr.

In many places, scoped references to dynamic instructions do a copy of
the DynInstPtr when a reference would do. This is detrimental to
performance. On top of that, in case there is a need for reference
tracking for debugging, the redundant copies make the process much more
painful than it already is.

Also, from the theoretical point of view, a function/method that
defines a convenience name to access an instruction should not be
considered an owner of the data, i.e., doing a copy and not a reference
is not justified.

On a related topic, C++11 introduces move semantics, and those are
useful when, for example, there is a class modelling a HW structure that
contains a list, and has a getHeadOfList function, to prevent doing a
copy to an internal variable -> update pointer, remove from the list ->
update pointer, return value making a copy to the assined variable ->
update pointer, destroy the returned value -> update pointer.

Change-Id: I3bb46c20ef23b6873b469fd22befb251ac44d2f6
Signed-off-by: Giacomo Gabrielli <giacomo.gabrielli@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/13105
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>
diff --git a/src/base/refcnt.hh b/src/base/refcnt.hh
index baf08c6..f282123 100644
--- a/src/base/refcnt.hh
+++ b/src/base/refcnt.hh
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2017 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2002-2005 The Regents of The University of Michigan
  * All rights reserved.
  *
@@ -31,6 +43,8 @@
 #ifndef __BASE_REFCNT_HH__
 #define __BASE_REFCNT_HH__
 
+#include <type_traits>
+
 /**
  * @file base/refcnt.hh
  *
@@ -80,11 +94,11 @@
     virtual ~RefCounted() {}
 
     /// Increment the reference count
-    void incref() { ++count; }
+    void incref() const { ++count; }
 
     /// Decrement the reference count and destroy the object if all
     /// references are gone.
-    void decref() { if (--count <= 0) delete this; }
+    void decref() const { if (--count <= 0) delete this; }
 };
 
 /**
@@ -106,6 +120,18 @@
 class RefCountingPtr
 {
   protected:
+    /** Convenience aliases for const/non-const versions of T w/ friendship. */
+    /** @{ */
+    static constexpr auto TisConst = std::is_const<T>::value;
+    using ConstT = typename std::conditional<TisConst,
+            RefCountingPtr<T>,
+            RefCountingPtr<typename std::add_const<T>::type>>::type;
+    friend ConstT;
+    using NonConstT = typename std::conditional<TisConst,
+            RefCountingPtr<typename std::remove_const<T>::type>,
+            RefCountingPtr<T>>::type;
+    friend NonConstT;
+    /** @} */
     /// The stored pointer.
     /// Arguably this should be private.
     T *data;
@@ -163,6 +189,18 @@
     /// one.  Adds a reference.
     RefCountingPtr(const RefCountingPtr &r) { copy(r.data); }
 
+    /** Move-constructor.
+     * Does not add a reference.
+     */
+    RefCountingPtr(RefCountingPtr&& r)
+    {
+        data = r.data;
+        r.data = nullptr;
+    }
+
+    template <bool B = TisConst>
+    RefCountingPtr(const NonConstT &r) { copy(r.data); }
+
     /// Destroy the pointer and any reference it may hold.
     ~RefCountingPtr() { del(); }
 
@@ -179,6 +217,12 @@
     /// Directly access the pointer itself without taking a reference.
     T *get() const { return data; }
 
+    template <bool B = TisConst>
+    operator RefCountingPtr<typename std::enable_if<!B, ConstT>::type>()
+    {
+        return RefCountingPtr<const T>(*this);
+    }
+
     /// Assign a new value to the pointer
     const RefCountingPtr &operator=(T *p) { set(p); return *this; }
 
@@ -186,6 +230,18 @@
     const RefCountingPtr &operator=(const RefCountingPtr &r)
     { return operator=(r.data); }
 
+    /// Move-assign the pointer from another RefCountingPtr
+    const RefCountingPtr &operator=(RefCountingPtr&& r)
+    {
+        /* This happens regardless of whether the pointer is the same or not,
+         * because of the move semantics, the rvalue needs to be 'destroyed'.
+         */
+        del();
+        data = r.data;
+        r.data = nullptr;
+        return *this;
+    }
+
     /// Check if the pointer is empty
     bool operator!() const { return data == 0; }
 
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh
index 93cafd6..b4431da 100644
--- a/src/cpu/base_dyn_inst.hh
+++ b/src/cpu/base_dyn_inst.hh
@@ -827,7 +827,7 @@
     /**Read the micro PC of this instruction. */
     Addr microPC() const { return pc.microPC(); }
 
-    bool readPredicate()
+    bool readPredicate() const
     {
         return instFlags[Predicate];
     }
@@ -855,13 +855,13 @@
 
   public:
     /** Returns whether or not the eff. addr. source registers are ready. */
-    bool eaSrcsReady();
+    bool eaSrcsReady() const;
 
     /** Is this instruction's memory access strictly ordered? */
     bool strictlyOrdered() const { return instFlags[IsStrictlyOrdered]; }
 
     /** Has this instruction generated a memory request. */
-    bool hasRequest() { return instFlags[ReqMade]; }
+    bool hasRequest() const { return instFlags[ReqMade]; }
 
     /** Returns iterator to this instruction in the list of all insts. */
     ListIt &getInstListIt() { return instListIt; }
diff --git a/src/cpu/base_dyn_inst_impl.hh b/src/cpu/base_dyn_inst_impl.hh
index b499fe4..f638f75 100644
--- a/src/cpu/base_dyn_inst_impl.hh
+++ b/src/cpu/base_dyn_inst_impl.hh
@@ -217,7 +217,7 @@
 
 template <class Impl>
 bool
-BaseDynInst<Impl>::eaSrcsReady()
+BaseDynInst<Impl>::eaSrcsReady() const
 {
     // For now I am assuming that src registers 1..n-1 are the ones that the
     // EA calc depends on.  (i.e. src reg 0 is the source of the data to be
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh
index bee7225..cb87f62 100644
--- a/src/cpu/checker/cpu.hh
+++ b/src/cpu/checker/cpu.hh
@@ -397,7 +397,8 @@
         setVecElemResult(val);
     }
 
-    bool readPredicate() override { return thread->readPredicate(); }
+    bool readPredicate() const override { return thread->readPredicate(); }
+
     void setPredicate(bool val) override
     {
         thread->setPredicate(val);
@@ -572,18 +573,18 @@
 
     void advancePC(const Fault &fault);
 
-    void verify(DynInstPtr &inst);
+    void verify(const DynInstPtr &inst);
 
-    void validateInst(DynInstPtr &inst);
-    void validateExecution(DynInstPtr &inst);
+    void validateInst(const DynInstPtr &inst);
+    void validateExecution(const DynInstPtr &inst);
     void validateState();
 
-    void copyResult(DynInstPtr &inst, const InstResult& mismatch_val,
+    void copyResult(const DynInstPtr &inst, const InstResult& mismatch_val,
                     int start_idx);
     void handlePendingInt();
 
   private:
-    void handleError(DynInstPtr &inst)
+    void handleError(const DynInstPtr &inst)
     {
         if (exitOnError) {
             dumpAndExit(inst);
@@ -592,7 +593,7 @@
         }
     }
 
-    void dumpAndExit(DynInstPtr &inst);
+    void dumpAndExit(const DynInstPtr &inst);
 
     bool updateThisCycle;
 
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh
index 57282cd..4fa5956 100644
--- a/src/cpu/checker/cpu_impl.hh
+++ b/src/cpu/checker/cpu_impl.hh
@@ -124,7 +124,7 @@
 
 template <class Impl>
 void
-Checker<Impl>::verify(DynInstPtr &completed_inst)
+Checker<Impl>::verify(const DynInstPtr &completed_inst)
 {
     DynInstPtr inst;
 
@@ -456,7 +456,7 @@
 
 template <class Impl>
 void
-Checker<Impl>::validateInst(DynInstPtr &inst)
+Checker<Impl>::validateInst(const DynInstPtr &inst)
 {
     if (inst->instAddr() != thread->instAddr()) {
         warn("%lli: PCs do not match! Inst: %s, checker: %s",
@@ -477,7 +477,7 @@
 
 template <class Impl>
 void
-Checker<Impl>::validateExecution(DynInstPtr &inst)
+Checker<Impl>::validateExecution(const DynInstPtr &inst)
 {
     InstResult checker_val;
     InstResult inst_val;
@@ -595,8 +595,8 @@
 
 template <class Impl>
 void
-Checker<Impl>::copyResult(DynInstPtr &inst, const InstResult& mismatch_val,
-                          int start_idx)
+Checker<Impl>::copyResult(const DynInstPtr &inst,
+                          const InstResult& mismatch_val, int start_idx)
 {
     // We've already popped one dest off the queue,
     // so do the fix-up then start with the next dest reg;
@@ -672,7 +672,7 @@
 
 template <class Impl>
 void
-Checker<Impl>::dumpAndExit(DynInstPtr &inst)
+Checker<Impl>::dumpAndExit(const DynInstPtr &inst)
 {
     cprintf("Error detected, instruction information:\n");
     cprintf("PC:%s, nextPC:%#x\n[sn:%lli]\n[tid:%i]\n"
diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh
index 59d7414..bc9b486 100644
--- a/src/cpu/exec_context.hh
+++ b/src/cpu/exec_context.hh
@@ -306,7 +306,7 @@
      * @name ARM-Specific Interfaces
      */
 
-    virtual bool readPredicate() = 0;
+    virtual bool readPredicate() const = 0;
     virtual void setPredicate(bool val) = 0;
 
     /** @} */
diff --git a/src/cpu/minor/exec_context.hh b/src/cpu/minor/exec_context.hh
index 6ac0df5..238d113 100644
--- a/src/cpu/minor/exec_context.hh
+++ b/src/cpu/minor/exec_context.hh
@@ -292,7 +292,7 @@
     }
 
     bool
-    readPredicate() override
+    readPredicate() const override
     {
         return thread.readPredicate();
     }
diff --git a/src/cpu/o3/commit.hh b/src/cpu/o3/commit.hh
index f508a37..b74917d 100644
--- a/src/cpu/o3/commit.hh
+++ b/src/cpu/o3/commit.hh
@@ -282,7 +282,7 @@
      * @param tid ID of the thread to squash.
      * @param head_inst Instruction that requested the squash.
      */
-    void squashAfter(ThreadID tid, DynInstPtr &head_inst);
+    void squashAfter(ThreadID tid, const DynInstPtr &head_inst);
 
     /** Handles processing an interrupt. */
     void handleInterrupt();
@@ -296,7 +296,7 @@
     /** Tries to commit the head ROB instruction passed in.
      * @param head_inst The instruction to be committed.
      */
-    bool commitHead(DynInstPtr &head_inst, unsigned inst_num);
+    bool commitHead(const DynInstPtr &head_inst, unsigned inst_num);
 
     /** Gets instructions from rename and inserts them into the ROB. */
     void getInsts();
@@ -477,7 +477,7 @@
     bool avoidQuiesceLiveLock;
 
     /** Updates commit stats based on this instruction. */
-    void updateComInstStats(DynInstPtr &inst);
+    void updateComInstStats(const DynInstPtr &inst);
 
     /** Stat for the total number of squashed instructions discarded by commit.
      */
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index d32493c..8fd142c 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -636,7 +636,7 @@
 
 template <class Impl>
 void
-DefaultCommit<Impl>::squashAfter(ThreadID tid, DynInstPtr &head_inst)
+DefaultCommit<Impl>::squashAfter(ThreadID tid, const DynInstPtr &head_inst)
 {
     DPRINTF(Commit, "Executing squash after for [tid:%i] inst [sn:%lli]\n",
             tid, head_inst->seqNum);
@@ -696,14 +696,14 @@
             // will be active.
             _nextStatus = Active;
 
-            DynInstPtr inst = rob->readHeadInst(tid);
+            const DynInstPtr &inst M5_VAR_USED = rob->readHeadInst(tid);
 
             DPRINTF(Commit,"[tid:%i]: Instruction [sn:%lli] PC %s is head of"
                     " ROB and ready to commit\n",
                     tid, inst->seqNum, inst->pcState());
 
         } else if (!rob->isEmpty(tid)) {
-            DynInstPtr inst = rob->readHeadInst(tid);
+            const DynInstPtr &inst = rob->readHeadInst(tid);
 
             ppCommitStall->notify(inst);
 
@@ -1136,7 +1136,7 @@
 
 template <class Impl>
 bool
-DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
+DefaultCommit<Impl>::commitHead(const DynInstPtr &head_inst, unsigned inst_num)
 {
     assert(head_inst);
 
@@ -1317,9 +1317,7 @@
     int insts_to_process = std::min((int)renameWidth, fromRename->size);
 
     for (int inst_num = 0; inst_num < insts_to_process; ++inst_num) {
-        DynInstPtr inst;
-
-        inst = fromRename->insts[inst_num];
+        const DynInstPtr &inst = fromRename->insts[inst_num];
         ThreadID tid = inst->threadNumber;
 
         if (!inst->isSquashed() &&
@@ -1366,7 +1364,7 @@
 
 template <class Impl>
 void
-DefaultCommit<Impl>::updateComInstStats(DynInstPtr &inst)
+DefaultCommit<Impl>::updateComInstStats(const DynInstPtr &inst)
 {
     ThreadID tid = inst->threadNumber;
 
@@ -1507,7 +1505,7 @@
 
             if (rob->isHeadReady(tid)) {
 
-                DynInstPtr head_inst = rob->readHeadInst(tid);
+                const DynInstPtr &head_inst = rob->readHeadInst(tid);
 
                 if (first) {
                     oldest = tid;
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index c4bc13f..2f79345 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -1564,7 +1564,7 @@
 
 template <class Impl>
 typename FullO3CPU<Impl>::ListIt
-FullO3CPU<Impl>::addInst(DynInstPtr &inst)
+FullO3CPU<Impl>::addInst(const DynInstPtr &inst)
 {
     instList.push_back(inst);
 
@@ -1573,7 +1573,7 @@
 
 template <class Impl>
 void
-FullO3CPU<Impl>::instDone(ThreadID tid, DynInstPtr &inst)
+FullO3CPU<Impl>::instDone(ThreadID tid, const DynInstPtr &inst)
 {
     // Keep an instruction count.
     if (!inst->isMicroop() || inst->isLastMicroop()) {
@@ -1595,7 +1595,7 @@
 
 template <class Impl>
 void
-FullO3CPU<Impl>::removeFrontInst(DynInstPtr &inst)
+FullO3CPU<Impl>::removeFrontInst(const DynInstPtr &inst)
 {
     DPRINTF(O3CPU, "Removing committed instruction [tid:%i] PC %s "
             "[sn:%lli]\n",
@@ -1751,7 +1751,7 @@
 /*
 template <class Impl>
 void
-FullO3CPU<Impl>::wakeDependents(DynInstPtr &inst)
+FullO3CPU<Impl>::wakeDependents(const DynInstPtr &inst)
 {
     iew.wakeDependents(inst);
 }
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index 1589220..19b9a34 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -537,15 +537,15 @@
     /** Function to add instruction onto the head of the list of the
      *  instructions.  Used when new instructions are fetched.
      */
-    ListIt addInst(DynInstPtr &inst);
+    ListIt addInst(const DynInstPtr &inst);
 
     /** Function to tell the CPU that an instruction has completed. */
-    void instDone(ThreadID tid, DynInstPtr &inst);
+    void instDone(ThreadID tid, const DynInstPtr &inst);
 
     /** Remove an instruction from the front end of the list.  There's
      *  no restriction on location of the instruction.
      */
-    void removeFrontInst(DynInstPtr &inst);
+    void removeFrontInst(const DynInstPtr &inst);
 
     /** Remove all instructions that are not currently in the ROB.
      *  There's also an option to not squash delay slot instructions.*/
diff --git a/src/cpu/o3/decode.hh b/src/cpu/o3/decode.hh
index 006219a..a1e29a6 100644
--- a/src/cpu/o3/decode.hh
+++ b/src/cpu/o3/decode.hh
@@ -194,7 +194,7 @@
     /** Squashes if there is a PC-relative branch that was predicted
      * incorrectly. Sends squash information back to fetch.
      */
-    void squash(DynInstPtr &inst, ThreadID tid);
+    void squash(const DynInstPtr &inst, ThreadID tid);
 
   public:
     /** Squashes due to commit signalling a squash. Changes status to
diff --git a/src/cpu/o3/decode_impl.hh b/src/cpu/o3/decode_impl.hh
index 15ec76f..51c1b9d 100644
--- a/src/cpu/o3/decode_impl.hh
+++ b/src/cpu/o3/decode_impl.hh
@@ -288,7 +288,7 @@
 
 template<class Impl>
 void
-DefaultDecode<Impl>::squash(DynInstPtr &inst, ThreadID tid)
+DefaultDecode<Impl>::squash(const DynInstPtr &inst, ThreadID tid)
 {
     DPRINTF(Decode, "[tid:%i]: [sn:%i] Squashing due to incorrect branch "
             "prediction detected at decode.\n", tid, inst->seqNum);
@@ -650,8 +650,6 @@
         ++decodeRunCycles;
     }
 
-    DynInstPtr inst;
-
     std::queue<DynInstPtr>
         &insts_to_decode = decodeStatus[tid] == Unblocking ?
         skidBuffer[tid] : insts[tid];
@@ -661,7 +659,7 @@
     while (insts_available > 0 && toRenameIndex < decodeWidth) {
         assert(!insts_to_decode.empty());
 
-        inst = insts_to_decode.front();
+        DynInstPtr inst = std::move(insts_to_decode.front());
 
         insts_to_decode.pop();
 
diff --git a/src/cpu/o3/dep_graph.hh b/src/cpu/o3/dep_graph.hh
index 41ab6e9..212130e 100644
--- a/src/cpu/o3/dep_graph.hh
+++ b/src/cpu/o3/dep_graph.hh
@@ -89,10 +89,10 @@
     void reset();
 
     /** Inserts an instruction to be dependent on the given index. */
-    void insert(PhysRegIndex idx, DynInstPtr &new_inst);
+    void insert(PhysRegIndex idx, const DynInstPtr &new_inst);
 
     /** Sets the producing instruction of a given register. */
-    void setInst(PhysRegIndex idx, DynInstPtr &new_inst)
+    void setInst(PhysRegIndex idx, const DynInstPtr &new_inst)
     { dependGraph[idx].inst = new_inst; }
 
     /** Clears the producing instruction. */
@@ -100,7 +100,7 @@
     { dependGraph[idx].inst = NULL; }
 
     /** Removes an instruction from a single linked list. */
-    void remove(PhysRegIndex idx, DynInstPtr &inst_to_remove);
+    void remove(PhysRegIndex idx, const DynInstPtr &inst_to_remove);
 
     /** Removes and returns the newest dependent of a specific register. */
     DynInstPtr pop(PhysRegIndex idx);
@@ -182,7 +182,8 @@
 
 template <class DynInstPtr>
 void
-DependencyGraph<DynInstPtr>::insert(PhysRegIndex idx, DynInstPtr &new_inst)
+DependencyGraph<DynInstPtr>::insert(PhysRegIndex idx,
+        const DynInstPtr &new_inst)
 {
     //Add this new, dependent instruction at the head of the dependency
     //chain.
@@ -203,7 +204,7 @@
 template <class DynInstPtr>
 void
 DependencyGraph<DynInstPtr>::remove(PhysRegIndex idx,
-                                    DynInstPtr &inst_to_remove)
+                                    const DynInstPtr &inst_to_remove)
 {
     DepEntry *prev = &dependGraph[idx];
     DepEntry *curr = dependGraph[idx].next;
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index da7ba4b..28739d2 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -281,7 +281,7 @@
      * @param next_NPC Used for ISAs which use delay slots.
      * @return Whether or not a branch was predicted as taken.
      */
-    bool lookupAndUpdateNextPC(DynInstPtr &inst, TheISA::PCState &pc);
+    bool lookupAndUpdateNextPC(const DynInstPtr &inst, TheISA::PCState &pc);
 
     /**
      * Fetches the cache line that contains the fetch PC.  Returns any
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 2df7b84..5810c03 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -546,7 +546,7 @@
 template <class Impl>
 bool
 DefaultFetch<Impl>::lookupAndUpdateNextPC(
-        DynInstPtr &inst, TheISA::PCState &nextPC)
+        const DynInstPtr &inst, TheISA::PCState &nextPC)
 {
     // Do branch prediction check here.
     // A bit of a misnomer...next_PC is actually the current PC until
@@ -953,7 +953,7 @@
     while (available_insts != 0 && insts_to_decode < decodeWidth) {
         ThreadID tid = *tid_itr;
         if (!stalls[tid].decode && !fetchQueue[tid].empty()) {
-            auto inst = fetchQueue[tid].front();
+            const auto& inst = fetchQueue[tid].front();
             toDecode->insts[toDecode->size++] = inst;
             DPRINTF(Fetch, "[tid:%i][sn:%i]: Sending instruction to decode from "
                     "fetch queue. Fetch queue size: %i.\n",
diff --git a/src/cpu/o3/iew.hh b/src/cpu/o3/iew.hh
index de88340..b15521f 100644
--- a/src/cpu/o3/iew.hh
+++ b/src/cpu/o3/iew.hh
@@ -175,24 +175,24 @@
     void squash(ThreadID tid);
 
     /** Wakes all dependents of a completed instruction. */
-    void wakeDependents(DynInstPtr &inst);
+    void wakeDependents(const DynInstPtr &inst);
 
     /** Tells memory dependence unit that a memory instruction needs to be
      * rescheduled. It will re-execute once replayMemInst() is called.
      */
-    void rescheduleMemInst(DynInstPtr &inst);
+    void rescheduleMemInst(const DynInstPtr &inst);
 
     /** Re-executes all rescheduled memory instructions. */
-    void replayMemInst(DynInstPtr &inst);
+    void replayMemInst(const DynInstPtr &inst);
 
     /** Moves memory instruction onto the list of cache blocked instructions */
-    void blockMemInst(DynInstPtr &inst);
+    void blockMemInst(const DynInstPtr &inst);
 
     /** Notifies that the cache has become unblocked */
     void cacheUnblocked();
 
     /** Sends an instruction to commit through the time buffer. */
-    void instToCommit(DynInstPtr &inst);
+    void instToCommit(const DynInstPtr &inst);
 
     /** Inserts unused instructions of a thread into the skid buffer. */
     void skidInsert(ThreadID tid);
@@ -230,18 +230,18 @@
     bool hasStoresToWB(ThreadID tid) { return ldstQueue.hasStoresToWB(tid); }
 
     /** Check misprediction  */
-    void checkMisprediction(DynInstPtr &inst);
+    void checkMisprediction(const DynInstPtr &inst);
 
   private:
     /** Sends commit proper information for a squash due to a branch
      * mispredict.
      */
-    void squashDueToBranch(DynInstPtr &inst, ThreadID tid);
+    void squashDueToBranch(const DynInstPtr &inst, ThreadID tid);
 
     /** Sends commit proper information for a squash due to a memory order
      * violation.
      */
-    void squashDueToMemOrder(DynInstPtr &inst, ThreadID tid);
+    void squashDueToMemOrder(const DynInstPtr &inst, ThreadID tid);
 
     /** Sets Dispatch to blocked, and signals back to other stages to block. */
     void block(ThreadID tid);
@@ -295,7 +295,7 @@
 
   private:
     /** Updates execution stats based on the instruction. */
-    void updateExeInstStats(DynInstPtr &inst);
+    void updateExeInstStats(const DynInstPtr &inst);
 
     /** Pointer to main time buffer used for backwards communication. */
     TimeBuffer<TimeStruct> *timeBuffer;
diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh
index 8270a71..e46bc5b 100644
--- a/src/cpu/o3/iew_impl.hh
+++ b/src/cpu/o3/iew_impl.hh
@@ -478,7 +478,7 @@
 
 template<class Impl>
 void
-DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, ThreadID tid)
+DefaultIEW<Impl>::squashDueToBranch(const DynInstPtr& inst, ThreadID tid)
 {
     DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %s "
             "[sn:%i].\n", tid, inst->pcState(), inst->seqNum);
@@ -503,7 +503,7 @@
 
 template<class Impl>
 void
-DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, ThreadID tid)
+DefaultIEW<Impl>::squashDueToMemOrder(const DynInstPtr& inst, ThreadID tid)
 {
     DPRINTF(IEW, "[tid:%i]: Memory violation, squashing violator and younger "
             "insts, PC: %s [sn:%i].\n", tid, inst->pcState(), inst->seqNum);
@@ -566,28 +566,28 @@
 
 template<class Impl>
 void
-DefaultIEW<Impl>::wakeDependents(DynInstPtr &inst)
+DefaultIEW<Impl>::wakeDependents(const DynInstPtr& inst)
 {
     instQueue.wakeDependents(inst);
 }
 
 template<class Impl>
 void
-DefaultIEW<Impl>::rescheduleMemInst(DynInstPtr &inst)
+DefaultIEW<Impl>::rescheduleMemInst(const DynInstPtr& inst)
 {
     instQueue.rescheduleMemInst(inst);
 }
 
 template<class Impl>
 void
-DefaultIEW<Impl>::replayMemInst(DynInstPtr &inst)
+DefaultIEW<Impl>::replayMemInst(const DynInstPtr& inst)
 {
     instQueue.replayMemInst(inst);
 }
 
 template<class Impl>
 void
-DefaultIEW<Impl>::blockMemInst(DynInstPtr& inst)
+DefaultIEW<Impl>::blockMemInst(const DynInstPtr& inst)
 {
     instQueue.blockMemInst(inst);
 }
@@ -601,7 +601,7 @@
 
 template<class Impl>
 void
-DefaultIEW<Impl>::instToCommit(DynInstPtr &inst)
+DefaultIEW<Impl>::instToCommit(const DynInstPtr& inst)
 {
     // This function should not be called after writebackInsts in a
     // single cycle.  That will cause problems with an instruction
@@ -1578,7 +1578,7 @@
 
 template <class Impl>
 void
-DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst)
+DefaultIEW<Impl>::updateExeInstStats(const DynInstPtr& inst)
 {
     ThreadID tid = inst->threadNumber;
 
@@ -1610,7 +1610,7 @@
 
 template <class Impl>
 void
-DefaultIEW<Impl>::checkMisprediction(DynInstPtr &inst)
+DefaultIEW<Impl>::checkMisprediction(const DynInstPtr& inst)
 {
     ThreadID tid = inst->threadNumber;
 
diff --git a/src/cpu/o3/impl.hh b/src/cpu/o3/impl.hh
index 8905bdb..a0007e5 100644
--- a/src/cpu/o3/impl.hh
+++ b/src/cpu/o3/impl.hh
@@ -65,6 +65,7 @@
      *  what should be used, and not DynInst *.
      */
     typedef RefCountingPtr<DynInst> DynInstPtr;
+    typedef RefCountingPtr<const DynInst> DynInstConstPtr;
 
     /** The O3CPU type to be used. */
     typedef FullO3CPU<O3CPUImpl> O3CPU;
diff --git a/src/cpu/o3/inst_queue.hh b/src/cpu/o3/inst_queue.hh
index 64f8aa1..37cc3a2 100644
--- a/src/cpu/o3/inst_queue.hh
+++ b/src/cpu/o3/inst_queue.hh
@@ -113,7 +113,7 @@
 
       public:
         /** Construct a FU completion event. */
-        FUCompletion(DynInstPtr &_inst, int fu_idx,
+        FUCompletion(const DynInstPtr &_inst, int fu_idx,
                      InstructionQueue<Impl> *iq_ptr);
 
         virtual void process();
@@ -176,15 +176,15 @@
     bool hasReadyInsts();
 
     /** Inserts a new instruction into the IQ. */
-    void insert(DynInstPtr &new_inst);
+    void insert(const DynInstPtr &new_inst);
 
     /** Inserts a new, non-speculative instruction into the IQ. */
-    void insertNonSpec(DynInstPtr &new_inst);
+    void insertNonSpec(const DynInstPtr &new_inst);
 
     /** Inserts a memory or write barrier into the IQ to make sure
      *  loads and stores are ordered properly.
      */
-    void insertBarrier(DynInstPtr &barr_inst);
+    void insertBarrier(const DynInstPtr &barr_inst);
 
     /** Returns the oldest scheduled instruction, and removes it from
      * the list of instructions waiting to execute.
@@ -205,11 +205,11 @@
      * Records the instruction as the producer of a register without
      * adding it to the rest of the IQ.
      */
-    void recordProducer(DynInstPtr &inst)
+    void recordProducer(const DynInstPtr &inst)
     { addToProducers(inst); }
 
     /** Process FU completion event. */
-    void processFUCompletion(DynInstPtr &inst, int fu_idx);
+    void processFUCompletion(const DynInstPtr &inst, int fu_idx);
 
     /**
      * Schedules ready instructions, adding the ready ones (oldest first) to
@@ -227,37 +227,37 @@
     void commit(const InstSeqNum &inst, ThreadID tid = 0);
 
     /** Wakes all dependents of a completed instruction. */
-    int wakeDependents(DynInstPtr &completed_inst);
+    int wakeDependents(const DynInstPtr &completed_inst);
 
     /** Adds a ready memory instruction to the ready list. */
-    void addReadyMemInst(DynInstPtr &ready_inst);
+    void addReadyMemInst(const DynInstPtr &ready_inst);
 
     /**
      * Reschedules a memory instruction. It will be ready to issue once
      * replayMemInst() is called.
      */
-    void rescheduleMemInst(DynInstPtr &resched_inst);
+    void rescheduleMemInst(const DynInstPtr &resched_inst);
 
     /** Replays a memory instruction. It must be rescheduled first. */
-    void replayMemInst(DynInstPtr &replay_inst);
+    void replayMemInst(const DynInstPtr &replay_inst);
 
     /** Completes a memory operation. */
-    void completeMemInst(DynInstPtr &completed_inst);
+    void completeMemInst(const DynInstPtr &completed_inst);
 
     /**
      * Defers a memory instruction when its DTB translation incurs a hw
      * page table walk.
      */
-    void deferMemInst(DynInstPtr &deferred_inst);
+    void deferMemInst(const DynInstPtr &deferred_inst);
 
     /**  Defers a memory instruction when it is cache blocked. */
-    void blockMemInst(DynInstPtr &blocked_inst);
+    void blockMemInst(const DynInstPtr &blocked_inst);
 
     /**  Notify instruction queue that a previous blockage has resolved */
     void cacheUnblocked();
 
     /** Indicates an ordering violation between a store and a load. */
-    void violation(DynInstPtr &store, DynInstPtr &faulting_load);
+    void violation(const DynInstPtr &store, const DynInstPtr &faulting_load);
 
     /**
      * Squashes instructions for a thread. Squashing information is obtained
@@ -457,13 +457,13 @@
     std::vector<bool> regScoreboard;
 
     /** Adds an instruction to the dependency graph, as a consumer. */
-    bool addToDependents(DynInstPtr &new_inst);
+    bool addToDependents(const DynInstPtr &new_inst);
 
     /** Adds an instruction to the dependency graph, as a producer. */
-    void addToProducers(DynInstPtr &new_inst);
+    void addToProducers(const DynInstPtr &new_inst);
 
     /** Moves an instruction to the ready queue if it is ready. */
-    void addIfReady(DynInstPtr &inst);
+    void addIfReady(const DynInstPtr &inst);
 
     /** Debugging function to count how many entries are in the IQ.  It does
      *  a linear walk through the instructions, so do not call this function
diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh
index 84ac579..bc4822b 100644
--- a/src/cpu/o3/inst_queue_impl.hh
+++ b/src/cpu/o3/inst_queue_impl.hh
@@ -60,7 +60,7 @@
 using std::list;
 
 template <class Impl>
-InstructionQueue<Impl>::FUCompletion::FUCompletion(DynInstPtr &_inst,
+InstructionQueue<Impl>::FUCompletion::FUCompletion(const DynInstPtr &_inst,
     int fu_idx, InstructionQueue<Impl> *iq_ptr)
     : Event(Stat_Event_Pri, AutoDelete),
       inst(_inst), fuIdx(fu_idx), iqPtr(iq_ptr), freeFU(false)
@@ -585,7 +585,7 @@
 
 template <class Impl>
 void
-InstructionQueue<Impl>::insert(DynInstPtr &new_inst)
+InstructionQueue<Impl>::insert(const DynInstPtr &new_inst)
 {
     if (new_inst->isFloating()) {
         fpInstQueueWrites++;
@@ -631,7 +631,7 @@
 
 template <class Impl>
 void
-InstructionQueue<Impl>::insertNonSpec(DynInstPtr &new_inst)
+InstructionQueue<Impl>::insertNonSpec(const DynInstPtr &new_inst)
 {
     // @todo: Clean up this code; can do it by setting inst as unable
     // to issue, then calling normal insert on the inst.
@@ -678,7 +678,7 @@
 
 template <class Impl>
 void
-InstructionQueue<Impl>::insertBarrier(DynInstPtr &barr_inst)
+InstructionQueue<Impl>::insertBarrier(const DynInstPtr &barr_inst)
 {
     memDepUnit[barr_inst->threadNumber].insertBarrier(barr_inst);
 
@@ -690,7 +690,7 @@
 InstructionQueue<Impl>::getInstToExecute()
 {
     assert(!instsToExecute.empty());
-    DynInstPtr inst = instsToExecute.front();
+    DynInstPtr inst = std::move(instsToExecute.front());
     instsToExecute.pop_front();
     if (inst->isFloating()) {
         fpInstQueueReads++;
@@ -757,7 +757,7 @@
 
 template <class Impl>
 void
-InstructionQueue<Impl>::processFUCompletion(DynInstPtr &inst, int fu_idx)
+InstructionQueue<Impl>::processFUCompletion(const DynInstPtr &inst, int fu_idx)
 {
     DPRINTF(IQ, "Processing FU completion [sn:%lli]\n", inst->seqNum);
     assert(!cpu->switchedOut());
@@ -789,12 +789,12 @@
     IssueStruct *i2e_info = issueToExecuteQueue->access(0);
 
     DynInstPtr mem_inst;
-    while (mem_inst = getDeferredMemInstToExecute()) {
+    while (mem_inst = std::move(getDeferredMemInstToExecute())) {
         addReadyMemInst(mem_inst);
     }
 
     // See if any cache blocked instructions are able to be executed
-    while (mem_inst = getBlockedMemInstToExecute()) {
+    while (mem_inst = std::move(getBlockedMemInstToExecute())) {
         addReadyMemInst(mem_inst);
     }
 
@@ -995,7 +995,7 @@
 
 template <class Impl>
 int
-InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
+InstructionQueue<Impl>::wakeDependents(const DynInstPtr &completed_inst)
 {
     int dependents = 0;
 
@@ -1079,7 +1079,7 @@
 
 template <class Impl>
 void
-InstructionQueue<Impl>::addReadyMemInst(DynInstPtr &ready_inst)
+InstructionQueue<Impl>::addReadyMemInst(const DynInstPtr &ready_inst)
 {
     OpClass op_class = ready_inst->opClass();
 
@@ -1102,7 +1102,7 @@
 
 template <class Impl>
 void
-InstructionQueue<Impl>::rescheduleMemInst(DynInstPtr &resched_inst)
+InstructionQueue<Impl>::rescheduleMemInst(const DynInstPtr &resched_inst)
 {
     DPRINTF(IQ, "Rescheduling mem inst [sn:%lli]\n", resched_inst->seqNum);
 
@@ -1116,14 +1116,14 @@
 
 template <class Impl>
 void
-InstructionQueue<Impl>::replayMemInst(DynInstPtr &replay_inst)
+InstructionQueue<Impl>::replayMemInst(const DynInstPtr &replay_inst)
 {
     memDepUnit[replay_inst->threadNumber].replay();
 }
 
 template <class Impl>
 void
-InstructionQueue<Impl>::completeMemInst(DynInstPtr &completed_inst)
+InstructionQueue<Impl>::completeMemInst(const DynInstPtr &completed_inst)
 {
     ThreadID tid = completed_inst->threadNumber;
 
@@ -1140,14 +1140,14 @@
 
 template <class Impl>
 void
-InstructionQueue<Impl>::deferMemInst(DynInstPtr &deferred_inst)
+InstructionQueue<Impl>::deferMemInst(const DynInstPtr &deferred_inst)
 {
     deferredMemInsts.push_back(deferred_inst);
 }
 
 template <class Impl>
 void
-InstructionQueue<Impl>::blockMemInst(DynInstPtr &blocked_inst)
+InstructionQueue<Impl>::blockMemInst(const DynInstPtr &blocked_inst)
 {
     blocked_inst->translationStarted(false);
     blocked_inst->translationCompleted(false);
@@ -1173,7 +1173,7 @@
     for (ListIt it = deferredMemInsts.begin(); it != deferredMemInsts.end();
          ++it) {
         if ((*it)->translationCompleted() || (*it)->isSquashed()) {
-            DynInstPtr mem_inst = *it;
+            DynInstPtr mem_inst = std::move(*it);
             deferredMemInsts.erase(it);
             return mem_inst;
         }
@@ -1188,7 +1188,7 @@
     if (retryMemInsts.empty()) {
         return nullptr;
     } else {
-        DynInstPtr mem_inst = retryMemInsts.front();
+        DynInstPtr mem_inst = std::move(retryMemInsts.front());
         retryMemInsts.pop_front();
         return mem_inst;
     }
@@ -1196,8 +1196,8 @@
 
 template <class Impl>
 void
-InstructionQueue<Impl>::violation(DynInstPtr &store,
-                                  DynInstPtr &faulting_load)
+InstructionQueue<Impl>::violation(const DynInstPtr &store,
+                                  const DynInstPtr &faulting_load)
 {
     intInstQueueWrites++;
     memDepUnit[store->threadNumber].violation(store, faulting_load);
@@ -1364,7 +1364,7 @@
 
 template <class Impl>
 bool
-InstructionQueue<Impl>::addToDependents(DynInstPtr &new_inst)
+InstructionQueue<Impl>::addToDependents(const DynInstPtr &new_inst)
 {
     // Loop through the instruction's source registers, adding
     // them to the dependency list if they are not ready.
@@ -1412,7 +1412,7 @@
 
 template <class Impl>
 void
-InstructionQueue<Impl>::addToProducers(DynInstPtr &new_inst)
+InstructionQueue<Impl>::addToProducers(const DynInstPtr &new_inst)
 {
     // Nothing really needs to be marked when an instruction becomes
     // the producer of a register's value, but for convenience a ptr
@@ -1448,7 +1448,7 @@
 
 template <class Impl>
 void
-InstructionQueue<Impl>::addIfReady(DynInstPtr &inst)
+InstructionQueue<Impl>::addIfReady(const DynInstPtr &inst)
 {
     // If the instruction now has all of its source registers
     // available, then add it to the list of ready instructions.
diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh
index 7c78156..175821e 100644
--- a/src/cpu/o3/lsq.hh
+++ b/src/cpu/o3/lsq.hh
@@ -106,15 +106,15 @@
     { thread[tid].tick(); }
 
     /** Inserts a load into the LSQ. */
-    void insertLoad(DynInstPtr &load_inst);
+    void insertLoad(const DynInstPtr &load_inst);
     /** Inserts a store into the LSQ. */
-    void insertStore(DynInstPtr &store_inst);
+    void insertStore(const DynInstPtr &store_inst);
 
     /** Executes a load. */
-    Fault executeLoad(DynInstPtr &inst);
+    Fault executeLoad(const DynInstPtr &inst);
 
     /** Executes a store. */
-    Fault executeStore(DynInstPtr &inst);
+    Fault executeStore(const DynInstPtr &inst);
 
     /**
      * Commits loads up until the given sequence number for a specific thread.
diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index 56b95a5..967a496 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -257,7 +257,7 @@
 
 template<class Impl>
 void
-LSQ<Impl>::insertLoad(DynInstPtr &load_inst)
+LSQ<Impl>::insertLoad(const DynInstPtr &load_inst)
 {
     ThreadID tid = load_inst->threadNumber;
 
@@ -266,7 +266,7 @@
 
 template<class Impl>
 void
-LSQ<Impl>::insertStore(DynInstPtr &store_inst)
+LSQ<Impl>::insertStore(const DynInstPtr &store_inst)
 {
     ThreadID tid = store_inst->threadNumber;
 
@@ -275,7 +275,7 @@
 
 template<class Impl>
 Fault
-LSQ<Impl>::executeLoad(DynInstPtr &inst)
+LSQ<Impl>::executeLoad(const DynInstPtr &inst)
 {
     ThreadID tid = inst->threadNumber;
 
@@ -284,7 +284,7 @@
 
 template<class Impl>
 Fault
-LSQ<Impl>::executeStore(DynInstPtr &inst)
+LSQ<Impl>::executeStore(const DynInstPtr &inst)
 {
     ThreadID tid = inst->threadNumber;
 
diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh
index f5b60b2..813a3ca 100644
--- a/src/cpu/o3/lsq_unit.hh
+++ b/src/cpu/o3/lsq_unit.hh
@@ -116,11 +116,11 @@
     void tick() { usedStorePorts = 0; }
 
     /** Inserts an instruction. */
-    void insert(DynInstPtr &inst);
+    void insert(const DynInstPtr &inst);
     /** Inserts a load instruction. */
-    void insertLoad(DynInstPtr &load_inst);
+    void insertLoad(const DynInstPtr &load_inst);
     /** Inserts a store instruction. */
-    void insertStore(DynInstPtr &store_inst);
+    void insertStore(const DynInstPtr &store_inst);
 
     /** Check for ordering violations in the LSQ. For a store squash if we
      * ever find a conflicting load. For a load, only squash if we
@@ -128,7 +128,7 @@
      * @param load_idx index to start checking at
      * @param inst the instruction to check
      */
-    Fault checkViolations(int load_idx, DynInstPtr &inst);
+    Fault checkViolations(int load_idx, const DynInstPtr &inst);
 
     /** Check if an incoming invalidate hits in the lsq on a load
      * that might have issued out of order wrt another load beacuse
@@ -137,11 +137,11 @@
     void checkSnoop(PacketPtr pkt);
 
     /** Executes a load instruction. */
-    Fault executeLoad(DynInstPtr &inst);
+    Fault executeLoad(const DynInstPtr &inst);
 
     Fault executeLoad(int lq_idx) { panic("Not implemented"); return NoFault; }
     /** Executes a store instruction. */
-    Fault executeStore(DynInstPtr &inst);
+    Fault executeStore(const DynInstPtr &inst);
 
     /** Commits the head load. */
     void commitLoad();
@@ -233,7 +233,7 @@
     void resetState();
 
     /** Writes back the instruction, sending it to IEW. */
-    void writeback(DynInstPtr &inst, PacketPtr pkt);
+    void writeback(const DynInstPtr &inst, PacketPtr pkt);
 
     /** Writes back a store that couldn't be completed the previous cycle. */
     void writebackPendingStore();
@@ -313,7 +313,8 @@
     class WritebackEvent : public Event {
       public:
         /** Constructs a writeback event. */
-        WritebackEvent(DynInstPtr &_inst, PacketPtr pkt, LSQUnit *lsq_ptr);
+        WritebackEvent(const DynInstPtr &_inst, PacketPtr pkt,
+                LSQUnit *lsq_ptr);
 
         /** Processes the writeback event. */
         void process();
@@ -348,7 +349,7 @@
         }
 
         /** Constructs a store queue entry for a given instruction. */
-        SQEntry(DynInstPtr &_inst)
+        SQEntry(const DynInstPtr &_inst)
             : inst(_inst), req(NULL), sreqLow(NULL), sreqHigh(NULL), size(0),
               isSplit(0), canWB(0), committed(0), completed(0), isAllZeros(0)
         {
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index c2750be..d8f1c39 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -61,8 +61,8 @@
 #include "mem/request.hh"
 
 template<class Impl>
-LSQUnit<Impl>::WritebackEvent::WritebackEvent(DynInstPtr &_inst, PacketPtr _pkt,
-                                              LSQUnit *lsq_ptr)
+LSQUnit<Impl>::WritebackEvent::WritebackEvent(const DynInstPtr &_inst,
+        PacketPtr _pkt, LSQUnit *lsq_ptr)
     : Event(Default_Pri, AutoDelete),
       inst(_inst), pkt(_pkt), lsqPtr(lsq_ptr)
 {
@@ -339,7 +339,7 @@
 
 template <class Impl>
 void
-LSQUnit<Impl>::insert(DynInstPtr &inst)
+LSQUnit<Impl>::insert(const DynInstPtr &inst)
 {
     assert(inst->isMemRef());
 
@@ -356,7 +356,7 @@
 
 template <class Impl>
 void
-LSQUnit<Impl>::insertLoad(DynInstPtr &load_inst)
+LSQUnit<Impl>::insertLoad(const DynInstPtr &load_inst)
 {
     assert((loadTail + 1) % LQEntries != loadHead);
     assert(loads < LQEntries);
@@ -381,7 +381,7 @@
 
 template <class Impl>
 void
-LSQUnit<Impl>::insertStore(DynInstPtr &store_inst)
+LSQUnit<Impl>::insertStore(const DynInstPtr &store_inst)
 {
     // Make sure it is not full before inserting an instruction.
     assert((storeTail + 1) % SQEntries != storeHead);
@@ -525,7 +525,7 @@
 
 template <class Impl>
 Fault
-LSQUnit<Impl>::checkViolations(int load_idx, DynInstPtr &inst)
+LSQUnit<Impl>::checkViolations(int load_idx, const DynInstPtr &inst)
 {
     Addr inst_eff_addr1 = inst->effAddr >> depCheckShift;
     Addr inst_eff_addr2 = (inst->effAddr + inst->effSize - 1) >> depCheckShift;
@@ -605,7 +605,7 @@
 
 template <class Impl>
 Fault
-LSQUnit<Impl>::executeLoad(DynInstPtr &inst)
+LSQUnit<Impl>::executeLoad(const DynInstPtr &inst)
 {
     using namespace TheISA;
     // Execute a specific load.
@@ -654,7 +654,7 @@
 
 template <class Impl>
 Fault
-LSQUnit<Impl>::executeStore(DynInstPtr &store_inst)
+LSQUnit<Impl>::executeStore(const DynInstPtr &store_inst)
 {
     using namespace TheISA;
     // Make sure that a store exists.
@@ -1105,7 +1105,7 @@
 
 template <class Impl>
 void
-LSQUnit<Impl>::writeback(DynInstPtr &inst, PacketPtr pkt)
+LSQUnit<Impl>::writeback(const DynInstPtr &inst, PacketPtr pkt)
 {
     iewStage->wakeCPU();
 
diff --git a/src/cpu/o3/mem_dep_unit.hh b/src/cpu/o3/mem_dep_unit.hh
index ffe66be..24f5c20 100644
--- a/src/cpu/o3/mem_dep_unit.hh
+++ b/src/cpu/o3/mem_dep_unit.hh
@@ -85,6 +85,7 @@
 
   public:
     typedef typename Impl::DynInstPtr DynInstPtr;
+    typedef typename Impl::DynInstConstPtr DynInstConstPtr;
 
     /** Empty constructor. Must call init() prior to using in this case. */
     MemDepUnit();
@@ -117,22 +118,22 @@
     void setIQ(InstructionQueue<Impl> *iq_ptr);
 
     /** Inserts a memory instruction. */
-    void insert(DynInstPtr &inst);
+    void insert(const DynInstPtr &inst);
 
     /** Inserts a non-speculative memory instruction. */
-    void insertNonSpec(DynInstPtr &inst);
+    void insertNonSpec(const DynInstPtr &inst);
 
     /** Inserts a barrier instruction. */
-    void insertBarrier(DynInstPtr &barr_inst);
+    void insertBarrier(const DynInstPtr &barr_inst);
 
     /** Indicate that an instruction has its registers ready. */
-    void regsReady(DynInstPtr &inst);
+    void regsReady(const DynInstPtr &inst);
 
     /** Indicate that a non-speculative instruction is ready. */
-    void nonSpecInstReady(DynInstPtr &inst);
+    void nonSpecInstReady(const DynInstPtr &inst);
 
     /** Reschedules an instruction to be re-executed. */
-    void reschedule(DynInstPtr &inst);
+    void reschedule(const DynInstPtr &inst);
 
     /** Replays all instructions that have been rescheduled by moving them to
      *  the ready list.
@@ -140,13 +141,13 @@
     void replay();
 
     /** Completes a memory instruction. */
-    void completed(DynInstPtr &inst);
+    void completed(const DynInstPtr &inst);
 
     /** Completes a barrier instruction. */
-    void completeBarrier(DynInstPtr &inst);
+    void completeBarrier(const DynInstPtr &inst);
 
     /** Wakes any dependents of a memory instruction. */
-    void wakeDependents(DynInstPtr &inst);
+    void wakeDependents(const DynInstPtr &inst);
 
     /** Squashes all instructions up until a given sequence number for a
      *  specific thread.
@@ -154,10 +155,11 @@
     void squash(const InstSeqNum &squashed_num, ThreadID tid);
 
     /** Indicates an ordering violation between a store and a younger load. */
-    void violation(DynInstPtr &store_inst, DynInstPtr &violating_load);
+    void violation(const DynInstPtr &store_inst,
+                   const DynInstPtr &violating_load);
 
     /** Issues the given instruction */
-    void issue(DynInstPtr &inst);
+    void issue(const DynInstPtr &inst);
 
     /** Debugging function to dump the lists of instructions. */
     void dumpLists();
@@ -176,7 +178,7 @@
     class MemDepEntry {
       public:
         /** Constructs a memory dependence entry. */
-        MemDepEntry(DynInstPtr &new_inst)
+        MemDepEntry(const DynInstPtr &new_inst)
             : inst(new_inst), regsReady(false), memDepReady(false),
               completed(false), squashed(false)
         {
@@ -232,7 +234,7 @@
     };
 
     /** Finds the memory dependence entry in the hash map. */
-    inline MemDepEntryPtr &findInHash(const DynInstPtr &inst);
+    inline MemDepEntryPtr &findInHash(const DynInstConstPtr& inst);
 
     /** Moves an entry to the ready list. */
     inline void moveToReady(MemDepEntryPtr &ready_inst_entry);
diff --git a/src/cpu/o3/mem_dep_unit_impl.hh b/src/cpu/o3/mem_dep_unit_impl.hh
index 376198f..26c4b4d 100644
--- a/src/cpu/o3/mem_dep_unit_impl.hh
+++ b/src/cpu/o3/mem_dep_unit_impl.hh
@@ -171,7 +171,7 @@
 
 template <class MemDepPred, class Impl>
 void
-MemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst)
+MemDepUnit<MemDepPred, Impl>::insert(const DynInstPtr &inst)
 {
     ThreadID tid = inst->threadNumber;
 
@@ -268,7 +268,7 @@
 
 template <class MemDepPred, class Impl>
 void
-MemDepUnit<MemDepPred, Impl>::insertNonSpec(DynInstPtr &inst)
+MemDepUnit<MemDepPred, Impl>::insertNonSpec(const DynInstPtr &inst)
 {
     ThreadID tid = inst->threadNumber;
 
@@ -304,7 +304,7 @@
 
 template <class MemDepPred, class Impl>
 void
-MemDepUnit<MemDepPred, Impl>::insertBarrier(DynInstPtr &barr_inst)
+MemDepUnit<MemDepPred, Impl>::insertBarrier(const DynInstPtr &barr_inst)
 {
     InstSeqNum barr_sn = barr_inst->seqNum;
     // Memory barriers block loads and stores, write barriers only stores.
@@ -340,7 +340,7 @@
 
 template <class MemDepPred, class Impl>
 void
-MemDepUnit<MemDepPred, Impl>::regsReady(DynInstPtr &inst)
+MemDepUnit<MemDepPred, Impl>::regsReady(const DynInstPtr &inst)
 {
     DPRINTF(MemDepUnit, "Marking registers as ready for "
             "instruction PC %s [sn:%lli].\n",
@@ -363,7 +363,7 @@
 
 template <class MemDepPred, class Impl>
 void
-MemDepUnit<MemDepPred, Impl>::nonSpecInstReady(DynInstPtr &inst)
+MemDepUnit<MemDepPred, Impl>::nonSpecInstReady(const DynInstPtr &inst)
 {
     DPRINTF(MemDepUnit, "Marking non speculative "
             "instruction PC %s as ready [sn:%lli].\n",
@@ -376,7 +376,7 @@
 
 template <class MemDepPred, class Impl>
 void
-MemDepUnit<MemDepPred, Impl>::reschedule(DynInstPtr &inst)
+MemDepUnit<MemDepPred, Impl>::reschedule(const DynInstPtr &inst)
 {
     instsToReplay.push_back(inst);
 }
@@ -404,7 +404,7 @@
 
 template <class MemDepPred, class Impl>
 void
-MemDepUnit<MemDepPred, Impl>::completed(DynInstPtr &inst)
+MemDepUnit<MemDepPred, Impl>::completed(const DynInstPtr &inst)
 {
     DPRINTF(MemDepUnit, "Completed mem instruction PC %s [sn:%lli].\n",
             inst->pcState(), inst->seqNum);
@@ -428,7 +428,7 @@
 
 template <class MemDepPred, class Impl>
 void
-MemDepUnit<MemDepPred, Impl>::completeBarrier(DynInstPtr &inst)
+MemDepUnit<MemDepPred, Impl>::completeBarrier(const DynInstPtr &inst)
 {
     wakeDependents(inst);
     completed(inst);
@@ -449,7 +449,7 @@
 
 template <class MemDepPred, class Impl>
 void
-MemDepUnit<MemDepPred, Impl>::wakeDependents(DynInstPtr &inst)
+MemDepUnit<MemDepPred, Impl>::wakeDependents(const DynInstPtr &inst)
 {
     // Only stores and barriers have dependents.
     if (!inst->isStore() && !inst->isMemBarrier() && !inst->isWriteBarrier()) {
@@ -536,8 +536,8 @@
 
 template <class MemDepPred, class Impl>
 void
-MemDepUnit<MemDepPred, Impl>::violation(DynInstPtr &store_inst,
-                                        DynInstPtr &violating_load)
+MemDepUnit<MemDepPred, Impl>::violation(const DynInstPtr &store_inst,
+                                        const DynInstPtr &violating_load)
 {
     DPRINTF(MemDepUnit, "Passing violating PCs to store sets,"
             " load: %#x, store: %#x\n", violating_load->instAddr(),
@@ -548,7 +548,7 @@
 
 template <class MemDepPred, class Impl>
 void
-MemDepUnit<MemDepPred, Impl>::issue(DynInstPtr &inst)
+MemDepUnit<MemDepPred, Impl>::issue(const DynInstPtr &inst)
 {
     DPRINTF(MemDepUnit, "Issuing instruction PC %#x [sn:%lli].\n",
             inst->instAddr(), inst->seqNum);
@@ -558,7 +558,7 @@
 
 template <class MemDepPred, class Impl>
 inline typename MemDepUnit<MemDepPred,Impl>::MemDepEntryPtr &
-MemDepUnit<MemDepPred, Impl>::findInHash(const DynInstPtr &inst)
+MemDepUnit<MemDepPred, Impl>::findInHash(const DynInstConstPtr &inst)
 {
     MemDepHashIt hash_it = memDepHash.find(inst->seqNum);
 
diff --git a/src/cpu/o3/probe/elastic_trace.cc b/src/cpu/o3/probe/elastic_trace.cc
index 508140e..a4a2013 100644
--- a/src/cpu/o3/probe/elastic_trace.cc
+++ b/src/cpu/o3/probe/elastic_trace.cc
@@ -124,18 +124,23 @@
     // each probe point.
     listeners.push_back(new ProbeListenerArg<ElasticTrace, RequestPtr>(this,
                         "FetchRequest", &ElasticTrace::fetchReqTrace));
-    listeners.push_back(new ProbeListenerArg<ElasticTrace, DynInstPtr>(this,
-                        "Execute", &ElasticTrace::recordExecTick));
-    listeners.push_back(new ProbeListenerArg<ElasticTrace, DynInstPtr>(this,
-                        "ToCommit", &ElasticTrace::recordToCommTick));
-    listeners.push_back(new ProbeListenerArg<ElasticTrace, DynInstPtr>(this,
-                        "Rename", &ElasticTrace::updateRegDep));
+    listeners.push_back(new ProbeListenerArg<ElasticTrace,
+            DynInstConstPtr>(this, "Execute",
+                &ElasticTrace::recordExecTick));
+    listeners.push_back(new ProbeListenerArg<ElasticTrace,
+            DynInstConstPtr>(this, "ToCommit",
+                &ElasticTrace::recordToCommTick));
+    listeners.push_back(new ProbeListenerArg<ElasticTrace,
+            DynInstConstPtr>(this, "Rename",
+                &ElasticTrace::updateRegDep));
     listeners.push_back(new ProbeListenerArg<ElasticTrace, SeqNumRegPair>(this,
                         "SquashInRename", &ElasticTrace::removeRegDepMapEntry));
-    listeners.push_back(new ProbeListenerArg<ElasticTrace, DynInstPtr>(this,
-                        "Squash", &ElasticTrace::addSquashedInst));
-    listeners.push_back(new ProbeListenerArg<ElasticTrace, DynInstPtr>(this,
-                        "Commit", &ElasticTrace::addCommittedInst));
+    listeners.push_back(new ProbeListenerArg<ElasticTrace,
+            DynInstConstPtr>(this, "Squash",
+                &ElasticTrace::addSquashedInst));
+    listeners.push_back(new ProbeListenerArg<ElasticTrace,
+            DynInstConstPtr>(this, "Commit",
+                &ElasticTrace::addCommittedInst));
     allProbesReg = true;
 }
 
@@ -162,7 +167,7 @@
 }
 
 void
-ElasticTrace::recordExecTick(const DynInstPtr &dyn_inst)
+ElasticTrace::recordExecTick(const DynInstConstPtr& dyn_inst)
 {
 
     // In a corner case, a retired instruction is propagated backward to the
@@ -199,7 +204,7 @@
 }
 
 void
-ElasticTrace::recordToCommTick(const DynInstPtr &dyn_inst)
+ElasticTrace::recordToCommTick(const DynInstConstPtr& dyn_inst)
 {
     // If tracing has just been enabled then the instruction at this stage of
     // execution is far enough that we cannot gather info about its past like
@@ -220,7 +225,7 @@
 }
 
 void
-ElasticTrace::updateRegDep(const DynInstPtr &dyn_inst)
+ElasticTrace::updateRegDep(const DynInstConstPtr& dyn_inst)
 {
     // Get the sequence number of the instruction
     InstSeqNum seq_num = dyn_inst->seqNum;
@@ -298,7 +303,7 @@
 }
 
 void
-ElasticTrace::addSquashedInst(const DynInstPtr &head_inst)
+ElasticTrace::addSquashedInst(const DynInstConstPtr& head_inst)
 {
     // If the squashed instruction was squashed before being processed by
     // execute stage then it will not be in the temporary store. In this case
@@ -326,7 +331,7 @@
 }
 
 void
-ElasticTrace::addCommittedInst(const DynInstPtr &head_inst)
+ElasticTrace::addCommittedInst(const DynInstConstPtr& head_inst)
 {
     DPRINTFR(ElasticTrace, "Attempt to add committed inst [sn:%lli]\n",
                 head_inst->seqNum);
@@ -385,7 +390,7 @@
 }
 
 void
-ElasticTrace::addDepTraceRecord(const DynInstPtr &head_inst,
+ElasticTrace::addDepTraceRecord(const DynInstConstPtr& head_inst,
                                 InstExecInfo* exec_info_ptr, bool commit)
 {
     // Create a record to assign dynamic intruction related fields.
@@ -648,7 +653,7 @@
 }
 
 void
-ElasticTrace::clearTempStoreUntil(const DynInstPtr head_inst)
+ElasticTrace::clearTempStoreUntil(const DynInstConstPtr& head_inst)
 {
     // Clear from temp store starting with the execution info object
     // corresponding the head_inst and continue clearing by decrementing the
diff --git a/src/cpu/o3/probe/elastic_trace.hh b/src/cpu/o3/probe/elastic_trace.hh
index 08e02da..21029b9 100644
--- a/src/cpu/o3/probe/elastic_trace.hh
+++ b/src/cpu/o3/probe/elastic_trace.hh
@@ -90,6 +90,7 @@
 
   public:
     typedef typename O3CPUImpl::DynInstPtr DynInstPtr;
+    typedef typename O3CPUImpl::DynInstConstPtr DynInstConstPtr;
     typedef typename std::pair<InstSeqNum, PhysRegIndex> SeqNumRegPair;
 
     /** Trace record types corresponding to instruction node types */
@@ -132,7 +133,7 @@
      *
      * @param dyn_inst pointer to dynamic instruction in flight
      */
-    void recordExecTick(const DynInstPtr &dyn_inst);
+    void recordExecTick(const DynInstConstPtr& dyn_inst);
 
     /**
      * Populate the timestamp field in an InstExecInfo object for an
@@ -141,7 +142,7 @@
      *
      * @param dyn_inst pointer to dynamic instruction in flight
      */
-    void recordToCommTick(const DynInstPtr &dyn_inst);
+    void recordToCommTick(const DynInstConstPtr& dyn_inst);
 
     /**
      * Record a Read After Write physical register dependency if there has
@@ -152,7 +153,7 @@
      *
      * @param dyn_inst pointer to dynamic instruction in flight
      */
-    void updateRegDep(const DynInstPtr &dyn_inst);
+    void updateRegDep(const DynInstConstPtr& dyn_inst);
 
     /**
      * When an instruction gets squashed the destination register mapped to it
@@ -169,14 +170,14 @@
      *
      * @param head_inst pointer to dynamic instruction to be squashed
      */
-    void addSquashedInst(const DynInstPtr &head_inst);
+    void addSquashedInst(const DynInstConstPtr& head_inst);
 
     /**
      * Add an instruction that is at the head of the ROB and is committed.
      *
      * @param head_inst pointer to dynamic instruction to be committed
      */
-    void addCommittedInst(const DynInstPtr &head_inst);
+    void addCommittedInst(const DynInstConstPtr& head_inst);
 
     /** Register statistics for the elastic trace. */
     void regStats();
@@ -385,7 +386,7 @@
      * @param exec_info_ptr Pointer to InstExecInfo for that instruction
      * @param commit        True if instruction is committed, false if squashed
      */
-    void addDepTraceRecord(const DynInstPtr &head_inst,
+    void addDepTraceRecord(const DynInstConstPtr& head_inst,
                            InstExecInfo* exec_info_ptr, bool commit);
 
     /**
@@ -394,7 +395,7 @@
      *
      * @param head_inst pointer to dynamic instruction
      */
-    void clearTempStoreUntil(const DynInstPtr head_inst);
+    void clearTempStoreUntil(const DynInstConstPtr& head_inst);
 
     /**
      * Calculate the computational delay between an instruction and a
diff --git a/src/cpu/o3/probe/simple_trace.cc b/src/cpu/o3/probe/simple_trace.cc
index 060b4df..4c7b676 100644
--- a/src/cpu/o3/probe/simple_trace.cc
+++ b/src/cpu/o3/probe/simple_trace.cc
@@ -42,14 +42,14 @@
 #include "base/trace.hh"
 #include "debug/SimpleTrace.hh"
 
-void SimpleTrace::traceCommit(const O3CPUImpl::DynInstPtr &dynInst)
+void SimpleTrace::traceCommit(const O3CPUImpl::DynInstConstPtr& dynInst)
 {
     DPRINTFR(SimpleTrace, "[%s]: Commit 0x%08x %s.\n", name(),
              dynInst->instAddr(),
              dynInst->staticInst->disassemble(dynInst->instAddr()));
 }
 
-void SimpleTrace::traceFetch(const O3CPUImpl::DynInstPtr &dynInst)
+void SimpleTrace::traceFetch(const O3CPUImpl::DynInstConstPtr& dynInst)
 {
     DPRINTFR(SimpleTrace, "[%s]: Fetch 0x%08x %s.\n", name(),
              dynInst->instAddr(),
@@ -58,9 +58,12 @@
 
 void SimpleTrace::regProbeListeners()
 {
-    typedef ProbeListenerArg<SimpleTrace, O3CPUImpl::DynInstPtr> DynInstListener;
-    listeners.push_back(new DynInstListener(this, "Commit", &SimpleTrace::traceCommit));
-    listeners.push_back(new DynInstListener(this, "Fetch", &SimpleTrace::traceFetch));
+    typedef ProbeListenerArg<SimpleTrace,
+            O3CPUImpl::DynInstConstPtr> DynInstListener;
+    listeners.push_back(new DynInstListener(this, "Commit",
+                &SimpleTrace::traceCommit));
+    listeners.push_back(new DynInstListener(this, "Fetch",
+                &SimpleTrace::traceFetch));
 }
 
 SimpleTrace*
diff --git a/src/cpu/o3/probe/simple_trace.hh b/src/cpu/o3/probe/simple_trace.hh
index 6631288..928062e 100644
--- a/src/cpu/o3/probe/simple_trace.hh
+++ b/src/cpu/o3/probe/simple_trace.hh
@@ -66,8 +66,8 @@
     const std::string name() const { return ProbeListenerObject::name() + ".trace"; }
 
   private:
-    void traceFetch(const O3CPUImpl::DynInstPtr &dynInst);
-    void traceCommit(const O3CPUImpl::DynInstPtr &dynInst);
+    void traceFetch(const O3CPUImpl::DynInstConstPtr& dynInst);
+    void traceCommit(const O3CPUImpl::DynInstConstPtr& dynInst);
 
 };
 #endif//__CPU_O3_PROBE_SIMPLE_TRACE_HH__
diff --git a/src/cpu/o3/rename.hh b/src/cpu/o3/rename.hh
index d0f6ba1..bd5e72d 100644
--- a/src/cpu/o3/rename.hh
+++ b/src/cpu/o3/rename.hh
@@ -252,10 +252,10 @@
     void removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid);
 
     /** Renames the source registers of an instruction. */
-    inline void renameSrcRegs(DynInstPtr &inst, ThreadID tid);
+    inline void renameSrcRegs(const DynInstPtr &inst, ThreadID tid);
 
     /** Renames the destination registers of an instruction. */
-    inline void renameDestRegs(DynInstPtr &inst, ThreadID tid);
+    inline void renameDestRegs(const DynInstPtr &inst, ThreadID tid);
 
     /** Calculates the number of free ROB entries for a specific thread. */
     inline int calcFreeROBEntries(ThreadID tid);
diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh
index bc024f6..a295a87 100644
--- a/src/cpu/o3/rename_impl.hh
+++ b/src/cpu/o3/rename_impl.hh
@@ -524,8 +524,6 @@
         ++renameRunCycles;
     }
 
-    DynInstPtr inst;
-
     // Will have to do a different calculation for the number of free
     // entries.
     int free_rob_entries = calcFreeROBEntries(tid);
@@ -596,7 +594,7 @@
 
         assert(!insts_to_rename.empty());
 
-        inst = insts_to_rename.front();
+        DynInstPtr inst = insts_to_rename.front();
 
         //For all kind of instructions, check ROB and IQ first
         //For load instruction, check LQ size and take into account the inflight loads
@@ -787,7 +785,7 @@
 {
     int insts_from_decode = fromDecode->size;
     for (int i = 0; i < insts_from_decode; ++i) {
-        DynInstPtr inst = fromDecode->insts[i];
+        const DynInstPtr &inst = fromDecode->insts[i];
         insts[inst->threadNumber].push_back(inst);
 #if TRACING_ON
         if (DTRACE(O3PipeView)) {
@@ -1008,7 +1006,7 @@
 
 template <class Impl>
 inline void
-DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
+DefaultRename<Impl>::renameSrcRegs(const DynInstPtr &inst, ThreadID tid)
 {
     ThreadContext *tc = inst->tcBase();
     RenameMap *map = renameMap[tid];
@@ -1068,7 +1066,7 @@
 
 template <class Impl>
 inline void
-DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid)
+DefaultRename<Impl>::renameDestRegs(const DynInstPtr &inst, ThreadID tid)
 {
     ThreadContext *tc = inst->tcBase();
     RenameMap *map = renameMap[tid];
diff --git a/src/cpu/o3/rob.hh b/src/cpu/o3/rob.hh
index 1c3cc28..1896e62 100644
--- a/src/cpu/o3/rob.hh
+++ b/src/cpu/o3/rob.hh
@@ -114,7 +114,7 @@
      *  ROB for the new instruction.
      *  @param inst The instruction being inserted into the ROB.
      */
-    void insertInst(DynInstPtr &inst);
+    void insertInst(const DynInstPtr &inst);
 
     /** Returns pointer to the head instruction within the ROB.  There is
      *  no guarantee as to the return value if the ROB is empty.
@@ -126,7 +126,7 @@
      *  the ROB.
      *  @return Pointer to the DynInst that is at the head of the ROB.
      */
-    DynInstPtr readHeadInst(ThreadID tid);
+    const DynInstPtr &readHeadInst(ThreadID tid);
 
     /** Returns a pointer to the instruction with the given sequence if it is
      *  in the ROB.
diff --git a/src/cpu/o3/rob_impl.hh b/src/cpu/o3/rob_impl.hh
index 5a9dc90..223f94c 100644
--- a/src/cpu/o3/rob_impl.hh
+++ b/src/cpu/o3/rob_impl.hh
@@ -209,7 +209,7 @@
 
 template <class Impl>
 void
-ROB<Impl>::insertInst(DynInstPtr &inst)
+ROB<Impl>::insertInst(const DynInstPtr &inst)
 {
     assert(inst);
 
@@ -252,10 +252,11 @@
 
     assert(numInstsInROB > 0);
 
-    // Get the head ROB instruction.
+    // Get the head ROB instruction by copying it and remove it from the list
     InstIt head_it = instList[tid].begin();
 
-    DynInstPtr head_inst = (*head_it);
+    DynInstPtr head_inst = std::move(*head_it);
+    instList[tid].erase(head_it);
 
     assert(head_inst->readyToCommit());
 
@@ -269,8 +270,6 @@
     head_inst->clearInROB();
     head_inst->setCommitted();
 
-    instList[tid].erase(head_it);
-
     //Update "Global" Head of ROB
     updateHead();
 
@@ -513,7 +512,7 @@
 }
 
 template <class Impl>
-typename Impl::DynInstPtr
+const typename Impl::DynInstPtr&
 ROB<Impl>::readHeadInst(ThreadID tid)
 {
     if (threadEntries[tid] != 0) {
diff --git a/src/cpu/simple/exec_context.hh b/src/cpu/simple/exec_context.hh
index 13c44ac..8ff18dd 100644
--- a/src/cpu/simple/exec_context.hh
+++ b/src/cpu/simple/exec_context.hh
@@ -482,7 +482,7 @@
         return thread->simPalCheck(palFunc);
     }
 
-    bool readPredicate() override
+    bool readPredicate() const override
     {
         return thread->readPredicate();
     }