/*
+ * 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.
*
#ifndef __BASE_REFCNT_HH__
#define __BASE_REFCNT_HH__
+#include <type_traits>
+
/**
* @file base/refcnt.hh
*
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; }
};
/**
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;
/// 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(); }
/// 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; }
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; }
/**Read the micro PC of this instruction. */
Addr microPC() const { return pc.microPC(); }
- bool readPredicate()
+ bool readPredicate() const
{
return instFlags[Predicate];
}
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; }
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
setVecElemResult(val);
}
- bool readPredicate() override { return thread->readPredicate(); }
+ bool readPredicate() const override { return thread->readPredicate(); }
+
void setPredicate(bool val) override
{
thread->setPredicate(val);
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);
}
}
- void dumpAndExit(DynInstPtr &inst);
+ void dumpAndExit(const DynInstPtr &inst);
bool updateThisCycle;
template <class Impl>
void
-Checker<Impl>::verify(DynInstPtr &completed_inst)
+Checker<Impl>::verify(const DynInstPtr &completed_inst)
{
DynInstPtr inst;
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",
template <class Impl>
void
-Checker<Impl>::validateExecution(DynInstPtr &inst)
+Checker<Impl>::validateExecution(const DynInstPtr &inst)
{
InstResult checker_val;
InstResult inst_val;
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;
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"
* @name ARM-Specific Interfaces
*/
- virtual bool readPredicate() = 0;
+ virtual bool readPredicate() const = 0;
virtual void setPredicate(bool val) = 0;
/** @} */
}
bool
- readPredicate() override
+ readPredicate() const override
{
return thread.readPredicate();
}
* @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();
/** 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();
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.
*/
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);
// 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);
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);
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() &&
template <class Impl>
void
-DefaultCommit<Impl>::updateComInstStats(DynInstPtr &inst)
+DefaultCommit<Impl>::updateComInstStats(const DynInstPtr &inst)
{
ThreadID tid = inst->threadNumber;
if (rob->isHeadReady(tid)) {
- DynInstPtr head_inst = rob->readHeadInst(tid);
+ const DynInstPtr &head_inst = rob->readHeadInst(tid);
if (first) {
oldest = tid;
template <class Impl>
typename FullO3CPU<Impl>::ListIt
-FullO3CPU<Impl>::addInst(DynInstPtr &inst)
+FullO3CPU<Impl>::addInst(const DynInstPtr &inst)
{
instList.push_back(inst);
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()) {
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",
/*
template <class Impl>
void
-FullO3CPU<Impl>::wakeDependents(DynInstPtr &inst)
+FullO3CPU<Impl>::wakeDependents(const DynInstPtr &inst)
{
iew.wakeDependents(inst);
}
/** 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.*/
/** 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
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);
++decodeRunCycles;
}
- DynInstPtr inst;
-
std::queue<DynInstPtr>
&insts_to_decode = decodeStatus[tid] == Unblocking ?
skidBuffer[tid] : insts[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();
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. */
{ 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);
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.
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;
* @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
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
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",
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);
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);
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;
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);
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);
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);
}
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
template <class Impl>
void
-DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst)
+DefaultIEW<Impl>::updateExeInstStats(const DynInstPtr& inst)
{
ThreadID tid = inst->threadNumber;
template <class Impl>
void
-DefaultIEW<Impl>::checkMisprediction(DynInstPtr &inst)
+DefaultIEW<Impl>::checkMisprediction(const DynInstPtr& inst)
{
ThreadID tid = inst->threadNumber;
* 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;
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();
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.
* 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
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
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
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)
template <class Impl>
void
-InstructionQueue<Impl>::insert(DynInstPtr &new_inst)
+InstructionQueue<Impl>::insert(const DynInstPtr &new_inst)
{
if (new_inst->isFloating()) {
fpInstQueueWrites++;
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.
template <class Impl>
void
-InstructionQueue<Impl>::insertBarrier(DynInstPtr &barr_inst)
+InstructionQueue<Impl>::insertBarrier(const DynInstPtr &barr_inst)
{
memDepUnit[barr_inst->threadNumber].insertBarrier(barr_inst);
InstructionQueue<Impl>::getInstToExecute()
{
assert(!instsToExecute.empty());
- DynInstPtr inst = instsToExecute.front();
+ DynInstPtr inst = std::move(instsToExecute.front());
instsToExecute.pop_front();
if (inst->isFloating()) {
fpInstQueueReads++;
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());
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);
}
template <class Impl>
int
-InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
+InstructionQueue<Impl>::wakeDependents(const DynInstPtr &completed_inst)
{
int dependents = 0;
template <class Impl>
void
-InstructionQueue<Impl>::addReadyMemInst(DynInstPtr &ready_inst)
+InstructionQueue<Impl>::addReadyMemInst(const DynInstPtr &ready_inst)
{
OpClass op_class = ready_inst->opClass();
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);
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;
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);
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;
}
if (retryMemInsts.empty()) {
return nullptr;
} else {
- DynInstPtr mem_inst = retryMemInsts.front();
+ DynInstPtr mem_inst = std::move(retryMemInsts.front());
retryMemInsts.pop_front();
return mem_inst;
}
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);
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.
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
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.
{ 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.
template<class Impl>
void
-LSQ<Impl>::insertLoad(DynInstPtr &load_inst)
+LSQ<Impl>::insertLoad(const DynInstPtr &load_inst)
{
ThreadID tid = load_inst->threadNumber;
template<class Impl>
void
-LSQ<Impl>::insertStore(DynInstPtr &store_inst)
+LSQ<Impl>::insertStore(const DynInstPtr &store_inst)
{
ThreadID tid = store_inst->threadNumber;
template<class Impl>
Fault
-LSQ<Impl>::executeLoad(DynInstPtr &inst)
+LSQ<Impl>::executeLoad(const DynInstPtr &inst)
{
ThreadID tid = inst->threadNumber;
template<class Impl>
Fault
-LSQ<Impl>::executeStore(DynInstPtr &inst)
+LSQ<Impl>::executeStore(const DynInstPtr &inst)
{
ThreadID tid = inst->threadNumber;
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
* @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
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();
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();
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();
}
/** 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)
{
#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)
{
template <class Impl>
void
-LSQUnit<Impl>::insert(DynInstPtr &inst)
+LSQUnit<Impl>::insert(const DynInstPtr &inst)
{
assert(inst->isMemRef());
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);
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);
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;
template <class Impl>
Fault
-LSQUnit<Impl>::executeLoad(DynInstPtr &inst)
+LSQUnit<Impl>::executeLoad(const DynInstPtr &inst)
{
using namespace TheISA;
// Execute a specific load.
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.
template <class Impl>
void
-LSQUnit<Impl>::writeback(DynInstPtr &inst, PacketPtr pkt)
+LSQUnit<Impl>::writeback(const DynInstPtr &inst, PacketPtr pkt)
{
iewStage->wakeCPU();
public:
typedef typename Impl::DynInstPtr DynInstPtr;
+ typedef typename Impl::DynInstConstPtr DynInstConstPtr;
/** Empty constructor. Must call init() prior to using in this case. */
MemDepUnit();
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.
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.
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();
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)
{
};
/** 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);
template <class MemDepPred, class Impl>
void
-MemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst)
+MemDepUnit<MemDepPred, Impl>::insert(const DynInstPtr &inst)
{
ThreadID tid = inst->threadNumber;
template <class MemDepPred, class Impl>
void
-MemDepUnit<MemDepPred, Impl>::insertNonSpec(DynInstPtr &inst)
+MemDepUnit<MemDepPred, Impl>::insertNonSpec(const DynInstPtr &inst)
{
ThreadID tid = inst->threadNumber;
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.
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",
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",
template <class MemDepPred, class Impl>
void
-MemDepUnit<MemDepPred, Impl>::reschedule(DynInstPtr &inst)
+MemDepUnit<MemDepPred, Impl>::reschedule(const DynInstPtr &inst)
{
instsToReplay.push_back(inst);
}
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);
template <class MemDepPred, class Impl>
void
-MemDepUnit<MemDepPred, Impl>::completeBarrier(DynInstPtr &inst)
+MemDepUnit<MemDepPred, Impl>::completeBarrier(const DynInstPtr &inst)
{
wakeDependents(inst);
completed(inst);
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()) {
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(),
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);
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);
// 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;
}
}
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
}
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
}
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;
}
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
}
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);
}
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.
}
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
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 */
*
* @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
*
* @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
*
* @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
*
* @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();
* @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);
/**
*
* @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
#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(),
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*
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__
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);
++renameRunCycles;
}
- DynInstPtr inst;
-
// Will have to do a different calculation for the number of free
// entries.
int free_rob_entries = calcFreeROBEntries(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
{
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)) {
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];
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];
* 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.
* 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.
template <class Impl>
void
-ROB<Impl>::insertInst(DynInstPtr &inst)
+ROB<Impl>::insertInst(const DynInstPtr &inst)
{
assert(inst);
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());
head_inst->clearInROB();
head_inst->setCommitted();
- instList[tid].erase(head_it);
-
//Update "Global" Head of ROB
updateHead();
}
template <class Impl>
-typename Impl::DynInstPtr
+const typename Impl::DynInstPtr&
ROB<Impl>::readHeadInst(ThreadID tid)
{
if (threadEntries[tid] != 0) {
return thread->simPalCheck(palFunc);
}
- bool readPredicate() override
+ bool readPredicate() const override
{
return thread->readPredicate();
}