2c2
< * Copyright (c) 2004-2006 The Regents of The University of Michigan
---
> * Copyright (c) 2004-2005 The Regents of The University of Michigan
26a27,28
> *
> * Authors: Kevin Lim
29,30c31,34
< #ifndef __CPU_O3_RENAME_HH__
< #define __CPU_O3_RENAME_HH__
---
> // Todo:
> // Fix up trap and barrier handling.
> // May want to have different statuses to differentiate the different stall
> // conditions.
31a36,38
> #ifndef __CPU_O3_CPU_SIMPLE_RENAME_HH__
> #define __CPU_O3_CPU_SIMPLE_RENAME_HH__
>
37,48c44,45
< /**
< * DefaultRename handles both single threaded and SMT rename. Its
< * width is specified by the parameters; each cycle it tries to rename
< * that many instructions. It holds onto the rename history of all
< * instructions with destination registers, storing the
< * arch. register, the new physical register, and the old physical
< * register, to allow for undoing of mappings if squashing happens, or
< * freeing up registers upon commit. Rename handles blocking if the
< * ROB, IQ, or LSQ is going to be full. Rename also handles barriers,
< * and does so by stalling on the instruction until the ROB is empty
< * and there are no instructions in flight to the ROB.
< */
---
> // Will need rename maps for both the int reg file and fp reg file.
> // Or change rename map class to handle both. (RegFile handles both.)
50c47
< class DefaultRename
---
> class SimpleRename
59c56
< // Typedefs from the CPUPol
---
> typedef typename CPUPol::FetchStruct FetchStruct;
62a60,61
>
> // Typedefs from the CPUPol
65,67d63
< // These are used only for initialization.
< typedef typename CPUPol::IEW IEW;
< typedef typename CPUPol::Commit Commit;
72,77d67
< // A list is used to queue the instructions. Barrier insts must
< // be added to the front of the list, which is the only reason for
< // using a list instead of a queue. (Most other stages use a
< // queue)
< typedef std::list<DynInstPtr> InstQueue;
<
79,88c69,72
< /** Overall rename status. Used to determine if the CPU can
< * deschedule itself due to a lack of activity.
< */
< enum RenameStatus {
< Active,
< Inactive
< };
<
< /** Individual thread status. */
< enum ThreadStatus {
---
> // Rename will block if ROB becomes full or issue queue becomes full,
> // or there are no free registers to rename to.
> // Only case where rename squashes is if IEW squashes.
> enum Status {
91d74
< StartSquash,
95c78
< SerializeStall
---
> BarrierStall
99,100c82
< /** Rename status. */
< RenameStatus _status;
---
> Status _status;
102,104d83
< /** Per-thread status. */
< ThreadStatus renameStatus[Impl::MaxThreads];
<
106,107c85
< /** DefaultRename constructor. */
< DefaultRename(Params *params);
---
> SimpleRename(Params &params);
109,112d86
< /** Returns the name of rename. */
< std::string name() const;
<
< /** Registers statistics. */
115d88
< /** Sets CPU pointer. */
118d90
< /** Sets the main backwards communication time buffer pointer. */
121d92
< /** Sets pointer to time buffer used to communicate to the next stage. */
124d94
< /** Sets pointer to time buffer coming from decode. */
127,129c97
< /** Sets pointer to IEW stage. Used only for initialization. */
< void setIEWStage(IEW *iew_stage)
< { iew_ptr = iew_stage; }
---
> void setRenameMap(RenameMap *rm_ptr);
131,152d98
< /** Sets pointer to commit stage. Used only for initialization. */
< void setCommitStage(Commit *commit_stage)
< { commit_ptr = commit_stage; }
<
< private:
< /** Pointer to IEW stage. Used only for initialization. */
< IEW *iew_ptr;
<
< /** Pointer to commit stage. Used only for initialization. */
< Commit *commit_ptr;
<
< public:
< /** Initializes variables for the stage. */
< void initStage();
<
< /** Sets pointer to list of active threads. */
< void setActiveThreads(std::list<unsigned> *at_ptr);
<
< /** Sets pointer to rename maps (per-thread structures). */
< void setRenameMap(RenameMap rm_ptr[Impl::MaxThreads]);
<
< /** Sets pointer to the free list. */
155,156c101
< /** Sets pointer to the scoreboard. */
< void setScoreboard(Scoreboard *_scoreboard);
---
> void dumpHistory();
158,169d102
< void switchOut();
<
< void doSwitchOut();
<
< void takeOverFrom();
<
< /** Squashes all instructions in a thread. */
< void squash(unsigned tid);
<
< /** Ticks rename, which processes all input signals and attempts to rename
< * as many instructions as possible.
< */
172,173c105
< /** Debugging function used to dump history buffer of renamings. */
< void dumpHistory();
---
> void rename();
174a107,108
> void squash();
>
176,181c110
< /** Determines what to do based on rename's current status.
< * @param status_change rename() sets this variable if there was a status
< * change (ie switching from blocking to unblocking).
< * @param tid Thread id to rename instructions from.
< */
< void rename(bool &status_change, unsigned tid);
---
> void block();
183,186c112
< /** Renames instructions for the given thread. Also handles serializing
< * instructions.
< */
< void renameInsts(unsigned tid);
---
> inline void unblock();
188,191c114
< /** Inserts unused instructions from a given thread into the skid buffer,
< * to be renamed once rename unblocks.
< */
< void skidInsert(unsigned tid);
---
> void doSquash();
193,196c116
< /** Separates instructions from decode into individual lists of instructions
< * sorted by thread.
< */
< void sortInsts();
---
> void removeFromHistory(InstSeqNum inst_seq_num);
198,199c118
< /** Returns if all of the skid buffers are empty. */
< bool skidsEmpty();
---
> inline void renameSrcRegs(DynInstPtr &inst);
201,202c120
< /** Updates overall rename status based on all of the threads' statuses. */
< void updateStatus();
---
> inline void renameDestRegs(DynInstPtr &inst);
204,208c122
< /** Switches rename to blocking, and signals back that rename has become
< * blocked.
< * @return Returns true if there is a status change.
< */
< bool block(unsigned tid);
---
> inline int calcFreeROBEntries();
210,214c124
< /** Switches rename to unblocking if the skid buffer is empty, and signals
< * back that rename has unblocked.
< * @return Returns true if there is a status change.
< */
< bool unblock(unsigned tid);
---
> inline int calcFreeIQEntries();
216,255c126,128
< /** Executes actual squash, removing squashed instructions. */
< void doSquash(unsigned tid);
<
< /** Removes a committed instruction's rename history. */
< void removeFromHistory(InstSeqNum inst_seq_num, unsigned tid);
<
< /** Renames the source registers of an instruction. */
< inline void renameSrcRegs(DynInstPtr &inst, unsigned tid);
<
< /** Renames the destination registers of an instruction. */
< inline void renameDestRegs(DynInstPtr &inst, unsigned tid);
<
< /** Calculates the number of free ROB entries for a specific thread. */
< inline int calcFreeROBEntries(unsigned tid);
<
< /** Calculates the number of free IQ entries for a specific thread. */
< inline int calcFreeIQEntries(unsigned tid);
<
< /** Calculates the number of free LSQ entries for a specific thread. */
< inline int calcFreeLSQEntries(unsigned tid);
<
< /** Returns the number of valid instructions coming from decode. */
< unsigned validInsts();
<
< /** Reads signals telling rename to block/unblock. */
< void readStallSignals(unsigned tid);
<
< /** Checks if any stages are telling rename to block. */
< bool checkStall(unsigned tid);
<
< void readFreeEntries(unsigned tid);
<
< bool checkSignalsAndUpdate(unsigned tid);
<
< /** Either serializes on the next instruction available in the InstQueue,
< * or records that it must serialize on the next instruction to enter
< * rename.
< * @param inst_list The list of younger, unprocessed instructions for the
< * thread that has the serializeAfter instruction.
< * @param tid The thread id.
---
> /** Holds the previous information for each rename.
> * Note that often times the inst may have been deleted, so only access
> * the pointer for the address and do not dereference it.
257,262d129
< void serializeAfter(InstQueue &inst_list, unsigned tid);
<
< /** Holds the information for each destination register rename. It holds
< * the instruction's sequence number, the arch register, the old physical
< * register for that arch. register, and the new physical register.
< */
267c134,135
< newPhysReg(_newPhysReg), prevPhysReg(_prevPhysReg)
---
> newPhysReg(_newPhysReg), prevPhysReg(_prevPhysReg),
> placeHolder(false)
271c139,147
< /** The sequence number of the instruction that renamed. */
---
> /** Constructor used specifically for cases where a place holder
> * rename history entry is being made.
> */
> RenameHistory(InstSeqNum _instSeqNum)
> : instSeqNum(_instSeqNum), archReg(0), newPhysReg(0),
> prevPhysReg(0), placeHolder(true)
> {
> }
>
273d148
< /** The architectural register index that was renamed. */
275d149
< /** The new physical register that the arch. register is renamed to. */
277d150
< /** The old physical register that the arch. register was renamed to. */
278a152
> bool placeHolder;
281,284c155
< /** A per-thread list of all destination register renames, used to either
< * undo rename mappings or free old physical registers.
< */
< std::list<RenameHistory> historyBuffer[Impl::MaxThreads];
---
> std::list<RenameHistory> historyBuffer;
286c157
< /** Pointer to CPU. */
---
> /** CPU interface. */
289c160,161
< /** Pointer to main time buffer used for backwards communication. */
---
> // Interfaces to objects outside of rename.
> /** Time buffer interface. */
298a171
> // Might not be the best name as not only decode will read it.
313,315d185
< /** Queue of all instructions coming from decode this cycle. */
< InstQueue insts[Impl::MaxThreads];
<
317c187
< InstQueue skidBuffer[Impl::MaxThreads];
---
> std::queue<DecodeStruct> skidBuffer;
320c190
< RenameMap *renameMap[Impl::MaxThreads];
---
> SimpleRenameMap *renameMap;
325,377d194
< /** Pointer to the list of active threads. */
< std::list<unsigned> *activeThreads;
<
< /** Pointer to the scoreboard. */
< Scoreboard *scoreboard;
<
< /** Count of instructions in progress that have been sent off to the IQ
< * and ROB, but are not yet included in their occupancy counts.
< */
< int instsInProgress[Impl::MaxThreads];
<
< /** Variable that tracks if decode has written to the time buffer this
< * cycle. Used to tell CPU if there is activity this cycle.
< */
< bool wroteToTimeBuffer;
<
< /** Structures whose free entries impact the amount of instructions that
< * can be renamed.
< */
< struct FreeEntries {
< unsigned iqEntries;
< unsigned lsqEntries;
< unsigned robEntries;
< };
<
< /** Per-thread tracking of the number of free entries of back-end
< * structures.
< */
< FreeEntries freeEntries[Impl::MaxThreads];
<
< /** Records if the ROB is empty. In SMT mode the ROB may be dynamically
< * partitioned between threads, so the ROB must tell rename when it is
< * empty.
< */
< bool emptyROB[Impl::MaxThreads];
<
< /** Source of possible stalls. */
< struct Stalls {
< bool iew;
< bool commit;
< };
<
< /** Tracks which stages are telling decode to stall. */
< Stalls stalls[Impl::MaxThreads];
<
< /** The serialize instruction that rename has stalled on. */
< DynInstPtr serializeInst[Impl::MaxThreads];
<
< /** Records if rename needs to serialize on the next instruction for any
< * thread.
< */
< bool serializeOnNextInst[Impl::MaxThreads];
<
395,396c212,214
< /** The index of the instruction in the time buffer to IEW that rename is
< * currently using.
---
> /** The instruction that rename is currently on. It needs to have
> * persistent state so that when a stall occurs in the middle of a
> * group of instructions, it can restart at the proper instruction.
398c216
< unsigned toIEWIndex;
---
> unsigned numInst;
400,424d217
< /** Whether or not rename needs to block this cycle. */
< bool blockThisCycle;
<
< /** The number of threads active in rename. */
< unsigned numThreads;
<
< /** The maximum skid buffer size. */
< unsigned skidBufferMax;
<
< /** Enum to record the source of a structure full stall. Can come from
< * either ROB, IQ, LSQ, and it is priortized in that order.
< */
< enum FullSource {
< ROB,
< IQ,
< LSQ,
< NONE
< };
<
< /** Function used to increment the stat that corresponds to the source of
< * the stall.
< */
< inline void incrFullStat(const FullSource &source);
<
< /** Stat for total number of cycles spent squashing. */
426d218
< /** Stat for total number of cycles spent idle. */
428d219
< /** Stat for total number of cycles spent blocking. */
430,434d220
< /** Stat for total number of cycles spent stalling for a serializing inst. */
< Stats::Scalar<> renameSerializeStallCycles;
< /** Stat for total number of cycles spent running normally. */
< Stats::Scalar<> renameRunCycles;
< /** Stat for total number of cycles spent unblocking. */
436d221
< /** Stat for total number of renamed instructions. */
438d222
< /** Stat for total number of squashed instructions that rename discards. */
440d223
< /** Stat for total number of times that the ROB starts a stall in rename. */
442d224
< /** Stat for total number of times that the IQ starts a stall in rename. */
444,447d225
< /** Stat for total number of times that the LSQ starts a stall in rename. */
< Stats::Scalar<> renameLSQFullEvents;
< /** Stat for total number of times that rename runs out of free registers
< * to use to rename. */
449d226
< /** Stat for total number of renamed destination registers. */
451d227
< /** Stat for total number of source register rename lookups. */
453c229
< /** Stat for total number of committed renaming mappings. */
---
> Stats::Scalar<> renameHBPlaceHolders;
455d230
< /** Stat for total number of mappings that were undone due to a squash. */
457,459c232
< Stats::Scalar<> renamedSerializing;
< Stats::Scalar<> renamedTempSerializing;
< Stats::Scalar<> renameSkidInsts;
---
> Stats::Scalar<> renameValidUndoneMaps;
462c235
< #endif // __CPU_O3_RENAME_HH__
---
> #endif // __CPU_O3_CPU_SIMPLE_RENAME_HH__