mem_dep_unit.hh revision 2292
19243SN/A/* 210206Sandreas.hansson@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 39243SN/A * All rights reserved. 49243SN/A * 59243SN/A * Redistribution and use in source and binary forms, with or without 69243SN/A * modification, are permitted provided that the following conditions are 79243SN/A * met: redistributions of source code must retain the above copyright 89243SN/A * notice, this list of conditions and the following disclaimer; 99243SN/A * redistributions in binary form must reproduce the above copyright 109243SN/A * notice, this list of conditions and the following disclaimer in the 119243SN/A * documentation and/or other materials provided with the distribution; 129243SN/A * neither the name of the copyright holders nor the names of its 139243SN/A * contributors may be used to endorse or promote products derived from 149831SN/A * this software without specific prior written permission. 159831SN/A * 169831SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179243SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189243SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199243SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209243SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219243SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229243SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239243SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249243SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259243SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269243SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279243SN/A */ 289243SN/A 299243SN/A#ifndef __CPU_O3_MEM_DEP_UNIT_HH__ 309243SN/A#define __CPU_O3_MEM_DEP_UNIT_HH__ 319243SN/A 329243SN/A#include <list> 339243SN/A#include <set> 349243SN/A 359243SN/A#include "base/hashmap.hh" 369243SN/A#include "base/refcnt.hh" 379243SN/A#include "base/statistics.hh" 389243SN/A#include "cpu/inst_seq.hh" 399243SN/A 409243SN/Astruct SNHash { 419243SN/A size_t operator() (const InstSeqNum &seq_num) const { 429967SN/A unsigned a = (unsigned)seq_num; 4310618SOmar.Naji@arm.com unsigned hash = (((a >> 14) ^ ((a >> 2) & 0xffff))) & 0x7FFFFFFF; 449243SN/A 459243SN/A return hash; 4610146Sandreas.hansson@arm.com } 479356SN/A}; 4810146Sandreas.hansson@arm.com 4910247Sandreas.hansson@arm.comtemplate <class Impl> 5010208Sandreas.hansson@arm.comclass InstructionQueue; 519352SN/A 5210146Sandreas.hansson@arm.com/** 539814SN/A * Memory dependency unit class. This holds the memory dependence predictor. 549243SN/A * As memory operations are issued to the IQ, they are also issued to this 559243SN/A * unit, which then looks up the prediction as to what they are dependent 5610432SOmar.Naji@arm.com * upon. This unit must be checked prior to a memory operation being able 579243SN/A * to issue. Although this is templated, it's somewhat hard to make a generic 5810146Sandreas.hansson@arm.com * memory dependence unit. This one is mostly for store sets; it will be 599243SN/A * quite limited in what other memory dependence predictions it can also 6010619Sandreas.hansson@arm.com * utilize. Thus this class should be most likely be rewritten for other 619243SN/A * dependence prediction schemes. 6210211Sandreas.hansson@arm.com */ 6310618SOmar.Naji@arm.comtemplate <class MemDepPred, class Impl> 6410208Sandreas.hansson@arm.comclass MemDepUnit { 6510489SOmar.Naji@arm.com public: 669831SN/A typedef typename Impl::Params Params; 679831SN/A typedef typename Impl::DynInstPtr DynInstPtr; 689831SN/A 699831SN/A /** Empty constructor. Must call init() prior to using in this case. */ 709831SN/A MemDepUnit() {} 7110140SN/A 7210646Sandreas.hansson@arm.com /** Constructs a MemDepUnit with given parameters. */ 739243SN/A MemDepUnit(Params *params); 7410394Swendy.elsasser@arm.com 7510394Swendy.elsasser@arm.com /** Frees up any memory allocated. */ 769566SN/A ~MemDepUnit(); 779243SN/A 789243SN/A /** Returns the name of the memory dependence unit. */ 7910140SN/A std::string name() const; 8010140SN/A 8110147Sandreas.hansson@arm.com /** Initializes the unit with parameters and a thread id. */ 8210147Sandreas.hansson@arm.com void init(Params *params, int tid); 8310393Swendy.elsasser@arm.com 8410394Swendy.elsasser@arm.com /** Registers statistics. */ 8510394Swendy.elsasser@arm.com void regStats(); 8610394Swendy.elsasser@arm.com 879243SN/A /** Sets the pointer to the IQ. */ 889243SN/A void setIQ(InstructionQueue<Impl> *iq_ptr); 8910141SN/A 909726SN/A /** Inserts a memory instruction. */ 919726SN/A void insert(DynInstPtr &inst); 9210618SOmar.Naji@arm.com 9310618SOmar.Naji@arm.com /** Inserts a non-speculative memory instruction. */ 949243SN/A void insertNonSpec(DynInstPtr &inst); 9510620Sandreas.hansson@arm.com 9610620Sandreas.hansson@arm.com /** Inserts a barrier instruction. */ 9710620Sandreas.hansson@arm.com void insertBarrier(DynInstPtr &barr_inst); 9810620Sandreas.hansson@arm.com 9910620Sandreas.hansson@arm.com /** Indicate that an instruction has its registers ready. */ 10010618SOmar.Naji@arm.com void regsReady(DynInstPtr &inst); 10110618SOmar.Naji@arm.com 10210618SOmar.Naji@arm.com /** Indicate that a non-speculative instruction is ready. */ 10310432SOmar.Naji@arm.com void nonSpecInstReady(DynInstPtr &inst); 10410618SOmar.Naji@arm.com 10510618SOmar.Naji@arm.com /** Reschedules an instruction to be re-executed. */ 10610618SOmar.Naji@arm.com void reschedule(DynInstPtr &inst); 10710432SOmar.Naji@arm.com 10810246Sandreas.hansson@arm.com /** Replays all instructions that have been rescheduled by moving them to 10910618SOmar.Naji@arm.com * the ready list. 11010561SOmar.Naji@arm.com */ 11110561SOmar.Naji@arm.com void replay(DynInstPtr &inst); 11210561SOmar.Naji@arm.com 11310394Swendy.elsasser@arm.com /** Completes a memory instruction. */ 11410394Swendy.elsasser@arm.com void completed(DynInstPtr &inst); 11510394Swendy.elsasser@arm.com 11610394Swendy.elsasser@arm.com /** Completes a barrier instruction. */ 11710394Swendy.elsasser@arm.com void completeBarrier(DynInstPtr &inst); 11810394Swendy.elsasser@arm.com 11910394Swendy.elsasser@arm.com /** Wakes any dependents of a memory instruction. */ 12010394Swendy.elsasser@arm.com void wakeDependents(DynInstPtr &inst); 12110618SOmar.Naji@arm.com 12210394Swendy.elsasser@arm.com /** Squashes all instructions up until a given sequence number for a 12310394Swendy.elsasser@arm.com * specific thread. 12410618SOmar.Naji@arm.com */ 12510394Swendy.elsasser@arm.com void squash(const InstSeqNum &squashed_num, unsigned tid); 12610246Sandreas.hansson@arm.com 12710246Sandreas.hansson@arm.com /** Indicates an ordering violation between a store and a younger load. */ 12810246Sandreas.hansson@arm.com void violation(DynInstPtr &store_inst, DynInstPtr &violating_load); 12910140SN/A 13010140SN/A /** Issues the given instruction */ 13110140SN/A void issue(DynInstPtr &inst); 13210140SN/A 13310140SN/A /** Debugging function to dump the lists of instructions. */ 1349243SN/A void dumpLists(); 1359243SN/A 1369567SN/A private: 1379243SN/A typedef typename std::list<DynInstPtr>::iterator ListIt; 13810489SOmar.Naji@arm.com 13910489SOmar.Naji@arm.com class MemDepEntry; 14010489SOmar.Naji@arm.com 14110489SOmar.Naji@arm.com typedef RefCountingPtr<MemDepEntry> MemDepEntryPtr; 14210489SOmar.Naji@arm.com 14310489SOmar.Naji@arm.com /** Memory dependence entries that track memory operations, marking 14410489SOmar.Naji@arm.com * when the instruction is ready to execute and what instructions depend 14510489SOmar.Naji@arm.com * upon it. 14610489SOmar.Naji@arm.com */ 14710489SOmar.Naji@arm.com class MemDepEntry : public RefCounted { 1489243SN/A public: 1499243SN/A /** Constructs a memory dependence entry. */ 1509831SN/A MemDepEntry(DynInstPtr &new_inst) 1519831SN/A : inst(new_inst), regsReady(false), memDepReady(false), 1529831SN/A completed(false), squashed(false) 1539831SN/A { 1549831SN/A ++memdep_count; 1559243SN/A 15610207Sandreas.hansson@arm.com DPRINTF(MemDepUnit, "Memory dependency entry created. " 15710207Sandreas.hansson@arm.com "memdep_count=%i\n", memdep_count); 15810207Sandreas.hansson@arm.com } 15910207Sandreas.hansson@arm.com 16010207Sandreas.hansson@arm.com /** Frees any pointers. */ 16110394Swendy.elsasser@arm.com ~MemDepEntry() 16210394Swendy.elsasser@arm.com { 16310394Swendy.elsasser@arm.com for (int i = 0; i < dependInsts.size(); ++i) { 16410394Swendy.elsasser@arm.com dependInsts[i] = NULL; 16510394Swendy.elsasser@arm.com } 16610394Swendy.elsasser@arm.com 16710394Swendy.elsasser@arm.com --memdep_count; 16810394Swendy.elsasser@arm.com 16910394Swendy.elsasser@arm.com DPRINTF(MemDepUnit, "Memory dependency entry deleted. " 17010394Swendy.elsasser@arm.com "memdep_count=%i\n", memdep_count); 17110394Swendy.elsasser@arm.com } 17210394Swendy.elsasser@arm.com 17310394Swendy.elsasser@arm.com /** Returns the name of the memory dependence entry. */ 17410394Swendy.elsasser@arm.com std::string name() const { return "memdepentry"; } 17510394Swendy.elsasser@arm.com 17610394Swendy.elsasser@arm.com /** The instruction being tracked. */ 17710394Swendy.elsasser@arm.com DynInstPtr inst; 17810394Swendy.elsasser@arm.com 17910394Swendy.elsasser@arm.com /** The iterator to the instruction's location inside the list. */ 18010394Swendy.elsasser@arm.com ListIt listIt; 18110394Swendy.elsasser@arm.com 18210394Swendy.elsasser@arm.com /** A vector of any dependent instructions. */ 18310561SOmar.Naji@arm.com std::vector<MemDepEntryPtr> dependInsts; 18410561SOmar.Naji@arm.com 18510394Swendy.elsasser@arm.com /** If the registers are ready or not. */ 18610394Swendy.elsasser@arm.com bool regsReady; 18710394Swendy.elsasser@arm.com /** If all memory dependencies have been satisfied. */ 18810394Swendy.elsasser@arm.com bool memDepReady; 18910394Swendy.elsasser@arm.com /** If the instruction is completed. */ 19010394Swendy.elsasser@arm.com bool completed; 1919243SN/A /** If the instruction is squashed. */ 1929243SN/A bool squashed; 1939243SN/A 19410146Sandreas.hansson@arm.com /** For debugging. */ 19510140SN/A static int memdep_count; 19610466Sandreas.hansson@arm.com static int memdep_insert; 19710466Sandreas.hansson@arm.com static int memdep_erase; 19810466Sandreas.hansson@arm.com }; 19910146Sandreas.hansson@arm.com 20010140SN/A struct ltMemDepEntry { 20110140SN/A bool operator() (const MemDepEntryPtr &lhs, const MemDepEntryPtr &rhs) 20210140SN/A { 20310646Sandreas.hansson@arm.com return lhs->inst->seqNum < rhs->inst->seqNum; 20410646Sandreas.hansson@arm.com } 20510646Sandreas.hansson@arm.com }; 20610646Sandreas.hansson@arm.com 20710646Sandreas.hansson@arm.com /** Finds the memory dependence entry in the hash map. */ 20810646Sandreas.hansson@arm.com inline MemDepEntryPtr &findInHash(const DynInstPtr &inst); 20910646Sandreas.hansson@arm.com 21010646Sandreas.hansson@arm.com /** Moves an entry to the ready list. */ 21110646Sandreas.hansson@arm.com inline void moveToReady(MemDepEntryPtr &ready_inst_entry); 21210646Sandreas.hansson@arm.com 21310646Sandreas.hansson@arm.com typedef m5::hash_map<InstSeqNum, MemDepEntryPtr, SNHash> MemDepHash; 21410646Sandreas.hansson@arm.com 21510646Sandreas.hansson@arm.com typedef typename MemDepHash::iterator MemDepHashIt; 21610646Sandreas.hansson@arm.com 21710646Sandreas.hansson@arm.com /** A hash map of all memory dependence entries. */ 21810646Sandreas.hansson@arm.com MemDepHash memDepHash; 21910646Sandreas.hansson@arm.com 22010646Sandreas.hansson@arm.com /** A list of all instructions in the memory dependence unit. */ 22110646Sandreas.hansson@arm.com std::list<DynInstPtr> instList[Impl::MaxThreads]; 22210646Sandreas.hansson@arm.com 22310646Sandreas.hansson@arm.com /** A list of all instructions that are going to be replayed. */ 22410646Sandreas.hansson@arm.com std::list<DynInstPtr> instsToReplay; 22510646Sandreas.hansson@arm.com 22610646Sandreas.hansson@arm.com /** The memory dependence predictor. It is accessed upon new 22710646Sandreas.hansson@arm.com * instructions being added to the IQ, and responds by telling 22810646Sandreas.hansson@arm.com * this unit what instruction the newly added instruction is dependent 22910646Sandreas.hansson@arm.com * upon. 23010646Sandreas.hansson@arm.com */ 23110646Sandreas.hansson@arm.com MemDepPred depPred; 23210646Sandreas.hansson@arm.com 23310646Sandreas.hansson@arm.com bool loadBarrier; 23410646Sandreas.hansson@arm.com InstSeqNum loadBarrierSN; 23510646Sandreas.hansson@arm.com bool storeBarrier; 23610646Sandreas.hansson@arm.com InstSeqNum storeBarrierSN; 23710646Sandreas.hansson@arm.com 23810646Sandreas.hansson@arm.com /** Pointer to the IQ. */ 23910646Sandreas.hansson@arm.com InstructionQueue<Impl> *iqPtr; 24010646Sandreas.hansson@arm.com 24110646Sandreas.hansson@arm.com /** The thread id of this memory dependence unit. */ 24210646Sandreas.hansson@arm.com int id; 24310140SN/A 24410140SN/A /** Stat for number of inserted loads. */ 24510140SN/A Stats::Scalar<> insertedLoads; 24610146Sandreas.hansson@arm.com /** Stat for number of inserted stores. */ 2479243SN/A Stats::Scalar<> insertedStores; 24810619Sandreas.hansson@arm.com /** Stat for number of conflicting loads that had to wait for a store. */ 24910619Sandreas.hansson@arm.com Stats::Scalar<> conflictingLoads; 25010618SOmar.Naji@arm.com /** Stat for number of conflicting stores that had to wait for a store. */ 25110619Sandreas.hansson@arm.com Stats::Scalar<> conflictingStores; 25210619Sandreas.hansson@arm.com}; 25310619Sandreas.hansson@arm.com 25410619Sandreas.hansson@arm.com#endif // __CPU_O3_MEM_DEP_UNIT_HH__ 25510619Sandreas.hansson@arm.com