mem_dep_unit.hh revision 5529
113531Sjairo.balart@metempsy.com/* 214167Sgiacomo.travaglini@arm.com * Copyright (c) 2004-2006 The Regents of The University of Michigan 314167Sgiacomo.travaglini@arm.com * All rights reserved. 414167Sgiacomo.travaglini@arm.com * 514167Sgiacomo.travaglini@arm.com * Redistribution and use in source and binary forms, with or without 614167Sgiacomo.travaglini@arm.com * modification, are permitted provided that the following conditions are 714167Sgiacomo.travaglini@arm.com * met: redistributions of source code must retain the above copyright 814167Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer; 914167Sgiacomo.travaglini@arm.com * redistributions in binary form must reproduce the above copyright 1014167Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer in the 1114167Sgiacomo.travaglini@arm.com * documentation and/or other materials provided with the distribution; 1214167Sgiacomo.travaglini@arm.com * neither the name of the copyright holders nor the names of its 1314167Sgiacomo.travaglini@arm.com * contributors may be used to endorse or promote products derived from 1413531Sjairo.balart@metempsy.com * this software without specific prior written permission. 1513531Sjairo.balart@metempsy.com * 1613531Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1713531Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1813531Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1913531Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2013531Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2113531Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2213531Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2313531Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2413531Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2513531Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2613531Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2713531Sjairo.balart@metempsy.com * 2813531Sjairo.balart@metempsy.com * Authors: Kevin Lim 2913531Sjairo.balart@metempsy.com */ 3013531Sjairo.balart@metempsy.com 3113531Sjairo.balart@metempsy.com#ifndef __CPU_O3_MEM_DEP_UNIT_HH__ 3213531Sjairo.balart@metempsy.com#define __CPU_O3_MEM_DEP_UNIT_HH__ 3313531Sjairo.balart@metempsy.com 3413531Sjairo.balart@metempsy.com#include <list> 3513531Sjairo.balart@metempsy.com#include <set> 3613531Sjairo.balart@metempsy.com 3713531Sjairo.balart@metempsy.com#include "base/hashmap.hh" 3813531Sjairo.balart@metempsy.com#include "base/refcnt.hh" 3913531Sjairo.balart@metempsy.com#include "base/statistics.hh" 4013531Sjairo.balart@metempsy.com#include "cpu/inst_seq.hh" 4113531Sjairo.balart@metempsy.com 4213756Sjairo.balart@metempsy.comstruct SNHash { 4313531Sjairo.balart@metempsy.com size_t operator() (const InstSeqNum &seq_num) const { 4413531Sjairo.balart@metempsy.com unsigned a = (unsigned)seq_num; 4513531Sjairo.balart@metempsy.com unsigned hash = (((a >> 14) ^ ((a >> 2) & 0xffff))) & 0x7FFFFFFF; 4613531Sjairo.balart@metempsy.com 4713531Sjairo.balart@metempsy.com return hash; 4813531Sjairo.balart@metempsy.com } 4913531Sjairo.balart@metempsy.com}; 5013531Sjairo.balart@metempsy.com 5113531Sjairo.balart@metempsy.comclass DerivO3CPUParams; 5213756Sjairo.balart@metempsy.com 5313756Sjairo.balart@metempsy.comtemplate <class Impl> 5413756Sjairo.balart@metempsy.comclass InstructionQueue; 5513756Sjairo.balart@metempsy.com 5613756Sjairo.balart@metempsy.com/** 5713756Sjairo.balart@metempsy.com * Memory dependency unit class. This holds the memory dependence predictor. 5813756Sjairo.balart@metempsy.com * As memory operations are issued to the IQ, they are also issued to this 5913531Sjairo.balart@metempsy.com * unit, which then looks up the prediction as to what they are dependent 6013756Sjairo.balart@metempsy.com * upon. This unit must be checked prior to a memory operation being able 6113756Sjairo.balart@metempsy.com * to issue. Although this is templated, it's somewhat hard to make a generic 6213756Sjairo.balart@metempsy.com * memory dependence unit. This one is mostly for store sets; it will be 6313756Sjairo.balart@metempsy.com * quite limited in what other memory dependence predictions it can also 6413756Sjairo.balart@metempsy.com * utilize. Thus this class should be most likely be rewritten for other 6513756Sjairo.balart@metempsy.com * dependence prediction schemes. 6613756Sjairo.balart@metempsy.com */ 6713531Sjairo.balart@metempsy.comtemplate <class MemDepPred, class Impl> 6813531Sjairo.balart@metempsy.comclass MemDepUnit { 6913531Sjairo.balart@metempsy.com public: 7013531Sjairo.balart@metempsy.com typedef typename Impl::DynInstPtr DynInstPtr; 7113531Sjairo.balart@metempsy.com 7213531Sjairo.balart@metempsy.com /** Empty constructor. Must call init() prior to using in this case. */ 7313531Sjairo.balart@metempsy.com MemDepUnit(); 7413531Sjairo.balart@metempsy.com 7513531Sjairo.balart@metempsy.com /** Constructs a MemDepUnit with given parameters. */ 7613531Sjairo.balart@metempsy.com MemDepUnit(DerivO3CPUParams *params); 7713531Sjairo.balart@metempsy.com 7813531Sjairo.balart@metempsy.com /** Frees up any memory allocated. */ 7914167Sgiacomo.travaglini@arm.com ~MemDepUnit(); 8014167Sgiacomo.travaglini@arm.com 8114167Sgiacomo.travaglini@arm.com /** Returns the name of the memory dependence unit. */ 8214167Sgiacomo.travaglini@arm.com std::string name() const; 8314167Sgiacomo.travaglini@arm.com 8414167Sgiacomo.travaglini@arm.com /** Initializes the unit with parameters and a thread id. */ 8513531Sjairo.balart@metempsy.com void init(DerivO3CPUParams *params, int tid); 8613531Sjairo.balart@metempsy.com 8713531Sjairo.balart@metempsy.com /** Registers statistics. */ 8813531Sjairo.balart@metempsy.com void regStats(); 8913531Sjairo.balart@metempsy.com 9013531Sjairo.balart@metempsy.com /** Switches out the memory dependence predictor. */ 9113531Sjairo.balart@metempsy.com void switchOut(); 9213531Sjairo.balart@metempsy.com 9313531Sjairo.balart@metempsy.com /** Takes over from another CPU's thread. */ 9413531Sjairo.balart@metempsy.com void takeOverFrom(); 9513531Sjairo.balart@metempsy.com 9613531Sjairo.balart@metempsy.com /** Sets the pointer to the IQ. */ 9713531Sjairo.balart@metempsy.com void setIQ(InstructionQueue<Impl> *iq_ptr); 9813531Sjairo.balart@metempsy.com 9913531Sjairo.balart@metempsy.com /** Inserts a memory instruction. */ 10013531Sjairo.balart@metempsy.com void insert(DynInstPtr &inst); 10113531Sjairo.balart@metempsy.com 10213531Sjairo.balart@metempsy.com /** Inserts a non-speculative memory instruction. */ 10313531Sjairo.balart@metempsy.com void insertNonSpec(DynInstPtr &inst); 10413531Sjairo.balart@metempsy.com 10513531Sjairo.balart@metempsy.com /** Inserts a barrier instruction. */ 10613531Sjairo.balart@metempsy.com void insertBarrier(DynInstPtr &barr_inst); 10713531Sjairo.balart@metempsy.com 10813531Sjairo.balart@metempsy.com /** Indicate that an instruction has its registers ready. */ 10913531Sjairo.balart@metempsy.com void regsReady(DynInstPtr &inst); 11013531Sjairo.balart@metempsy.com 11113531Sjairo.balart@metempsy.com /** Indicate that a non-speculative instruction is ready. */ 11213531Sjairo.balart@metempsy.com void nonSpecInstReady(DynInstPtr &inst); 11313531Sjairo.balart@metempsy.com 11413531Sjairo.balart@metempsy.com /** Reschedules an instruction to be re-executed. */ 11513531Sjairo.balart@metempsy.com void reschedule(DynInstPtr &inst); 11613531Sjairo.balart@metempsy.com 11713531Sjairo.balart@metempsy.com /** Replays all instructions that have been rescheduled by moving them to 11813531Sjairo.balart@metempsy.com * the ready list. 11913531Sjairo.balart@metempsy.com */ 12013531Sjairo.balart@metempsy.com void replay(DynInstPtr &inst); 12113531Sjairo.balart@metempsy.com 12213531Sjairo.balart@metempsy.com /** Completes a memory instruction. */ 12313531Sjairo.balart@metempsy.com void completed(DynInstPtr &inst); 12413531Sjairo.balart@metempsy.com 12513531Sjairo.balart@metempsy.com /** Completes a barrier instruction. */ 12613531Sjairo.balart@metempsy.com void completeBarrier(DynInstPtr &inst); 12713531Sjairo.balart@metempsy.com 12813531Sjairo.balart@metempsy.com /** Wakes any dependents of a memory instruction. */ 12913531Sjairo.balart@metempsy.com void wakeDependents(DynInstPtr &inst); 13013531Sjairo.balart@metempsy.com 13113531Sjairo.balart@metempsy.com /** Squashes all instructions up until a given sequence number for a 13213531Sjairo.balart@metempsy.com * specific thread. 13313531Sjairo.balart@metempsy.com */ 13413531Sjairo.balart@metempsy.com void squash(const InstSeqNum &squashed_num, unsigned tid); 13513531Sjairo.balart@metempsy.com 13613531Sjairo.balart@metempsy.com /** Indicates an ordering violation between a store and a younger load. */ 13713531Sjairo.balart@metempsy.com void violation(DynInstPtr &store_inst, DynInstPtr &violating_load); 13813531Sjairo.balart@metempsy.com 13913531Sjairo.balart@metempsy.com /** Issues the given instruction */ 14013531Sjairo.balart@metempsy.com void issue(DynInstPtr &inst); 14113531Sjairo.balart@metempsy.com 14213531Sjairo.balart@metempsy.com /** Debugging function to dump the lists of instructions. */ 14313531Sjairo.balart@metempsy.com void dumpLists(); 14413531Sjairo.balart@metempsy.com 14513531Sjairo.balart@metempsy.com private: 14613531Sjairo.balart@metempsy.com typedef typename std::list<DynInstPtr>::iterator ListIt; 14713531Sjairo.balart@metempsy.com 14813531Sjairo.balart@metempsy.com class MemDepEntry; 14913756Sjairo.balart@metempsy.com 15013531Sjairo.balart@metempsy.com typedef RefCountingPtr<MemDepEntry> MemDepEntryPtr; 15113531Sjairo.balart@metempsy.com 15213531Sjairo.balart@metempsy.com /** Memory dependence entries that track memory operations, marking 15313531Sjairo.balart@metempsy.com * when the instruction is ready to execute and what instructions depend 15413756Sjairo.balart@metempsy.com * upon it. 15513531Sjairo.balart@metempsy.com */ 15613531Sjairo.balart@metempsy.com class MemDepEntry : public RefCounted { 15713531Sjairo.balart@metempsy.com public: 15813531Sjairo.balart@metempsy.com /** Constructs a memory dependence entry. */ 15913531Sjairo.balart@metempsy.com MemDepEntry(DynInstPtr &new_inst) 16013531Sjairo.balart@metempsy.com : inst(new_inst), regsReady(false), memDepReady(false), 16113531Sjairo.balart@metempsy.com completed(false), squashed(false) 16213531Sjairo.balart@metempsy.com { 16313531Sjairo.balart@metempsy.com#ifdef DEBUG 16413756Sjairo.balart@metempsy.com ++memdep_count; 16513756Sjairo.balart@metempsy.com 16613531Sjairo.balart@metempsy.com DPRINTF(MemDepUnit, "Memory dependency entry created. " 16713531Sjairo.balart@metempsy.com "memdep_count=%i\n", memdep_count); 16813531Sjairo.balart@metempsy.com#endif 16913531Sjairo.balart@metempsy.com } 17013531Sjairo.balart@metempsy.com 17113531Sjairo.balart@metempsy.com /** Frees any pointers. */ 17213531Sjairo.balart@metempsy.com ~MemDepEntry() 17313531Sjairo.balart@metempsy.com { 17413531Sjairo.balart@metempsy.com for (int i = 0; i < dependInsts.size(); ++i) { 17513531Sjairo.balart@metempsy.com dependInsts[i] = NULL; 17613531Sjairo.balart@metempsy.com } 17713531Sjairo.balart@metempsy.com#ifdef DEBUG 17813531Sjairo.balart@metempsy.com --memdep_count; 17913531Sjairo.balart@metempsy.com 18013531Sjairo.balart@metempsy.com DPRINTF(MemDepUnit, "Memory dependency entry deleted. " 18113531Sjairo.balart@metempsy.com "memdep_count=%i\n", memdep_count); 18213531Sjairo.balart@metempsy.com#endif 18313531Sjairo.balart@metempsy.com } 18413531Sjairo.balart@metempsy.com 18513756Sjairo.balart@metempsy.com /** Returns the name of the memory dependence entry. */ 18613756Sjairo.balart@metempsy.com std::string name() const { return "memdepentry"; } 18713531Sjairo.balart@metempsy.com 18813531Sjairo.balart@metempsy.com /** The instruction being tracked. */ 18913531Sjairo.balart@metempsy.com DynInstPtr inst; 19013531Sjairo.balart@metempsy.com 19113531Sjairo.balart@metempsy.com /** The iterator to the instruction's location inside the list. */ 19213531Sjairo.balart@metempsy.com ListIt listIt; 19313531Sjairo.balart@metempsy.com 19413531Sjairo.balart@metempsy.com /** A vector of any dependent instructions. */ 19513531Sjairo.balart@metempsy.com std::vector<MemDepEntryPtr> dependInsts; 19613531Sjairo.balart@metempsy.com 19713756Sjairo.balart@metempsy.com /** If the registers are ready or not. */ 19813531Sjairo.balart@metempsy.com bool regsReady; 19913531Sjairo.balart@metempsy.com /** If all memory dependencies have been satisfied. */ 20013531Sjairo.balart@metempsy.com bool memDepReady; 20113531Sjairo.balart@metempsy.com /** If the instruction is completed. */ 20213531Sjairo.balart@metempsy.com bool completed; 20313531Sjairo.balart@metempsy.com /** If the instruction is squashed. */ 20413531Sjairo.balart@metempsy.com bool squashed; 20513531Sjairo.balart@metempsy.com 20613756Sjairo.balart@metempsy.com /** For debugging. */ 20713756Sjairo.balart@metempsy.com#ifdef DEBUG 20813531Sjairo.balart@metempsy.com static int memdep_count; 20913531Sjairo.balart@metempsy.com static int memdep_insert; 21013531Sjairo.balart@metempsy.com static int memdep_erase; 21113531Sjairo.balart@metempsy.com#endif 21213531Sjairo.balart@metempsy.com }; 21313531Sjairo.balart@metempsy.com 21413531Sjairo.balart@metempsy.com /** Finds the memory dependence entry in the hash map. */ 21513531Sjairo.balart@metempsy.com inline MemDepEntryPtr &findInHash(const DynInstPtr &inst); 21613531Sjairo.balart@metempsy.com 21713531Sjairo.balart@metempsy.com /** Moves an entry to the ready list. */ 21813531Sjairo.balart@metempsy.com inline void moveToReady(MemDepEntryPtr &ready_inst_entry); 21913531Sjairo.balart@metempsy.com 22013531Sjairo.balart@metempsy.com typedef m5::hash_map<InstSeqNum, MemDepEntryPtr, SNHash> MemDepHash; 22113756Sjairo.balart@metempsy.com 22213531Sjairo.balart@metempsy.com typedef typename MemDepHash::iterator MemDepHashIt; 22313531Sjairo.balart@metempsy.com 22413531Sjairo.balart@metempsy.com /** A hash map of all memory dependence entries. */ 22513531Sjairo.balart@metempsy.com MemDepHash memDepHash; 22613531Sjairo.balart@metempsy.com 22713531Sjairo.balart@metempsy.com /** A list of all instructions in the memory dependence unit. */ 22813531Sjairo.balart@metempsy.com std::list<DynInstPtr> instList[Impl::MaxThreads]; 22913531Sjairo.balart@metempsy.com 23013756Sjairo.balart@metempsy.com /** A list of all instructions that are going to be replayed. */ 23113756Sjairo.balart@metempsy.com std::list<DynInstPtr> instsToReplay; 23213531Sjairo.balart@metempsy.com 23313531Sjairo.balart@metempsy.com /** The memory dependence predictor. It is accessed upon new 23413531Sjairo.balart@metempsy.com * instructions being added to the IQ, and responds by telling 23513531Sjairo.balart@metempsy.com * this unit what instruction the newly added instruction is dependent 23613531Sjairo.balart@metempsy.com * upon. 23713531Sjairo.balart@metempsy.com */ 23813531Sjairo.balart@metempsy.com MemDepPred depPred; 23913531Sjairo.balart@metempsy.com 24013531Sjairo.balart@metempsy.com /** Is there an outstanding load barrier that loads must wait on. */ 24113531Sjairo.balart@metempsy.com bool loadBarrier; 24213531Sjairo.balart@metempsy.com /** The sequence number of the load barrier. */ 24313531Sjairo.balart@metempsy.com InstSeqNum loadBarrierSN; 24413756Sjairo.balart@metempsy.com /** Is there an outstanding store barrier that loads must wait on. */ 24513531Sjairo.balart@metempsy.com bool storeBarrier; 24613531Sjairo.balart@metempsy.com /** The sequence number of the store barrier. */ 24713531Sjairo.balart@metempsy.com InstSeqNum storeBarrierSN; 24813531Sjairo.balart@metempsy.com 24913531Sjairo.balart@metempsy.com /** Pointer to the IQ. */ 25013531Sjairo.balart@metempsy.com InstructionQueue<Impl> *iqPtr; 25113531Sjairo.balart@metempsy.com 25213531Sjairo.balart@metempsy.com /** The thread id of this memory dependence unit. */ 25313531Sjairo.balart@metempsy.com int id; 25413531Sjairo.balart@metempsy.com 25513756Sjairo.balart@metempsy.com /** Stat for number of inserted loads. */ 25613756Sjairo.balart@metempsy.com Stats::Scalar<> insertedLoads; 25713531Sjairo.balart@metempsy.com /** Stat for number of inserted stores. */ 25813531Sjairo.balart@metempsy.com Stats::Scalar<> insertedStores; 25913531Sjairo.balart@metempsy.com /** Stat for number of conflicting loads that had to wait for a store. */ 26013531Sjairo.balart@metempsy.com Stats::Scalar<> conflictingLoads; 26113531Sjairo.balart@metempsy.com /** Stat for number of conflicting stores that had to wait for a store. */ 26213531Sjairo.balart@metempsy.com Stats::Scalar<> conflictingStores; 26313531Sjairo.balart@metempsy.com}; 26413531Sjairo.balart@metempsy.com 26513531Sjairo.balart@metempsy.com#endif // __CPU_O3_MEM_DEP_UNIT_HH__ 26613531Sjairo.balart@metempsy.com