mem_dep_unit.hh revision 2307
17008Snate@binkert.org/* 27008Snate@binkert.org * Copyright (c) 2004-2005 The Regents of The University of Michigan 37008Snate@binkert.org * All rights reserved. 47008Snate@binkert.org * 57008Snate@binkert.org * Redistribution and use in source and binary forms, with or without 67008Snate@binkert.org * modification, are permitted provided that the following conditions are 77008Snate@binkert.org * met: redistributions of source code must retain the above copyright 87008Snate@binkert.org * notice, this list of conditions and the following disclaimer; 97008Snate@binkert.org * redistributions in binary form must reproduce the above copyright 107008Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 117008Snate@binkert.org * documentation and/or other materials provided with the distribution; 127008Snate@binkert.org * neither the name of the copyright holders nor the names of its 137008Snate@binkert.org * contributors may be used to endorse or promote products derived from 147008Snate@binkert.org * this software without specific prior written permission. 157008Snate@binkert.org * 167008Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177008Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187008Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197008Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207008Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217008Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227008Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237008Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247008Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257008Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267008Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277008Snate@binkert.org */ 286285Snate@binkert.org 2910472Sandreas.hansson@arm.com#ifndef __CPU_O3_MEM_DEP_UNIT_HH__ 3010472Sandreas.hansson@arm.com#define __CPU_O3_MEM_DEP_UNIT_HH__ 318232Snate@binkert.org 329104Shestness@cs.utexas.edu#include <list> 337039Snate@binkert.org#include <set> 3411339SMichael.Lebeane@amd.com 357039Snate@binkert.org#include "base/hashmap.hh" 3611108Sdavid.hashe@amd.com#include "base/refcnt.hh" 376285Snate@binkert.org#include "base/statistics.hh" 386876Ssteve.reinhardt@amd.com#include "cpu/inst_seq.hh" 3911339SMichael.Lebeane@amd.com 406285Snate@binkert.orgstruct SNHash { 416285Snate@binkert.org size_t operator() (const InstSeqNum &seq_num) const { 426285Snate@binkert.org unsigned a = (unsigned)seq_num; 437039Snate@binkert.org unsigned hash = (((a >> 14) ^ ((a >> 2) & 0xffff))) & 0x7FFFFFFF; 447039Snate@binkert.org 456285Snate@binkert.org return hash; 4611339SMichael.Lebeane@amd.com } 477039Snate@binkert.org}; 487039Snate@binkert.org 4911346Santhony.gutierrez@amd.comtemplate <class Impl> 5011346Santhony.gutierrez@amd.comclass InstructionQueue; 5111346Santhony.gutierrez@amd.com 5210518Snilay@cs.wisc.edu/** 5310518Snilay@cs.wisc.edu * Memory dependency unit class. This holds the memory dependence predictor. 547039Snate@binkert.org * As memory operations are issued to the IQ, they are also issued to this 558615Snilay@cs.wisc.edu * unit, which then looks up the prediction as to what they are dependent 566285Snate@binkert.org * upon. This unit must be checked prior to a memory operation being able 577544SBrad.Beckmann@amd.com * to issue. Although this is templated, it's somewhat hard to make a generic 587544SBrad.Beckmann@amd.com * memory dependence unit. This one is mostly for store sets; it will be 597544SBrad.Beckmann@amd.com * quite limited in what other memory dependence predictions it can also 607544SBrad.Beckmann@amd.com * utilize. Thus this class should be most likely be rewritten for other 6111025Snilay@cs.wisc.edu * dependence prediction schemes. 6210562Sandreas.hansson@arm.com */ 638615Snilay@cs.wisc.edutemplate <class MemDepPred, class Impl> 648615Snilay@cs.wisc.educlass MemDepUnit { 656285Snate@binkert.org public: 667039Snate@binkert.org typedef typename Impl::Params Params; 677039Snate@binkert.org typedef typename Impl::DynInstPtr DynInstPtr; 686285Snate@binkert.org 697039Snate@binkert.org /** Empty constructor. Must call init() prior to using in this case. */ 707039Snate@binkert.org MemDepUnit() {} 717039Snate@binkert.org 727039Snate@binkert.org /** Constructs a MemDepUnit with given parameters. */ 737039Snate@binkert.org MemDepUnit(Params *params); 747039Snate@binkert.org 758615Snilay@cs.wisc.edu /** Frees up any memory allocated. */ 766285Snate@binkert.org ~MemDepUnit(); 7710472Sandreas.hansson@arm.com 7810472Sandreas.hansson@arm.com /** Returns the name of the memory dependence unit. */ 7911025Snilay@cs.wisc.edu std::string name() const; 8011025Snilay@cs.wisc.edu 817453Snate@binkert.org /** Initializes the unit with parameters and a thread id. */ 827039Snate@binkert.org void init(Params *params, int tid); 836888SBrad.Beckmann@amd.com 847453Snate@binkert.org /** Registers statistics. */ 857039Snate@binkert.org void regStats(); 866888SBrad.Beckmann@amd.com 877915SBrad.Beckmann@amd.com void switchOut(); 887915SBrad.Beckmann@amd.com 897915SBrad.Beckmann@amd.com void takeOverFrom(); 907915SBrad.Beckmann@amd.com 917039Snate@binkert.org /** Sets the pointer to the IQ. */ 926888SBrad.Beckmann@amd.com void setIQ(InstructionQueue<Impl> *iq_ptr); 937039Snate@binkert.org 9411111Snilay@cs.wisc.edu /** Inserts a memory instruction. */ 957453Snate@binkert.org void insert(DynInstPtr &inst); 966285Snate@binkert.org 977039Snate@binkert.org /** Inserts a non-speculative memory instruction. */ 986285Snate@binkert.org void insertNonSpec(DynInstPtr &inst); 996285Snate@binkert.org 1007039Snate@binkert.org /** Inserts a barrier instruction. */ 1017039Snate@binkert.org void insertBarrier(DynInstPtr &barr_inst); 1026285Snate@binkert.org 10310231Ssteve.reinhardt@amd.com /** Indicate that an instruction has its registers ready. */ 1047039Snate@binkert.org void regsReady(DynInstPtr &inst); 1057039Snate@binkert.org 1068162SBrad.Beckmann@amd.com /** Indicate that a non-speculative instruction is ready. */ 1078162SBrad.Beckmann@amd.com void nonSpecInstReady(DynInstPtr &inst); 1088162SBrad.Beckmann@amd.com 1098162SBrad.Beckmann@amd.com /** Reschedules an instruction to be re-executed. */ 1108162SBrad.Beckmann@amd.com void reschedule(DynInstPtr &inst); 1118162SBrad.Beckmann@amd.com 1127039Snate@binkert.org /** Replays all instructions that have been rescheduled by moving them to 1137039Snate@binkert.org * the ready list. 1147039Snate@binkert.org */ 1156285Snate@binkert.org void replay(DynInstPtr &inst); 11610472Sandreas.hansson@arm.com 11710472Sandreas.hansson@arm.com /** Completes a memory instruction. */ 11811025Snilay@cs.wisc.edu void completed(DynInstPtr &inst); 11911025Snilay@cs.wisc.edu 1206888SBrad.Beckmann@amd.com /** Completes a barrier instruction. */ 12111025Snilay@cs.wisc.edu void completeBarrier(DynInstPtr &inst); 12211025Snilay@cs.wisc.edu 1236888SBrad.Beckmann@amd.com /** Wakes any dependents of a memory instruction. */ 1247453Snate@binkert.org void wakeDependents(DynInstPtr &inst); 1257039Snate@binkert.org 1266888SBrad.Beckmann@amd.com /** Squashes all instructions up until a given sequence number for a 1277453Snate@binkert.org * specific thread. 1287039Snate@binkert.org */ 1297039Snate@binkert.org void squash(const InstSeqNum &squashed_num, unsigned tid); 1307039Snate@binkert.org 1317039Snate@binkert.org /** Indicates an ordering violation between a store and a younger load. */ 1326888SBrad.Beckmann@amd.com void violation(DynInstPtr &store_inst, DynInstPtr &violating_load); 1337039Snate@binkert.org 1347453Snate@binkert.org /** Issues the given instruction */ 1357039Snate@binkert.org void issue(DynInstPtr &inst); 1367453Snate@binkert.org 1377039Snate@binkert.org /** Debugging function to dump the lists of instructions. */ 1386888SBrad.Beckmann@amd.com void dumpLists(); 1397039Snate@binkert.org 14011111Snilay@cs.wisc.edu private: 1417453Snate@binkert.org typedef typename std::list<DynInstPtr>::iterator ListIt; 14210917Sbrandon.potter@amd.com 1438160SBrad.Beckmann@amd.com class MemDepEntry; 1448160SBrad.Beckmann@amd.com 1458160SBrad.Beckmann@amd.com typedef RefCountingPtr<MemDepEntry> MemDepEntryPtr; 1466285Snate@binkert.org 1476285Snate@binkert.org /** Memory dependence entries that track memory operations, marking 1487039Snate@binkert.org * when the instruction is ready to execute and what instructions depend 1497039Snate@binkert.org * upon it. 1506285Snate@binkert.org */ 15110231Ssteve.reinhardt@amd.com class MemDepEntry : public RefCounted { 1527039Snate@binkert.org public: 1537039Snate@binkert.org /** Constructs a memory dependence entry. */ 1547039Snate@binkert.org MemDepEntry(DynInstPtr &new_inst) 1557039Snate@binkert.org : inst(new_inst), regsReady(false), memDepReady(false), 15610231Ssteve.reinhardt@amd.com completed(false), squashed(false) 1577915SBrad.Beckmann@amd.com { 1587915SBrad.Beckmann@amd.com ++memdep_count; 1597915SBrad.Beckmann@amd.com 1607915SBrad.Beckmann@amd.com DPRINTF(MemDepUnit, "Memory dependency entry created. " 1617039Snate@binkert.org "memdep_count=%i\n", memdep_count); 1626285Snate@binkert.org } 1636285Snate@binkert.org 1647039Snate@binkert.org /** Frees any pointers. */ 1657039Snate@binkert.org ~MemDepEntry() 1666285Snate@binkert.org { 1677039Snate@binkert.org for (int i = 0; i < dependInsts.size(); ++i) { 1686285Snate@binkert.org dependInsts[i] = NULL; 1696285Snate@binkert.org } 1707039Snate@binkert.org 17110518Snilay@cs.wisc.edu --memdep_count; 17210518Snilay@cs.wisc.edu 1739104Shestness@cs.utexas.edu DPRINTF(MemDepUnit, "Memory dependency entry deleted. " 1749104Shestness@cs.utexas.edu "memdep_count=%i\n", memdep_count); 1759104Shestness@cs.utexas.edu } 1769104Shestness@cs.utexas.edu 1776876Ssteve.reinhardt@amd.com /** Returns the name of the memory dependence entry. */ 1786876Ssteve.reinhardt@amd.com std::string name() const { return "memdepentry"; } 1796876Ssteve.reinhardt@amd.com 1806876Ssteve.reinhardt@amd.com /** The instruction being tracked. */ 1816876Ssteve.reinhardt@amd.com DynInstPtr inst; 182 183 /** The iterator to the instruction's location inside the list. */ 184 ListIt listIt; 185 186 /** A vector of any dependent instructions. */ 187 std::vector<MemDepEntryPtr> dependInsts; 188 189 /** If the registers are ready or not. */ 190 bool regsReady; 191 /** If all memory dependencies have been satisfied. */ 192 bool memDepReady; 193 /** If the instruction is completed. */ 194 bool completed; 195 /** If the instruction is squashed. */ 196 bool squashed; 197 198 /** For debugging. */ 199 static int memdep_count; 200 static int memdep_insert; 201 static int memdep_erase; 202 }; 203 204 struct ltMemDepEntry { 205 bool operator() (const MemDepEntryPtr &lhs, const MemDepEntryPtr &rhs) 206 { 207 return lhs->inst->seqNum < rhs->inst->seqNum; 208 } 209 }; 210 211 /** Finds the memory dependence entry in the hash map. */ 212 inline MemDepEntryPtr &findInHash(const DynInstPtr &inst); 213 214 /** Moves an entry to the ready list. */ 215 inline void moveToReady(MemDepEntryPtr &ready_inst_entry); 216 217 typedef m5::hash_map<InstSeqNum, MemDepEntryPtr, SNHash> MemDepHash; 218 219 typedef typename MemDepHash::iterator MemDepHashIt; 220 221 /** A hash map of all memory dependence entries. */ 222 MemDepHash memDepHash; 223 224 /** A list of all instructions in the memory dependence unit. */ 225 std::list<DynInstPtr> instList[Impl::MaxThreads]; 226 227 /** A list of all instructions that are going to be replayed. */ 228 std::list<DynInstPtr> instsToReplay; 229 230 /** The memory dependence predictor. It is accessed upon new 231 * instructions being added to the IQ, and responds by telling 232 * this unit what instruction the newly added instruction is dependent 233 * upon. 234 */ 235 MemDepPred depPred; 236 237 bool loadBarrier; 238 InstSeqNum loadBarrierSN; 239 bool storeBarrier; 240 InstSeqNum storeBarrierSN; 241 242 /** Pointer to the IQ. */ 243 InstructionQueue<Impl> *iqPtr; 244 245 /** The thread id of this memory dependence unit. */ 246 int id; 247 248 /** Stat for number of inserted loads. */ 249 Stats::Scalar<> insertedLoads; 250 /** Stat for number of inserted stores. */ 251 Stats::Scalar<> insertedStores; 252 /** Stat for number of conflicting loads that had to wait for a store. */ 253 Stats::Scalar<> conflictingLoads; 254 /** Stat for number of conflicting stores that had to wait for a store. */ 255 Stats::Scalar<> conflictingStores; 256}; 257 258#endif // __CPU_O3_MEM_DEP_UNIT_HH__ 259