diff options
author | Kevin Lim <ktlim@umich.edu> | 2006-05-30 14:17:41 -0400 |
---|---|---|
committer | Kevin Lim <ktlim@umich.edu> | 2006-05-30 14:17:41 -0400 |
commit | 4a5b51b516853c9fcaabc44caacdd7e8e93dc0ef (patch) | |
tree | 4b7d92408a2b74a16ae6f7b4167ded00079355ef /src/cpu/o3/mem_dep_unit.hh | |
parent | d308055afc1ace1f321b76e8a85a9a45165da2ce (diff) | |
parent | f1fab2a4469d6cb2e55ebac15da02f8c1fcb7055 (diff) | |
download | gem5-4a5b51b516853c9fcaabc44caacdd7e8e93dc0ef.tar.xz |
Merge ktlim@zizzer:/bk/m5
into zamp.eecs.umich.edu:/z/ktlim2/clean/newmem
SConstruct:
src/SConscript:
src/arch/SConscript:
src/arch/alpha/faults.cc:
src/arch/alpha/tlb.cc:
src/base/traceflags.py:
src/cpu/SConscript:
src/cpu/base.cc:
src/cpu/base.hh:
src/cpu/base_dyn_inst.cc:
src/cpu/cpu_exec_context.cc:
src/cpu/cpu_exec_context.hh:
src/cpu/exec_context.hh:
src/cpu/o3/alpha_cpu.hh:
src/cpu/o3/alpha_cpu_impl.hh:
src/cpu/o3/alpha_dyn_inst.hh:
src/cpu/o3/cpu.cc:
src/cpu/o3/cpu.hh:
src/cpu/o3/regfile.hh:
src/cpu/ozone/cpu.hh:
src/cpu/simple/base.cc:
src/cpu/base_dyn_inst.hh:
src/cpu/o3/2bit_local_pred.cc:
src/cpu/o3/2bit_local_pred.hh:
src/cpu/o3/alpha_cpu.cc:
src/cpu/o3/alpha_cpu_builder.cc:
src/cpu/o3/alpha_dyn_inst.cc:
src/cpu/o3/alpha_dyn_inst_impl.hh:
src/cpu/o3/alpha_impl.hh:
src/cpu/o3/alpha_params.hh:
src/cpu/o3/bpred_unit.cc:
src/cpu/o3/bpred_unit.hh:
src/cpu/o3/bpred_unit_impl.hh:
src/cpu/o3/btb.cc:
src/cpu/o3/btb.hh:
src/cpu/o3/comm.hh:
src/cpu/o3/commit.cc:
src/cpu/o3/commit.hh:
src/cpu/o3/commit_impl.hh:
src/cpu/o3/cpu_policy.hh:
src/cpu/o3/decode.cc:
src/cpu/o3/decode.hh:
src/cpu/o3/decode_impl.hh:
src/cpu/o3/fetch.cc:
src/cpu/o3/fetch.hh:
src/cpu/o3/fetch_impl.hh:
src/cpu/o3/free_list.cc:
src/cpu/o3/free_list.hh:
src/cpu/o3/iew.cc:
src/cpu/o3/iew.hh:
src/cpu/o3/iew_impl.hh:
src/cpu/o3/inst_queue.cc:
src/cpu/o3/inst_queue.hh:
src/cpu/o3/inst_queue_impl.hh:
src/cpu/o3/mem_dep_unit.cc:
src/cpu/o3/mem_dep_unit.hh:
src/cpu/o3/mem_dep_unit_impl.hh:
src/cpu/o3/ras.cc:
src/cpu/o3/ras.hh:
src/cpu/o3/rename.cc:
src/cpu/o3/rename.hh:
src/cpu/o3/rename_impl.hh:
src/cpu/o3/rename_map.cc:
src/cpu/o3/rename_map.hh:
src/cpu/o3/rob.cc:
src/cpu/o3/rob.hh:
src/cpu/o3/rob_impl.hh:
src/cpu/o3/sat_counter.cc:
src/cpu/o3/sat_counter.hh:
src/cpu/o3/store_set.cc:
src/cpu/o3/store_set.hh:
src/cpu/o3/tournament_pred.cc:
src/cpu/o3/tournament_pred.hh:
Hand merges.
--HG--
rename : build/SConstruct => SConstruct
rename : SConscript => src/SConscript
rename : arch/alpha/ev5.cc => src/arch/alpha/ev5.cc
rename : arch/alpha/isa/decoder.isa => src/arch/alpha/isa/decoder.isa
rename : arch/alpha/isa/pal.isa => src/arch/alpha/isa/pal.isa
rename : base/traceflags.py => src/base/traceflags.py
rename : cpu/SConscript => src/cpu/SConscript
rename : cpu/base.cc => src/cpu/base.cc
rename : cpu/base.hh => src/cpu/base.hh
rename : cpu/base_dyn_inst.cc => src/cpu/base_dyn_inst.cc
rename : cpu/base_dyn_inst.hh => src/cpu/base_dyn_inst.hh
rename : cpu/cpu_exec_context.cc => src/cpu/cpu_exec_context.cc
rename : cpu/cpu_exec_context.hh => src/cpu/cpu_exec_context.hh
rename : cpu/cpu_models.py => src/cpu/cpu_models.py
rename : cpu/exec_context.hh => src/cpu/exec_context.hh
rename : cpu/exetrace.cc => src/cpu/exetrace.cc
rename : cpu/exetrace.hh => src/cpu/exetrace.hh
rename : cpu/inst_seq.hh => src/cpu/inst_seq.hh
rename : cpu/o3/2bit_local_pred.cc => src/cpu/o3/2bit_local_pred.cc
rename : cpu/o3/2bit_local_pred.hh => src/cpu/o3/2bit_local_pred.hh
rename : cpu/o3/alpha_cpu.hh => src/cpu/o3/alpha_cpu.hh
rename : cpu/o3/alpha_cpu_builder.cc => src/cpu/o3/alpha_cpu_builder.cc
rename : cpu/o3/alpha_cpu_impl.hh => src/cpu/o3/alpha_cpu_impl.hh
rename : cpu/o3/alpha_dyn_inst.hh => src/cpu/o3/alpha_dyn_inst.hh
rename : cpu/o3/alpha_dyn_inst_impl.hh => src/cpu/o3/alpha_dyn_inst_impl.hh
rename : cpu/o3/alpha_impl.hh => src/cpu/o3/alpha_impl.hh
rename : cpu/o3/alpha_params.hh => src/cpu/o3/alpha_params.hh
rename : cpu/o3/bpred_unit.cc => src/cpu/o3/bpred_unit.cc
rename : cpu/o3/bpred_unit.hh => src/cpu/o3/bpred_unit.hh
rename : cpu/o3/bpred_unit_impl.hh => src/cpu/o3/bpred_unit_impl.hh
rename : cpu/o3/btb.cc => src/cpu/o3/btb.cc
rename : cpu/o3/btb.hh => src/cpu/o3/btb.hh
rename : cpu/o3/comm.hh => src/cpu/o3/comm.hh
rename : cpu/o3/commit.cc => src/cpu/o3/commit.cc
rename : cpu/o3/commit.hh => src/cpu/o3/commit.hh
rename : cpu/o3/commit_impl.hh => src/cpu/o3/commit_impl.hh
rename : cpu/o3/cpu.cc => src/cpu/o3/cpu.cc
rename : cpu/o3/cpu.hh => src/cpu/o3/cpu.hh
rename : cpu/o3/cpu_policy.hh => src/cpu/o3/cpu_policy.hh
rename : cpu/o3/decode.cc => src/cpu/o3/decode.cc
rename : cpu/o3/decode.hh => src/cpu/o3/decode.hh
rename : cpu/o3/decode_impl.hh => src/cpu/o3/decode_impl.hh
rename : cpu/o3/fetch.cc => src/cpu/o3/fetch.cc
rename : cpu/o3/fetch.hh => src/cpu/o3/fetch.hh
rename : cpu/o3/fetch_impl.hh => src/cpu/o3/fetch_impl.hh
rename : cpu/o3/free_list.cc => src/cpu/o3/free_list.cc
rename : cpu/o3/free_list.hh => src/cpu/o3/free_list.hh
rename : cpu/o3/iew.cc => src/cpu/o3/iew.cc
rename : cpu/o3/iew.hh => src/cpu/o3/iew.hh
rename : cpu/o3/iew_impl.hh => src/cpu/o3/iew_impl.hh
rename : cpu/o3/inst_queue.cc => src/cpu/o3/inst_queue.cc
rename : cpu/o3/inst_queue.hh => src/cpu/o3/inst_queue.hh
rename : cpu/o3/inst_queue_impl.hh => src/cpu/o3/inst_queue_impl.hh
rename : cpu/o3/mem_dep_unit.cc => src/cpu/o3/mem_dep_unit.cc
rename : cpu/o3/mem_dep_unit.hh => src/cpu/o3/mem_dep_unit.hh
rename : cpu/o3/mem_dep_unit_impl.hh => src/cpu/o3/mem_dep_unit_impl.hh
rename : cpu/o3/ras.cc => src/cpu/o3/ras.cc
rename : cpu/o3/ras.hh => src/cpu/o3/ras.hh
rename : cpu/o3/regfile.hh => src/cpu/o3/regfile.hh
rename : cpu/o3/rename.cc => src/cpu/o3/rename.cc
rename : cpu/o3/rename.hh => src/cpu/o3/rename.hh
rename : cpu/o3/rename_impl.hh => src/cpu/o3/rename_impl.hh
rename : cpu/o3/rename_map.cc => src/cpu/o3/rename_map.cc
rename : cpu/o3/rename_map.hh => src/cpu/o3/rename_map.hh
rename : cpu/o3/rob.hh => src/cpu/o3/rob.hh
rename : cpu/o3/rob_impl.hh => src/cpu/o3/rob_impl.hh
rename : cpu/o3/sat_counter.hh => src/cpu/o3/sat_counter.hh
rename : cpu/o3/store_set.cc => src/cpu/o3/store_set.cc
rename : cpu/o3/store_set.hh => src/cpu/o3/store_set.hh
rename : cpu/o3/tournament_pred.cc => src/cpu/o3/tournament_pred.cc
rename : cpu/o3/tournament_pred.hh => src/cpu/o3/tournament_pred.hh
rename : cpu/ozone/cpu.cc => src/cpu/ozone/cpu.cc
rename : cpu/ozone/cpu.hh => src/cpu/ozone/cpu.hh
rename : cpu/ozone/cpu_impl.hh => src/cpu/ozone/cpu_impl.hh
rename : cpu/static_inst.hh => src/cpu/static_inst.hh
rename : kern/system_events.cc => src/kern/system_events.cc
rename : kern/tru64/tru64.hh => src/kern/tru64/tru64.hh
rename : python/m5/objects/AlphaFullCPU.py => src/python/m5/objects/AlphaFullCPU.py
rename : sim/pseudo_inst.cc => src/sim/pseudo_inst.cc
extra : convert_revision : ff351fc0e3a7c0f23e59fdbec33d8209eb9280be
Diffstat (limited to 'src/cpu/o3/mem_dep_unit.hh')
-rw-r--r-- | src/cpu/o3/mem_dep_unit.hh | 227 |
1 files changed, 157 insertions, 70 deletions
diff --git a/src/cpu/o3/mem_dep_unit.hh b/src/cpu/o3/mem_dep_unit.hh index ca63577a1..acbe08ec2 100644 --- a/src/cpu/o3/mem_dep_unit.hh +++ b/src/cpu/o3/mem_dep_unit.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2005 The Regents of The University of Michigan + * Copyright (c) 2004-2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,15 +26,29 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __CPU_O3_CPU_MEM_DEP_UNIT_HH__ -#define __CPU_O3_CPU_MEM_DEP_UNIT_HH__ +#ifndef __CPU_O3_MEM_DEP_UNIT_HH__ +#define __CPU_O3_MEM_DEP_UNIT_HH__ -#include <map> +#include <list> #include <set> +#include "base/hashmap.hh" +#include "base/refcnt.hh" #include "base/statistics.hh" #include "cpu/inst_seq.hh" +struct SNHash { + size_t operator() (const InstSeqNum &seq_num) const { + unsigned a = (unsigned)seq_num; + unsigned hash = (((a >> 14) ^ ((a >> 2) & 0xffff))) & 0x7FFFFFFF; + + return hash; + } +}; + +template <class Impl> +class InstructionQueue; + /** * Memory dependency unit class. This holds the memory dependence predictor. * As memory operations are issued to the IQ, they are also issued to this @@ -52,101 +66,159 @@ class MemDepUnit { typedef typename Impl::Params Params; typedef typename Impl::DynInstPtr DynInstPtr; - public: - MemDepUnit(Params ¶ms); + /** Empty constructor. Must call init() prior to using in this case. */ + MemDepUnit() {} + + /** Constructs a MemDepUnit with given parameters. */ + MemDepUnit(Params *params); + /** Frees up any memory allocated. */ + ~MemDepUnit(); + + /** Returns the name of the memory dependence unit. */ + std::string name() const; + + /** Initializes the unit with parameters and a thread id. */ + void init(Params *params, int tid); + + /** Registers statistics. */ void regStats(); + void switchOut(); + + void takeOverFrom(); + + /** Sets the pointer to the IQ. */ + void setIQ(InstructionQueue<Impl> *iq_ptr); + + /** Inserts a memory instruction. */ void insert(DynInstPtr &inst); + /** Inserts a non-speculative memory instruction. */ void insertNonSpec(DynInstPtr &inst); - // Will want to make this operation relatively fast. Right now it - // is somewhat slow. - DynInstPtr &top(); - - void pop(); + /** Inserts a barrier instruction. */ + void insertBarrier(DynInstPtr &barr_inst); + /** Indicate that an instruction has its registers ready. */ void regsReady(DynInstPtr &inst); + /** Indicate that a non-speculative instruction is ready. */ void nonSpecInstReady(DynInstPtr &inst); - void issue(DynInstPtr &inst); + /** Reschedules an instruction to be re-executed. */ + void reschedule(DynInstPtr &inst); + + /** Replays all instructions that have been rescheduled by moving them to + * the ready list. + */ + void replay(DynInstPtr &inst); + + /** Completes a memory instruction. */ + void completed(DynInstPtr &inst); + /** Completes a barrier instruction. */ + void completeBarrier(DynInstPtr &inst); + + /** Wakes any dependents of a memory instruction. */ void wakeDependents(DynInstPtr &inst); - void squash(const InstSeqNum &squashed_num); + /** Squashes all instructions up until a given sequence number for a + * specific thread. + */ + void squash(const InstSeqNum &squashed_num, unsigned tid); + /** Indicates an ordering violation between a store and a younger load. */ void violation(DynInstPtr &store_inst, DynInstPtr &violating_load); - inline bool empty() - { return readyInsts.empty(); } + /** Issues the given instruction */ + void issue(DynInstPtr &inst); + + /** Debugging function to dump the lists of instructions. */ + void dumpLists(); private: - typedef typename std::set<InstSeqNum>::iterator sn_it_t; - typedef typename std::map<InstSeqNum, DynInstPtr>::iterator dyn_it_t; - - // Forward declarations so that the following two typedefs work. - class Dependency; - class ltDependency; - - typedef typename std::set<Dependency, ltDependency>::iterator dep_it_t; - typedef typename std::map<InstSeqNum, vector<dep_it_t> >::iterator - sd_it_t; - - struct Dependency { - Dependency(const InstSeqNum &_seqNum) - : seqNum(_seqNum), regsReady(0), memDepReady(0) - { } - - Dependency(const InstSeqNum &_seqNum, bool _regsReady, - bool _memDepReady) - : seqNum(_seqNum), regsReady(_regsReady), - memDepReady(_memDepReady) - { } - - InstSeqNum seqNum; - mutable bool regsReady; - mutable bool memDepReady; - mutable sd_it_t storeDep; - }; + typedef typename std::list<DynInstPtr>::iterator ListIt; - struct ltDependency { - bool operator() (const Dependency &lhs, const Dependency &rhs) + class MemDepEntry; + + typedef RefCountingPtr<MemDepEntry> MemDepEntryPtr; + + /** Memory dependence entries that track memory operations, marking + * when the instruction is ready to execute and what instructions depend + * upon it. + */ + class MemDepEntry : public RefCounted { + public: + /** Constructs a memory dependence entry. */ + MemDepEntry(DynInstPtr &new_inst) + : inst(new_inst), regsReady(false), memDepReady(false), + completed(false), squashed(false) { - return lhs.seqNum < rhs.seqNum; + ++memdep_count; + + DPRINTF(MemDepUnit, "Memory dependency entry created. " + "memdep_count=%i\n", memdep_count); } + + /** Frees any pointers. */ + ~MemDepEntry() + { + for (int i = 0; i < dependInsts.size(); ++i) { + dependInsts[i] = NULL; + } + + --memdep_count; + + DPRINTF(MemDepUnit, "Memory dependency entry deleted. " + "memdep_count=%i\n", memdep_count); + } + + /** Returns the name of the memory dependence entry. */ + std::string name() const { return "memdepentry"; } + + /** The instruction being tracked. */ + DynInstPtr inst; + + /** The iterator to the instruction's location inside the list. */ + ListIt listIt; + + /** A vector of any dependent instructions. */ + std::vector<MemDepEntryPtr> dependInsts; + + /** If the registers are ready or not. */ + bool regsReady; + /** If all memory dependencies have been satisfied. */ + bool memDepReady; + /** If the instruction is completed. */ + bool completed; + /** If the instruction is squashed. */ + bool squashed; + + /** For debugging. */ + static int memdep_count; + static int memdep_insert; + static int memdep_erase; }; - inline void moveToReady(dep_it_t &woken_inst); + /** Finds the memory dependence entry in the hash map. */ + inline MemDepEntryPtr &findInHash(const DynInstPtr &inst); - /** List of instructions that have passed through rename, yet are still - * waiting on either a memory dependence to resolve or source registers to - * become available before they can issue. - */ - std::set<Dependency, ltDependency> waitingInsts; + /** Moves an entry to the ready list. */ + inline void moveToReady(MemDepEntryPtr &ready_inst_entry); - /** List of instructions that have all their predicted memory dependences - * resolved and their source registers ready. - */ - std::set<InstSeqNum> readyInsts; + typedef m5::hash_map<InstSeqNum, MemDepEntryPtr, SNHash> MemDepHash; - // Change this to hold a vector of iterators, which will point to the - // entry of the waiting instructions. - /** List of stores' sequence numbers, each of which has a vector of - * iterators. The iterators point to the appropriate node within - * waitingInsts that has the depenendent instruction. - */ - std::map<InstSeqNum, vector<dep_it_t> > storeDependents; + typedef typename MemDepHash::iterator MemDepHashIt; + + /** A hash map of all memory dependence entries. */ + MemDepHash memDepHash; - // For now will implement this as a map...hash table might not be too - // bad, or could move to something that mimics the current dependency - // graph. - std::map<InstSeqNum, DynInstPtr> memInsts; + /** A list of all instructions in the memory dependence unit. */ + std::list<DynInstPtr> instList[Impl::MaxThreads]; - // Iterator pointer to the top instruction which has is ready. - // Is set by the top() call. - dyn_it_t topInst; + /** A list of all instructions that are going to be replayed. */ + std::list<DynInstPtr> instsToReplay; /** The memory dependence predictor. It is accessed upon new * instructions being added to the IQ, and responds by telling @@ -155,10 +227,25 @@ class MemDepUnit { */ MemDepPred depPred; + bool loadBarrier; + InstSeqNum loadBarrierSN; + bool storeBarrier; + InstSeqNum storeBarrierSN; + + /** Pointer to the IQ. */ + InstructionQueue<Impl> *iqPtr; + + /** The thread id of this memory dependence unit. */ + int id; + + /** Stat for number of inserted loads. */ Stats::Scalar<> insertedLoads; + /** Stat for number of inserted stores. */ Stats::Scalar<> insertedStores; + /** Stat for number of conflicting loads that had to wait for a store. */ Stats::Scalar<> conflictingLoads; + /** Stat for number of conflicting stores that had to wait for a store. */ Stats::Scalar<> conflictingStores; }; -#endif // __CPU_O3_CPU_MEM_DEP_UNIT_HH__ +#endif // __CPU_O3_MEM_DEP_UNIT_HH__ |