Fix SCons version check.
[gem5.git] / src / cpu / o3 / mem_dep_unit.hh
1 /*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifndef __CPU_O3_CPU_MEM_DEP_UNIT_HH__
30 #define __CPU_O3_CPU_MEM_DEP_UNIT_HH__
31
32 #include <map>
33 #include <set>
34
35 #include "base/statistics.hh"
36 #include "cpu/inst_seq.hh"
37
38 /**
39 * Memory dependency unit class. This holds the memory dependence predictor.
40 * As memory operations are issued to the IQ, they are also issued to this
41 * unit, which then looks up the prediction as to what they are dependent
42 * upon. This unit must be checked prior to a memory operation being able
43 * to issue. Although this is templated, it's somewhat hard to make a generic
44 * memory dependence unit. This one is mostly for store sets; it will be
45 * quite limited in what other memory dependence predictions it can also
46 * utilize. Thus this class should be most likely be rewritten for other
47 * dependence prediction schemes.
48 */
49 template <class MemDepPred, class Impl>
50 class MemDepUnit {
51 public:
52 typedef typename Impl::Params Params;
53 typedef typename Impl::DynInstPtr DynInstPtr;
54
55 public:
56 MemDepUnit(Params &params);
57
58 void regStats();
59
60 void insert(DynInstPtr &inst);
61
62 void insertNonSpec(DynInstPtr &inst);
63
64 // Will want to make this operation relatively fast. Right now it
65 // is somewhat slow.
66 DynInstPtr &top();
67
68 void pop();
69
70 void regsReady(DynInstPtr &inst);
71
72 void nonSpecInstReady(DynInstPtr &inst);
73
74 void issue(DynInstPtr &inst);
75
76 void wakeDependents(DynInstPtr &inst);
77
78 void squash(const InstSeqNum &squashed_num);
79
80 void violation(DynInstPtr &store_inst, DynInstPtr &violating_load);
81
82 inline bool empty()
83 { return readyInsts.empty(); }
84
85 private:
86 typedef typename std::set<InstSeqNum>::iterator sn_it_t;
87 typedef typename std::map<InstSeqNum, DynInstPtr>::iterator dyn_it_t;
88
89 // Forward declarations so that the following two typedefs work.
90 class Dependency;
91 class ltDependency;
92
93 typedef typename std::set<Dependency, ltDependency>::iterator dep_it_t;
94 typedef typename std::map<InstSeqNum, vector<dep_it_t> >::iterator
95 sd_it_t;
96
97 struct Dependency {
98 Dependency(const InstSeqNum &_seqNum)
99 : seqNum(_seqNum), regsReady(0), memDepReady(0)
100 { }
101
102 Dependency(const InstSeqNum &_seqNum, bool _regsReady,
103 bool _memDepReady)
104 : seqNum(_seqNum), regsReady(_regsReady),
105 memDepReady(_memDepReady)
106 { }
107
108 InstSeqNum seqNum;
109 mutable bool regsReady;
110 mutable bool memDepReady;
111 mutable sd_it_t storeDep;
112 };
113
114 struct ltDependency {
115 bool operator() (const Dependency &lhs, const Dependency &rhs)
116 {
117 return lhs.seqNum < rhs.seqNum;
118 }
119 };
120
121 inline void moveToReady(dep_it_t &woken_inst);
122
123 /** List of instructions that have passed through rename, yet are still
124 * waiting on either a memory dependence to resolve or source registers to
125 * become available before they can issue.
126 */
127 std::set<Dependency, ltDependency> waitingInsts;
128
129 /** List of instructions that have all their predicted memory dependences
130 * resolved and their source registers ready.
131 */
132 std::set<InstSeqNum> readyInsts;
133
134 // Change this to hold a vector of iterators, which will point to the
135 // entry of the waiting instructions.
136 /** List of stores' sequence numbers, each of which has a vector of
137 * iterators. The iterators point to the appropriate node within
138 * waitingInsts that has the depenendent instruction.
139 */
140 std::map<InstSeqNum, vector<dep_it_t> > storeDependents;
141
142 // For now will implement this as a map...hash table might not be too
143 // bad, or could move to something that mimics the current dependency
144 // graph.
145 std::map<InstSeqNum, DynInstPtr> memInsts;
146
147 // Iterator pointer to the top instruction which has is ready.
148 // Is set by the top() call.
149 dyn_it_t topInst;
150
151 /** The memory dependence predictor. It is accessed upon new
152 * instructions being added to the IQ, and responds by telling
153 * this unit what instruction the newly added instruction is dependent
154 * upon.
155 */
156 MemDepPred depPred;
157
158 Stats::Scalar<> insertedLoads;
159 Stats::Scalar<> insertedStores;
160 Stats::Scalar<> conflictingLoads;
161 Stats::Scalar<> conflictingStores;
162 };
163
164 #endif // __CPU_O3_CPU_MEM_DEP_UNIT_HH__