mem_dep_unit.hh revision 2632:1bb2f91485ea
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 */
49template <class MemDepPred, class Impl>
50class 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__
165