summaryrefslogtreecommitdiff
path: root/cpu/beta_cpu/mem_dep_unit.hh
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/beta_cpu/mem_dep_unit.hh')
-rw-r--r--cpu/beta_cpu/mem_dep_unit.hh92
1 files changed, 81 insertions, 11 deletions
diff --git a/cpu/beta_cpu/mem_dep_unit.hh b/cpu/beta_cpu/mem_dep_unit.hh
index 4821c63b7..e43543e09 100644
--- a/cpu/beta_cpu/mem_dep_unit.hh
+++ b/cpu/beta_cpu/mem_dep_unit.hh
@@ -6,6 +6,7 @@
#include <map>
#include "cpu/inst_seq.hh"
+#include "base/statistics.hh"
/**
* Memory dependency unit class. This holds the memory dependence predictor.
@@ -25,16 +26,17 @@ class MemDepUnit {
typedef typename Impl::DynInstPtr DynInstPtr;
public:
- typedef typename std::set<InstSeqNum>::iterator sn_it_t;
- typedef typename std::map<InstSeqNum, vector<InstSeqNum> >::iterator
- dep_it_t;
-
- public:
MemDepUnit(Params &params);
+ void regStats();
+
void insert(DynInstPtr &inst);
- bool readyToIssue(DynInstPtr &inst);
+ void insertNonSpec(DynInstPtr &inst);
+
+ void regsReady(DynInstPtr &inst);
+
+ void nonSpecInstReady(DynInstPtr &inst);
void issue(DynInstPtr &inst);
@@ -44,19 +46,83 @@ class MemDepUnit {
void violation(DynInstPtr &store_inst, DynInstPtr &violating_load);
+ // Will want to make this operation relatively fast. Right now it
+ // kind of sucks.
+ DynInstPtr &top();
+
+ void pop();
+
+ inline bool empty()
+ { return readyInsts.empty(); }
+
+ 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;
+ };
+
+ struct ltDependency {
+ bool operator() (const Dependency &lhs, const Dependency &rhs)
+ {
+ return lhs.seqNum < rhs.seqNum;
+ }
+ };
+
+
+ private:
+ inline void moveToReady(dep_it_t &woken_inst);
+
private:
/** List of instructions that have passed through rename, yet are still
- * waiting on a memory dependence to resolve before they can issue.
+ * waiting on either a memory dependence to resolve or source registers to
+ * become available before they can issue.
*/
- std::set<InstSeqNum> renamedInsts;
+ std::set<Dependency, ltDependency> waitingInsts;
/** List of instructions that have all their predicted memory dependences
- * resolved. They are ready in terms of being free of memory
- * dependences; however they may still have to wait on source registers.
+ * resolved and their source registers ready.
*/
std::set<InstSeqNum> readyInsts;
- std::map<InstSeqNum, vector<InstSeqNum> > dependencies;
+ // 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;
+
+ // 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;
+
+ // Iterator pointer to the top instruction which has is ready.
+ // Is set by the top() call.
+ dyn_it_t topInst;
/** The memory dependence predictor. It is accessed upon new
* instructions being added to the IQ, and responds by telling
@@ -65,6 +131,10 @@ class MemDepUnit {
*/
MemDepPred depPred;
+ Stats::Scalar<> insertedLoads;
+ Stats::Scalar<> insertedStores;
+ Stats::Scalar<> conflictingLoads;
+ Stats::Scalar<> conflictingStores;
};
#endif