From 0c50a0b4fe3956f9d2e08e75d47c9cbd79bf0268 Mon Sep 17 00:00:00 2001 From: Rekai Gonzalez-Alberquilla Date: Mon, 6 Feb 2017 11:10:06 +0000 Subject: 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 Reviewed-on: https://gem5-review.googlesource.com/c/13105 Reviewed-by: Andreas Sandberg Reviewed-by: Jason Lowe-Power Maintainer: Andreas Sandberg Maintainer: Jason Lowe-Power --- src/base/refcnt.hh | 60 +++++++++++++++++++++++++++++++++++++-- src/cpu/base_dyn_inst.hh | 6 ++-- src/cpu/base_dyn_inst_impl.hh | 2 +- src/cpu/checker/cpu.hh | 15 +++++----- src/cpu/checker/cpu_impl.hh | 12 ++++---- src/cpu/exec_context.hh | 2 +- src/cpu/minor/exec_context.hh | 2 +- src/cpu/o3/commit.hh | 6 ++-- src/cpu/o3/commit_impl.hh | 16 +++++------ src/cpu/o3/cpu.cc | 8 +++--- src/cpu/o3/cpu.hh | 6 ++-- src/cpu/o3/decode.hh | 2 +- src/cpu/o3/decode_impl.hh | 6 ++-- src/cpu/o3/dep_graph.hh | 11 +++---- src/cpu/o3/fetch.hh | 2 +- src/cpu/o3/fetch_impl.hh | 4 +-- src/cpu/o3/iew.hh | 18 ++++++------ src/cpu/o3/iew_impl.hh | 18 ++++++------ src/cpu/o3/impl.hh | 1 + src/cpu/o3/inst_queue.hh | 34 +++++++++++----------- src/cpu/o3/inst_queue_impl.hh | 44 ++++++++++++++-------------- src/cpu/o3/lsq.hh | 8 +++--- src/cpu/o3/lsq_impl.hh | 8 +++--- src/cpu/o3/lsq_unit.hh | 19 +++++++------ src/cpu/o3/lsq_unit_impl.hh | 18 ++++++------ src/cpu/o3/mem_dep_unit.hh | 28 +++++++++--------- src/cpu/o3/mem_dep_unit_impl.hh | 26 ++++++++--------- src/cpu/o3/probe/elastic_trace.cc | 39 ++++++++++++++----------- src/cpu/o3/probe/elastic_trace.hh | 15 +++++----- src/cpu/o3/probe/simple_trace.cc | 13 +++++---- src/cpu/o3/probe/simple_trace.hh | 4 +-- src/cpu/o3/rename.hh | 4 +-- src/cpu/o3/rename_impl.hh | 10 +++---- src/cpu/o3/rob.hh | 4 +-- src/cpu/o3/rob_impl.hh | 11 ++++--- src/cpu/simple/exec_context.hh | 2 +- 36 files changed, 274 insertions(+), 210 deletions(-) diff --git a/src/base/refcnt.hh b/src/base/refcnt.hh index baf08c62e..f2821231d 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 + /** * @file base/refcnt.hh * @@ -80,11 +94,11 @@ class RefCounted 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 @@ template class RefCountingPtr { protected: + /** Convenience aliases for const/non-const versions of T w/ friendship. */ + /** @{ */ + static constexpr auto TisConst = std::is_const::value; + using ConstT = typename std::conditional, + RefCountingPtr::type>>::type; + friend ConstT; + using NonConstT = typename std::conditional::type>, + RefCountingPtr>::type; + friend NonConstT; + /** @} */ /// The stored pointer. /// Arguably this should be private. T *data; @@ -163,6 +189,18 @@ class RefCountingPtr /// 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 + RefCountingPtr(const NonConstT &r) { copy(r.data); } + /// Destroy the pointer and any reference it may hold. ~RefCountingPtr() { del(); } @@ -179,6 +217,12 @@ class RefCountingPtr /// Directly access the pointer itself without taking a reference. T *get() const { return data; } + template + operator RefCountingPtr::type>() + { + return RefCountingPtr(*this); + } + /// Assign a new value to the pointer const RefCountingPtr &operator=(T *p) { set(p); return *this; } @@ -186,6 +230,18 @@ class RefCountingPtr 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 93cafd694..b4431da1f 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -827,7 +827,7 @@ class BaseDynInst : public ExecContext, public RefCounted /**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 @@ class BaseDynInst : public ExecContext, public RefCounted 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 b499fe4e6..f638f754c 100644 --- a/src/cpu/base_dyn_inst_impl.hh +++ b/src/cpu/base_dyn_inst_impl.hh @@ -217,7 +217,7 @@ BaseDynInst::markSrcRegReady(RegIndex src_idx) template bool -BaseDynInst::eaSrcsReady() +BaseDynInst::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 bee72253e..cb87f622a 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -397,7 +397,8 @@ class CheckerCPU : public BaseCPU, public ExecContext 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 @@ class Checker : public CheckerCPU 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 @@ class Checker : public CheckerCPU } } - 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 57282cd13..4fa59564a 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -124,7 +124,7 @@ Checker::handlePendingInt() template void -Checker::verify(DynInstPtr &completed_inst) +Checker::verify(const DynInstPtr &completed_inst) { DynInstPtr inst; @@ -456,7 +456,7 @@ Checker::takeOverFrom(BaseCPU *oldCPU) template void -Checker::validateInst(DynInstPtr &inst) +Checker::validateInst(const DynInstPtr &inst) { if (inst->instAddr() != thread->instAddr()) { warn("%lli: PCs do not match! Inst: %s, checker: %s", @@ -477,7 +477,7 @@ Checker::validateInst(DynInstPtr &inst) template void -Checker::validateExecution(DynInstPtr &inst) +Checker::validateExecution(const DynInstPtr &inst) { InstResult checker_val; InstResult inst_val; @@ -595,8 +595,8 @@ Checker::validateState() template void -Checker::copyResult(DynInstPtr &inst, const InstResult& mismatch_val, - int start_idx) +Checker::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 @@ Checker::copyResult(DynInstPtr &inst, const InstResult& mismatch_val, template void -Checker::dumpAndExit(DynInstPtr &inst) +Checker::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 59d74146b..bc9b486fe 100644 --- a/src/cpu/exec_context.hh +++ b/src/cpu/exec_context.hh @@ -306,7 +306,7 @@ class ExecContext { * @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 6ac0df5f8..238d11352 100644 --- a/src/cpu/minor/exec_context.hh +++ b/src/cpu/minor/exec_context.hh @@ -292,7 +292,7 @@ class ExecContext : public ::ExecContext } bool - readPredicate() override + readPredicate() const override { return thread.readPredicate(); } diff --git a/src/cpu/o3/commit.hh b/src/cpu/o3/commit.hh index f508a372e..b74917da3 100644 --- a/src/cpu/o3/commit.hh +++ b/src/cpu/o3/commit.hh @@ -282,7 +282,7 @@ class DefaultCommit * @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 @@ class DefaultCommit /** 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 @@ class DefaultCommit 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 d32493cbc..8fd142c08 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -636,7 +636,7 @@ DefaultCommit::squashFromSquashAfter(ThreadID tid) template void -DefaultCommit::squashAfter(ThreadID tid, DynInstPtr &head_inst) +DefaultCommit::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 @@ DefaultCommit::tick() // 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 @@ DefaultCommit::commitInsts() template bool -DefaultCommit::commitHead(DynInstPtr &head_inst, unsigned inst_num) +DefaultCommit::commitHead(const DynInstPtr &head_inst, unsigned inst_num) { assert(head_inst); @@ -1317,9 +1317,7 @@ DefaultCommit::getInsts() 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 @@ DefaultCommit::markCompletedInsts() template void -DefaultCommit::updateComInstStats(DynInstPtr &inst) +DefaultCommit::updateComInstStats(const DynInstPtr &inst) { ThreadID tid = inst->threadNumber; @@ -1507,7 +1505,7 @@ DefaultCommit::oldestReady() 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 c4bc13fb4..2f793453d 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -1564,7 +1564,7 @@ FullO3CPU::squashFromTC(ThreadID tid) template typename FullO3CPU::ListIt -FullO3CPU::addInst(DynInstPtr &inst) +FullO3CPU::addInst(const DynInstPtr &inst) { instList.push_back(inst); @@ -1573,7 +1573,7 @@ FullO3CPU::addInst(DynInstPtr &inst) template void -FullO3CPU::instDone(ThreadID tid, DynInstPtr &inst) +FullO3CPU::instDone(ThreadID tid, const DynInstPtr &inst) { // Keep an instruction count. if (!inst->isMicroop() || inst->isLastMicroop()) { @@ -1595,7 +1595,7 @@ FullO3CPU::instDone(ThreadID tid, DynInstPtr &inst) template void -FullO3CPU::removeFrontInst(DynInstPtr &inst) +FullO3CPU::removeFrontInst(const DynInstPtr &inst) { DPRINTF(O3CPU, "Removing committed instruction [tid:%i] PC %s " "[sn:%lli]\n", @@ -1751,7 +1751,7 @@ FullO3CPU::dumpInsts() /* template void -FullO3CPU::wakeDependents(DynInstPtr &inst) +FullO3CPU::wakeDependents(const DynInstPtr &inst) { iew.wakeDependents(inst); } diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 1589220a9..19b9a34e0 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -537,15 +537,15 @@ class FullO3CPU : public BaseO3CPU /** 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 006219a50..a1e29a6b5 100644 --- a/src/cpu/o3/decode.hh +++ b/src/cpu/o3/decode.hh @@ -194,7 +194,7 @@ class DefaultDecode /** 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 15ec76f5a..51c1b9de1 100644 --- a/src/cpu/o3/decode_impl.hh +++ b/src/cpu/o3/decode_impl.hh @@ -288,7 +288,7 @@ DefaultDecode::unblock(ThreadID tid) template void -DefaultDecode::squash(DynInstPtr &inst, ThreadID tid) +DefaultDecode::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 @@ DefaultDecode::decodeInsts(ThreadID tid) ++decodeRunCycles; } - DynInstPtr inst; - std::queue &insts_to_decode = decodeStatus[tid] == Unblocking ? skidBuffer[tid] : insts[tid]; @@ -661,7 +659,7 @@ DefaultDecode::decodeInsts(ThreadID tid) 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 41ab6e94f..212130e2b 100644 --- a/src/cpu/o3/dep_graph.hh +++ b/src/cpu/o3/dep_graph.hh @@ -89,10 +89,10 @@ class DependencyGraph 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 @@ class DependencyGraph { 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 @@ DependencyGraph::reset() template void -DependencyGraph::insert(PhysRegIndex idx, DynInstPtr &new_inst) +DependencyGraph::insert(PhysRegIndex idx, + const DynInstPtr &new_inst) { //Add this new, dependent instruction at the head of the dependency //chain. @@ -203,7 +204,7 @@ DependencyGraph::insert(PhysRegIndex idx, DynInstPtr &new_inst) template void DependencyGraph::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 da7ba4bb3..28739d2dc 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -281,7 +281,7 @@ class DefaultFetch * @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 2df7b84ee..5810c032f 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -546,7 +546,7 @@ DefaultFetch::deactivateThread(ThreadID tid) template bool DefaultFetch::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 @@ DefaultFetch::tick() 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 de8834005..b15521f5d 100644 --- a/src/cpu/o3/iew.hh +++ b/src/cpu/o3/iew.hh @@ -175,24 +175,24 @@ class DefaultIEW 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 @@ class DefaultIEW 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 @@ class DefaultIEW 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 *timeBuffer; diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index 8270a71b5..e46bc5ba5 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -478,7 +478,7 @@ DefaultIEW::squash(ThreadID tid) template void -DefaultIEW::squashDueToBranch(DynInstPtr &inst, ThreadID tid) +DefaultIEW::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 @@ DefaultIEW::squashDueToBranch(DynInstPtr &inst, ThreadID tid) template void -DefaultIEW::squashDueToMemOrder(DynInstPtr &inst, ThreadID tid) +DefaultIEW::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 @@ DefaultIEW::unblock(ThreadID tid) template void -DefaultIEW::wakeDependents(DynInstPtr &inst) +DefaultIEW::wakeDependents(const DynInstPtr& inst) { instQueue.wakeDependents(inst); } template void -DefaultIEW::rescheduleMemInst(DynInstPtr &inst) +DefaultIEW::rescheduleMemInst(const DynInstPtr& inst) { instQueue.rescheduleMemInst(inst); } template void -DefaultIEW::replayMemInst(DynInstPtr &inst) +DefaultIEW::replayMemInst(const DynInstPtr& inst) { instQueue.replayMemInst(inst); } template void -DefaultIEW::blockMemInst(DynInstPtr& inst) +DefaultIEW::blockMemInst(const DynInstPtr& inst) { instQueue.blockMemInst(inst); } @@ -601,7 +601,7 @@ DefaultIEW::cacheUnblocked() template void -DefaultIEW::instToCommit(DynInstPtr &inst) +DefaultIEW::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 @@ DefaultIEW::tick() template void -DefaultIEW::updateExeInstStats(DynInstPtr &inst) +DefaultIEW::updateExeInstStats(const DynInstPtr& inst) { ThreadID tid = inst->threadNumber; @@ -1610,7 +1610,7 @@ DefaultIEW::updateExeInstStats(DynInstPtr &inst) template void -DefaultIEW::checkMisprediction(DynInstPtr &inst) +DefaultIEW::checkMisprediction(const DynInstPtr& inst) { ThreadID tid = inst->threadNumber; diff --git a/src/cpu/o3/impl.hh b/src/cpu/o3/impl.hh index 8905bdb1c..a0007e542 100644 --- a/src/cpu/o3/impl.hh +++ b/src/cpu/o3/impl.hh @@ -65,6 +65,7 @@ struct O3CPUImpl * what should be used, and not DynInst *. */ typedef RefCountingPtr DynInstPtr; + typedef RefCountingPtr DynInstConstPtr; /** The O3CPU type to be used. */ typedef FullO3CPU O3CPU; diff --git a/src/cpu/o3/inst_queue.hh b/src/cpu/o3/inst_queue.hh index 64f8aa1be..37cc3a2bb 100644 --- a/src/cpu/o3/inst_queue.hh +++ b/src/cpu/o3/inst_queue.hh @@ -113,7 +113,7 @@ class InstructionQueue public: /** Construct a FU completion event. */ - FUCompletion(DynInstPtr &_inst, int fu_idx, + FUCompletion(const DynInstPtr &_inst, int fu_idx, InstructionQueue *iq_ptr); virtual void process(); @@ -176,15 +176,15 @@ class InstructionQueue 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 @@ class InstructionQueue * 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 @@ class InstructionQueue 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 @@ class InstructionQueue std::vector 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 84ac5799c..bc4822ba7 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 -InstructionQueue::FUCompletion::FUCompletion(DynInstPtr &_inst, +InstructionQueue::FUCompletion::FUCompletion(const DynInstPtr &_inst, int fu_idx, InstructionQueue *iq_ptr) : Event(Stat_Event_Pri, AutoDelete), inst(_inst), fuIdx(fu_idx), iqPtr(iq_ptr), freeFU(false) @@ -585,7 +585,7 @@ InstructionQueue::hasReadyInsts() template void -InstructionQueue::insert(DynInstPtr &new_inst) +InstructionQueue::insert(const DynInstPtr &new_inst) { if (new_inst->isFloating()) { fpInstQueueWrites++; @@ -631,7 +631,7 @@ InstructionQueue::insert(DynInstPtr &new_inst) template void -InstructionQueue::insertNonSpec(DynInstPtr &new_inst) +InstructionQueue::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 @@ InstructionQueue::insertNonSpec(DynInstPtr &new_inst) template void -InstructionQueue::insertBarrier(DynInstPtr &barr_inst) +InstructionQueue::insertBarrier(const DynInstPtr &barr_inst) { memDepUnit[barr_inst->threadNumber].insertBarrier(barr_inst); @@ -690,7 +690,7 @@ typename Impl::DynInstPtr InstructionQueue::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 @@ InstructionQueue::moveToYoungerInst(ListOrderIt list_order_it) template void -InstructionQueue::processFUCompletion(DynInstPtr &inst, int fu_idx) +InstructionQueue::processFUCompletion(const DynInstPtr &inst, int fu_idx) { DPRINTF(IQ, "Processing FU completion [sn:%lli]\n", inst->seqNum); assert(!cpu->switchedOut()); @@ -789,12 +789,12 @@ InstructionQueue::scheduleReadyInsts() 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 @@ InstructionQueue::commit(const InstSeqNum &inst, ThreadID tid) template int -InstructionQueue::wakeDependents(DynInstPtr &completed_inst) +InstructionQueue::wakeDependents(const DynInstPtr &completed_inst) { int dependents = 0; @@ -1079,7 +1079,7 @@ InstructionQueue::wakeDependents(DynInstPtr &completed_inst) template void -InstructionQueue::addReadyMemInst(DynInstPtr &ready_inst) +InstructionQueue::addReadyMemInst(const DynInstPtr &ready_inst) { OpClass op_class = ready_inst->opClass(); @@ -1102,7 +1102,7 @@ InstructionQueue::addReadyMemInst(DynInstPtr &ready_inst) template void -InstructionQueue::rescheduleMemInst(DynInstPtr &resched_inst) +InstructionQueue::rescheduleMemInst(const DynInstPtr &resched_inst) { DPRINTF(IQ, "Rescheduling mem inst [sn:%lli]\n", resched_inst->seqNum); @@ -1116,14 +1116,14 @@ InstructionQueue::rescheduleMemInst(DynInstPtr &resched_inst) template void -InstructionQueue::replayMemInst(DynInstPtr &replay_inst) +InstructionQueue::replayMemInst(const DynInstPtr &replay_inst) { memDepUnit[replay_inst->threadNumber].replay(); } template void -InstructionQueue::completeMemInst(DynInstPtr &completed_inst) +InstructionQueue::completeMemInst(const DynInstPtr &completed_inst) { ThreadID tid = completed_inst->threadNumber; @@ -1140,14 +1140,14 @@ InstructionQueue::completeMemInst(DynInstPtr &completed_inst) template void -InstructionQueue::deferMemInst(DynInstPtr &deferred_inst) +InstructionQueue::deferMemInst(const DynInstPtr &deferred_inst) { deferredMemInsts.push_back(deferred_inst); } template void -InstructionQueue::blockMemInst(DynInstPtr &blocked_inst) +InstructionQueue::blockMemInst(const DynInstPtr &blocked_inst) { blocked_inst->translationStarted(false); blocked_inst->translationCompleted(false); @@ -1173,7 +1173,7 @@ InstructionQueue::getDeferredMemInstToExecute() 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 @@ InstructionQueue::getBlockedMemInstToExecute() 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 @@ InstructionQueue::getBlockedMemInstToExecute() template void -InstructionQueue::violation(DynInstPtr &store, - DynInstPtr &faulting_load) +InstructionQueue::violation(const DynInstPtr &store, + const DynInstPtr &faulting_load) { intInstQueueWrites++; memDepUnit[store->threadNumber].violation(store, faulting_load); @@ -1364,7 +1364,7 @@ InstructionQueue::doSquash(ThreadID tid) template bool -InstructionQueue::addToDependents(DynInstPtr &new_inst) +InstructionQueue::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 @@ InstructionQueue::addToDependents(DynInstPtr &new_inst) template void -InstructionQueue::addToProducers(DynInstPtr &new_inst) +InstructionQueue::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 @@ InstructionQueue::addToProducers(DynInstPtr &new_inst) template void -InstructionQueue::addIfReady(DynInstPtr &inst) +InstructionQueue::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 7c78156d5..175821e69 100644 --- a/src/cpu/o3/lsq.hh +++ b/src/cpu/o3/lsq.hh @@ -106,15 +106,15 @@ class LSQ { { 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 56b95a5b6..967a496f6 100644 --- a/src/cpu/o3/lsq_impl.hh +++ b/src/cpu/o3/lsq_impl.hh @@ -257,7 +257,7 @@ LSQ::tick() template void -LSQ::insertLoad(DynInstPtr &load_inst) +LSQ::insertLoad(const DynInstPtr &load_inst) { ThreadID tid = load_inst->threadNumber; @@ -266,7 +266,7 @@ LSQ::insertLoad(DynInstPtr &load_inst) template void -LSQ::insertStore(DynInstPtr &store_inst) +LSQ::insertStore(const DynInstPtr &store_inst) { ThreadID tid = store_inst->threadNumber; @@ -275,7 +275,7 @@ LSQ::insertStore(DynInstPtr &store_inst) template Fault -LSQ::executeLoad(DynInstPtr &inst) +LSQ::executeLoad(const DynInstPtr &inst) { ThreadID tid = inst->threadNumber; @@ -284,7 +284,7 @@ LSQ::executeLoad(DynInstPtr &inst) template Fault -LSQ::executeStore(DynInstPtr &inst) +LSQ::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 f5b60b2fc..813a3cac7 100644 --- a/src/cpu/o3/lsq_unit.hh +++ b/src/cpu/o3/lsq_unit.hh @@ -116,11 +116,11 @@ class LSQUnit { 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 @@ class LSQUnit { * @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 @@ class LSQUnit { 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 @@ class LSQUnit { 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 LSQUnit { 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 @@ class LSQUnit { } /** 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 c2750be7d..d8f1c39c6 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 -LSQUnit::WritebackEvent::WritebackEvent(DynInstPtr &_inst, PacketPtr _pkt, - LSQUnit *lsq_ptr) +LSQUnit::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 @@ LSQUnit::resizeSQ(unsigned size) template void -LSQUnit::insert(DynInstPtr &inst) +LSQUnit::insert(const DynInstPtr &inst) { assert(inst->isMemRef()); @@ -356,7 +356,7 @@ LSQUnit::insert(DynInstPtr &inst) template void -LSQUnit::insertLoad(DynInstPtr &load_inst) +LSQUnit::insertLoad(const DynInstPtr &load_inst) { assert((loadTail + 1) % LQEntries != loadHead); assert(loads < LQEntries); @@ -381,7 +381,7 @@ LSQUnit::insertLoad(DynInstPtr &load_inst) template void -LSQUnit::insertStore(DynInstPtr &store_inst) +LSQUnit::insertStore(const DynInstPtr &store_inst) { // Make sure it is not full before inserting an instruction. assert((storeTail + 1) % SQEntries != storeHead); @@ -525,7 +525,7 @@ LSQUnit::checkSnoop(PacketPtr pkt) template Fault -LSQUnit::checkViolations(int load_idx, DynInstPtr &inst) +LSQUnit::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 @@ LSQUnit::checkViolations(int load_idx, DynInstPtr &inst) template Fault -LSQUnit::executeLoad(DynInstPtr &inst) +LSQUnit::executeLoad(const DynInstPtr &inst) { using namespace TheISA; // Execute a specific load. @@ -654,7 +654,7 @@ LSQUnit::executeLoad(DynInstPtr &inst) template Fault -LSQUnit::executeStore(DynInstPtr &store_inst) +LSQUnit::executeStore(const DynInstPtr &store_inst) { using namespace TheISA; // Make sure that a store exists. @@ -1105,7 +1105,7 @@ LSQUnit::storePostSend(PacketPtr pkt) template void -LSQUnit::writeback(DynInstPtr &inst, PacketPtr pkt) +LSQUnit::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 ffe66be6b..24f5c20ee 100644 --- a/src/cpu/o3/mem_dep_unit.hh +++ b/src/cpu/o3/mem_dep_unit.hh @@ -85,6 +85,7 @@ class MemDepUnit 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 @@ class MemDepUnit void setIQ(InstructionQueue *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 @@ class MemDepUnit 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 @@ class MemDepUnit 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 MemDepUnit 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 @@ class MemDepUnit }; /** 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 376198fc1..26c4b4d6e 100644 --- a/src/cpu/o3/mem_dep_unit_impl.hh +++ b/src/cpu/o3/mem_dep_unit_impl.hh @@ -171,7 +171,7 @@ MemDepUnit::setIQ(InstructionQueue *iq_ptr) template void -MemDepUnit::insert(DynInstPtr &inst) +MemDepUnit::insert(const DynInstPtr &inst) { ThreadID tid = inst->threadNumber; @@ -268,7 +268,7 @@ MemDepUnit::insert(DynInstPtr &inst) template void -MemDepUnit::insertNonSpec(DynInstPtr &inst) +MemDepUnit::insertNonSpec(const DynInstPtr &inst) { ThreadID tid = inst->threadNumber; @@ -304,7 +304,7 @@ MemDepUnit::insertNonSpec(DynInstPtr &inst) template void -MemDepUnit::insertBarrier(DynInstPtr &barr_inst) +MemDepUnit::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 @@ MemDepUnit::insertBarrier(DynInstPtr &barr_inst) template void -MemDepUnit::regsReady(DynInstPtr &inst) +MemDepUnit::regsReady(const DynInstPtr &inst) { DPRINTF(MemDepUnit, "Marking registers as ready for " "instruction PC %s [sn:%lli].\n", @@ -363,7 +363,7 @@ MemDepUnit::regsReady(DynInstPtr &inst) template void -MemDepUnit::nonSpecInstReady(DynInstPtr &inst) +MemDepUnit::nonSpecInstReady(const DynInstPtr &inst) { DPRINTF(MemDepUnit, "Marking non speculative " "instruction PC %s as ready [sn:%lli].\n", @@ -376,7 +376,7 @@ MemDepUnit::nonSpecInstReady(DynInstPtr &inst) template void -MemDepUnit::reschedule(DynInstPtr &inst) +MemDepUnit::reschedule(const DynInstPtr &inst) { instsToReplay.push_back(inst); } @@ -404,7 +404,7 @@ MemDepUnit::replay() template void -MemDepUnit::completed(DynInstPtr &inst) +MemDepUnit::completed(const DynInstPtr &inst) { DPRINTF(MemDepUnit, "Completed mem instruction PC %s [sn:%lli].\n", inst->pcState(), inst->seqNum); @@ -428,7 +428,7 @@ MemDepUnit::completed(DynInstPtr &inst) template void -MemDepUnit::completeBarrier(DynInstPtr &inst) +MemDepUnit::completeBarrier(const DynInstPtr &inst) { wakeDependents(inst); completed(inst); @@ -449,7 +449,7 @@ MemDepUnit::completeBarrier(DynInstPtr &inst) template void -MemDepUnit::wakeDependents(DynInstPtr &inst) +MemDepUnit::wakeDependents(const DynInstPtr &inst) { // Only stores and barriers have dependents. if (!inst->isStore() && !inst->isMemBarrier() && !inst->isWriteBarrier()) { @@ -536,8 +536,8 @@ MemDepUnit::squash(const InstSeqNum &squashed_num, template void -MemDepUnit::violation(DynInstPtr &store_inst, - DynInstPtr &violating_load) +MemDepUnit::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 @@ MemDepUnit::violation(DynInstPtr &store_inst, template void -MemDepUnit::issue(DynInstPtr &inst) +MemDepUnit::issue(const DynInstPtr &inst) { DPRINTF(MemDepUnit, "Issuing instruction PC %#x [sn:%lli].\n", inst->instAddr(), inst->seqNum); @@ -558,7 +558,7 @@ MemDepUnit::issue(DynInstPtr &inst) template inline typename MemDepUnit::MemDepEntryPtr & -MemDepUnit::findInHash(const DynInstPtr &inst) +MemDepUnit::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 508140e0c..a4a201398 100644 --- a/src/cpu/o3/probe/elastic_trace.cc +++ b/src/cpu/o3/probe/elastic_trace.cc @@ -124,18 +124,23 @@ ElasticTrace::regEtraceListeners() // each probe point. listeners.push_back(new ProbeListenerArg(this, "FetchRequest", &ElasticTrace::fetchReqTrace)); - listeners.push_back(new ProbeListenerArg(this, - "Execute", &ElasticTrace::recordExecTick)); - listeners.push_back(new ProbeListenerArg(this, - "ToCommit", &ElasticTrace::recordToCommTick)); - listeners.push_back(new ProbeListenerArg(this, - "Rename", &ElasticTrace::updateRegDep)); + listeners.push_back(new ProbeListenerArg(this, "Execute", + &ElasticTrace::recordExecTick)); + listeners.push_back(new ProbeListenerArg(this, "ToCommit", + &ElasticTrace::recordToCommTick)); + listeners.push_back(new ProbeListenerArg(this, "Rename", + &ElasticTrace::updateRegDep)); listeners.push_back(new ProbeListenerArg(this, "SquashInRename", &ElasticTrace::removeRegDepMapEntry)); - listeners.push_back(new ProbeListenerArg(this, - "Squash", &ElasticTrace::addSquashedInst)); - listeners.push_back(new ProbeListenerArg(this, - "Commit", &ElasticTrace::addCommittedInst)); + listeners.push_back(new ProbeListenerArg(this, "Squash", + &ElasticTrace::addSquashedInst)); + listeners.push_back(new ProbeListenerArg(this, "Commit", + &ElasticTrace::addCommittedInst)); allProbesReg = true; } @@ -162,7 +167,7 @@ ElasticTrace::fetchReqTrace(const RequestPtr &req) } 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 @@ ElasticTrace::recordExecTick(const DynInstPtr &dyn_inst) } 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 @@ ElasticTrace::recordToCommTick(const DynInstPtr &dyn_inst) } 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 @@ ElasticTrace::removeRegDepMapEntry(const SeqNumRegPair &inst_reg_pair) } 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 @@ ElasticTrace::addSquashedInst(const DynInstPtr &head_inst) } 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 @@ ElasticTrace::addCommittedInst(const DynInstPtr &head_inst) } 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 @@ ElasticTrace::hasCompCompleted(TraceInfo* past_record, } 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 08e02daef..21029b94c 100644 --- a/src/cpu/o3/probe/elastic_trace.hh +++ b/src/cpu/o3/probe/elastic_trace.hh @@ -90,6 +90,7 @@ class ElasticTrace : public ProbeListenerObject public: typedef typename O3CPUImpl::DynInstPtr DynInstPtr; + typedef typename O3CPUImpl::DynInstConstPtr DynInstConstPtr; typedef typename std::pair SeqNumRegPair; /** Trace record types corresponding to instruction node types */ @@ -132,7 +133,7 @@ class ElasticTrace : public ProbeListenerObject * * @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 @@ class ElasticTrace : public ProbeListenerObject * * @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 @@ class ElasticTrace : public ProbeListenerObject * * @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 @@ class ElasticTrace : public ProbeListenerObject * * @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 @@ class ElasticTrace : public ProbeListenerObject * @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 @@ class ElasticTrace : public ProbeListenerObject * * @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 060b4df13..4c7b676b4 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::traceFetch(const O3CPUImpl::DynInstPtr &dynInst) void SimpleTrace::regProbeListeners() { - typedef ProbeListenerArg DynInstListener; - listeners.push_back(new DynInstListener(this, "Commit", &SimpleTrace::traceCommit)); - listeners.push_back(new DynInstListener(this, "Fetch", &SimpleTrace::traceFetch)); + typedef ProbeListenerArg 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 663128810..928062eaa 100644 --- a/src/cpu/o3/probe/simple_trace.hh +++ b/src/cpu/o3/probe/simple_trace.hh @@ -66,8 +66,8 @@ class SimpleTrace : public ProbeListenerObject { 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 d0f6ba13d..bd5e72dec 100644 --- a/src/cpu/o3/rename.hh +++ b/src/cpu/o3/rename.hh @@ -252,10 +252,10 @@ class DefaultRename 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 bc024f603..a295a8705 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -524,8 +524,6 @@ DefaultRename::renameInsts(ThreadID tid) ++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 @@ DefaultRename::renameInsts(ThreadID tid) 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 @@ DefaultRename::sortInsts() { 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 @@ DefaultRename::removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid) template inline void -DefaultRename::renameSrcRegs(DynInstPtr &inst, ThreadID tid) +DefaultRename::renameSrcRegs(const DynInstPtr &inst, ThreadID tid) { ThreadContext *tc = inst->tcBase(); RenameMap *map = renameMap[tid]; @@ -1068,7 +1066,7 @@ DefaultRename::renameSrcRegs(DynInstPtr &inst, ThreadID tid) template inline void -DefaultRename::renameDestRegs(DynInstPtr &inst, ThreadID tid) +DefaultRename::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 1c3cc2815..1896e62a4 100644 --- a/src/cpu/o3/rob.hh +++ b/src/cpu/o3/rob.hh @@ -114,7 +114,7 @@ class ROB * 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 @@ class ROB * 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 5a9dc90f9..223f94caa 100644 --- a/src/cpu/o3/rob_impl.hh +++ b/src/cpu/o3/rob_impl.hh @@ -209,7 +209,7 @@ ROB::countInsts(ThreadID tid) template void -ROB::insertInst(DynInstPtr &inst) +ROB::insertInst(const DynInstPtr &inst) { assert(inst); @@ -252,10 +252,11 @@ ROB::retireHead(ThreadID tid) 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 @@ ROB::retireHead(ThreadID tid) head_inst->clearInROB(); head_inst->setCommitted(); - instList[tid].erase(head_it); - //Update "Global" Head of ROB updateHead(); @@ -513,7 +512,7 @@ ROB::squash(InstSeqNum squash_num, ThreadID tid) } template -typename Impl::DynInstPtr +const typename Impl::DynInstPtr& ROB::readHeadInst(ThreadID tid) { if (threadEntries[tid] != 0) { diff --git a/src/cpu/simple/exec_context.hh b/src/cpu/simple/exec_context.hh index 13c44ac22..8ff18dd60 100644 --- a/src/cpu/simple/exec_context.hh +++ b/src/cpu/simple/exec_context.hh @@ -482,7 +482,7 @@ class SimpleExecContext : public ExecContext { return thread->simPalCheck(palFunc); } - bool readPredicate() override + bool readPredicate() const override { return thread->readPredicate(); } -- cgit v1.2.3