mem_dep_unit_impl.hh revision 8519
1955SN/A/* 2955SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan 313576Sciro.santilli@arm.com * All rights reserved. 413576Sciro.santilli@arm.com * 513576Sciro.santilli@arm.com * Redistribution and use in source and binary forms, with or without 613576Sciro.santilli@arm.com * modification, are permitted provided that the following conditions are 713576Sciro.santilli@arm.com * met: redistributions of source code must retain the above copyright 813576Sciro.santilli@arm.com * notice, this list of conditions and the following disclaimer; 913576Sciro.santilli@arm.com * redistributions in binary form must reproduce the above copyright 1013576Sciro.santilli@arm.com * notice, this list of conditions and the following disclaimer in the 1113576Sciro.santilli@arm.com * documentation and/or other materials provided with the distribution; 1213576Sciro.santilli@arm.com * neither the name of the copyright holders nor the names of its 1313576Sciro.santilli@arm.com * contributors may be used to endorse or promote products derived from 141762SN/A * this software without specific prior written permission. 15955SN/A * 16955SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27955SN/A * 28955SN/A * Authors: Kevin Lim 29955SN/A */ 30955SN/A 31955SN/A#include <map> 32955SN/A 33955SN/A#include "cpu/o3/inst_queue.hh" 34955SN/A#include "cpu/o3/mem_dep_unit.hh" 35955SN/A#include "debug/MemDepUnit.hh" 36955SN/A#include "params/DerivO3CPU.hh" 37955SN/A 38955SN/Atemplate <class MemDepPred, class Impl> 392665Ssaidi@eecs.umich.eduMemDepUnit<MemDepPred, Impl>::MemDepUnit() 404762Snate@binkert.org : loadBarrier(false), loadBarrierSN(0), storeBarrier(false), 41955SN/A storeBarrierSN(0), iqPtr(NULL) 4212563Sgabeblack@google.com{ 4312563Sgabeblack@google.com} 445522Snate@binkert.org 456143Snate@binkert.orgtemplate <class MemDepPred, class Impl> 4612371Sgabeblack@google.comMemDepUnit<MemDepPred, Impl>::MemDepUnit(DerivO3CPUParams *params) 474762Snate@binkert.org : _name(params->name + ".memdepunit"), 485522Snate@binkert.org depPred(params->store_set_clear_period, params->SSITSize, 49955SN/A params->LFSTSize), 505522Snate@binkert.org loadBarrier(false), loadBarrierSN(0), storeBarrier(false), 5111974Sgabeblack@google.com storeBarrierSN(0), iqPtr(NULL) 52955SN/A{ 535522Snate@binkert.org DPRINTF(MemDepUnit, "Creating MemDepUnit object.\n"); 544202Sbinkertn@umich.edu} 555742Snate@binkert.org 56955SN/Atemplate <class MemDepPred, class Impl> 574381Sbinkertn@umich.eduMemDepUnit<MemDepPred, Impl>::~MemDepUnit() 584381Sbinkertn@umich.edu{ 5912246Sgabeblack@google.com for (ThreadID tid = 0; tid < Impl::MaxThreads; tid++) { 6012246Sgabeblack@google.com 618334Snate@binkert.org ListIt inst_list_it = instList[tid].begin(); 62955SN/A 63955SN/A MemDepHashIt hash_it; 644202Sbinkertn@umich.edu 65955SN/A while (!instList[tid].empty()) { 664382Sbinkertn@umich.edu hash_it = memDepHash.find((*inst_list_it)->seqNum); 674382Sbinkertn@umich.edu 684382Sbinkertn@umich.edu assert(hash_it != memDepHash.end()); 696654Snate@binkert.org 705517Snate@binkert.org memDepHash.erase(hash_it); 718614Sgblack@eecs.umich.edu 727674Snate@binkert.org instList[tid].erase(inst_list_it++); 736143Snate@binkert.org } 746143Snate@binkert.org } 756143Snate@binkert.org 7612302Sgabeblack@google.com#ifdef DEBUG 7712302Sgabeblack@google.com assert(MemDepEntry::memdep_count == 0); 7812302Sgabeblack@google.com#endif 7912371Sgabeblack@google.com} 8012371Sgabeblack@google.com 8112371Sgabeblack@google.comtemplate <class MemDepPred, class Impl> 8212371Sgabeblack@google.comvoid 8312371Sgabeblack@google.comMemDepUnit<MemDepPred, Impl>::init(DerivO3CPUParams *params, ThreadID tid) 8412371Sgabeblack@google.com{ 8512371Sgabeblack@google.com DPRINTF(MemDepUnit, "Creating MemDepUnit %i object.\n",tid); 8612371Sgabeblack@google.com 8712371Sgabeblack@google.com _name = csprintf("%s.memDep%d", params->name, tid); 8812371Sgabeblack@google.com id = tid; 8912371Sgabeblack@google.com 9012371Sgabeblack@google.com depPred.init(params->store_set_clear_period, params->SSITSize, 9112371Sgabeblack@google.com params->LFSTSize); 9212371Sgabeblack@google.com} 9312371Sgabeblack@google.com 9412371Sgabeblack@google.comtemplate <class MemDepPred, class Impl> 9512371Sgabeblack@google.comvoid 9612371Sgabeblack@google.comMemDepUnit<MemDepPred, Impl>::regStats() 9712371Sgabeblack@google.com{ 9812371Sgabeblack@google.com insertedLoads 9912371Sgabeblack@google.com .name(name() + ".insertedLoads") 10012371Sgabeblack@google.com .desc("Number of loads inserted to the mem dependence unit."); 10112371Sgabeblack@google.com 10212371Sgabeblack@google.com insertedStores 10312371Sgabeblack@google.com .name(name() + ".insertedStores") 10412371Sgabeblack@google.com .desc("Number of stores inserted to the mem dependence unit."); 10512371Sgabeblack@google.com 10612371Sgabeblack@google.com conflictingLoads 10712371Sgabeblack@google.com .name(name() + ".conflictingLoads") 10812371Sgabeblack@google.com .desc("Number of conflicting loads."); 10912371Sgabeblack@google.com 11012371Sgabeblack@google.com conflictingStores 11112371Sgabeblack@google.com .name(name() + ".conflictingStores") 11212371Sgabeblack@google.com .desc("Number of conflicting stores."); 11312371Sgabeblack@google.com} 11412371Sgabeblack@google.com 11512371Sgabeblack@google.comtemplate <class MemDepPred, class Impl> 11612371Sgabeblack@google.comvoid 11712371Sgabeblack@google.comMemDepUnit<MemDepPred, Impl>::switchOut() 11812371Sgabeblack@google.com{ 11912371Sgabeblack@google.com assert(instList[0].empty()); 12012371Sgabeblack@google.com assert(instsToReplay.empty()); 12112371Sgabeblack@google.com assert(memDepHash.empty()); 12212371Sgabeblack@google.com // Clear any state. 12312371Sgabeblack@google.com for (int i = 0; i < Impl::MaxThreads; ++i) { 12412371Sgabeblack@google.com instList[i].clear(); 12512371Sgabeblack@google.com } 12612302Sgabeblack@google.com instsToReplay.clear(); 12712371Sgabeblack@google.com memDepHash.clear(); 12812302Sgabeblack@google.com} 12912371Sgabeblack@google.com 13012302Sgabeblack@google.comtemplate <class MemDepPred, class Impl> 13112302Sgabeblack@google.comvoid 13212371Sgabeblack@google.comMemDepUnit<MemDepPred, Impl>::takeOverFrom() 13312371Sgabeblack@google.com{ 13412371Sgabeblack@google.com // Be sure to reset all state. 13512371Sgabeblack@google.com loadBarrier = storeBarrier = false; 13612302Sgabeblack@google.com loadBarrierSN = storeBarrierSN = 0; 13712371Sgabeblack@google.com depPred.clear(); 13812371Sgabeblack@google.com} 13912371Sgabeblack@google.com 14012371Sgabeblack@google.comtemplate <class MemDepPred, class Impl> 14111983Sgabeblack@google.comvoid 1426143Snate@binkert.orgMemDepUnit<MemDepPred, Impl>::setIQ(InstructionQueue<Impl> *iq_ptr) 1438233Snate@binkert.org{ 14412302Sgabeblack@google.com iqPtr = iq_ptr; 1456143Snate@binkert.org} 1466143Snate@binkert.org 14712302Sgabeblack@google.comtemplate <class MemDepPred, class Impl> 1484762Snate@binkert.orgvoid 1496143Snate@binkert.orgMemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst) 1508233Snate@binkert.org{ 1518233Snate@binkert.org ThreadID tid = inst->threadNumber; 15212302Sgabeblack@google.com 15312302Sgabeblack@google.com MemDepEntryPtr inst_entry = new MemDepEntry(inst); 1546143Snate@binkert.org 15512362Sgabeblack@google.com // Add the MemDepEntry to the hash. 15612362Sgabeblack@google.com memDepHash.insert( 15712362Sgabeblack@google.com std::pair<InstSeqNum, MemDepEntryPtr>(inst->seqNum, inst_entry)); 15812362Sgabeblack@google.com#ifdef DEBUG 15912302Sgabeblack@google.com MemDepEntry::memdep_insert++; 16012302Sgabeblack@google.com#endif 16112302Sgabeblack@google.com 16212302Sgabeblack@google.com instList[tid].push_back(inst); 16312302Sgabeblack@google.com 16412363Sgabeblack@google.com inst_entry->listIt = --(instList[tid].end()); 16512363Sgabeblack@google.com 16612363Sgabeblack@google.com // Check any barriers and the dependence predictor for any 16712363Sgabeblack@google.com // producing memrefs/stores. 16812302Sgabeblack@google.com InstSeqNum producing_store; 16912363Sgabeblack@google.com if (inst->isLoad() && loadBarrier) { 17012363Sgabeblack@google.com DPRINTF(MemDepUnit, "Load barrier [sn:%lli] in flight\n", 17112363Sgabeblack@google.com loadBarrierSN); 17212363Sgabeblack@google.com producing_store = loadBarrierSN; 17312363Sgabeblack@google.com } else if (inst->isStore() && storeBarrier) { 1748233Snate@binkert.org DPRINTF(MemDepUnit, "Store barrier [sn:%lli] in flight\n", 1756143Snate@binkert.org storeBarrierSN); 1766143Snate@binkert.org producing_store = storeBarrierSN; 1776143Snate@binkert.org } else { 1786143Snate@binkert.org producing_store = depPred.checkInst(inst->instAddr()); 1796143Snate@binkert.org } 1806143Snate@binkert.org 1816143Snate@binkert.org MemDepEntryPtr store_entry = NULL; 1826143Snate@binkert.org 1836143Snate@binkert.org // If there is a producing store, try to find the entry. 1847065Snate@binkert.org if (producing_store != 0) { 1856143Snate@binkert.org DPRINTF(MemDepUnit, "Searching for producer\n"); 18612362Sgabeblack@google.com MemDepHashIt hash_it = memDepHash.find(producing_store); 18712362Sgabeblack@google.com 18812362Sgabeblack@google.com if (hash_it != memDepHash.end()) { 18912362Sgabeblack@google.com store_entry = (*hash_it).second; 19012362Sgabeblack@google.com DPRINTF(MemDepUnit, "Proucer found\n"); 19112362Sgabeblack@google.com } 19212362Sgabeblack@google.com } 19312362Sgabeblack@google.com 19412362Sgabeblack@google.com // If no store entry, then instruction can issue as soon as the registers 19512362Sgabeblack@google.com // are ready. 19612362Sgabeblack@google.com if (!store_entry) { 19712362Sgabeblack@google.com DPRINTF(MemDepUnit, "No dependency for inst PC " 1988233Snate@binkert.org "%s [sn:%lli].\n", inst->pcState(), inst->seqNum); 1998233Snate@binkert.org 2008233Snate@binkert.org inst_entry->memDepReady = true; 2018233Snate@binkert.org 2028233Snate@binkert.org if (inst->readyToIssue()) { 2038233Snate@binkert.org inst_entry->regsReady = true; 2048233Snate@binkert.org 2058233Snate@binkert.org moveToReady(inst_entry); 2068233Snate@binkert.org } 2078233Snate@binkert.org } else { 2088233Snate@binkert.org // Otherwise make the instruction dependent on the store/barrier. 2098233Snate@binkert.org DPRINTF(MemDepUnit, "Adding to dependency list; " 2108233Snate@binkert.org "inst PC %s is dependent on [sn:%lli].\n", 2118233Snate@binkert.org inst->pcState(), producing_store); 2128233Snate@binkert.org 2138233Snate@binkert.org if (inst->readyToIssue()) { 2148233Snate@binkert.org inst_entry->regsReady = true; 2158233Snate@binkert.org } 2168233Snate@binkert.org 2178233Snate@binkert.org // Clear the bit saying this instruction can issue. 2188233Snate@binkert.org inst->clearCanIssue(); 2196143Snate@binkert.org 2206143Snate@binkert.org // Add this instruction to the list of dependents. 2216143Snate@binkert.org store_entry->dependInsts.push_back(inst_entry); 2226143Snate@binkert.org 2236143Snate@binkert.org if (inst->isLoad()) { 2246143Snate@binkert.org ++conflictingLoads; 2259982Satgutier@umich.edu } else { 22613576Sciro.santilli@arm.com ++conflictingStores; 22713576Sciro.santilli@arm.com } 22813576Sciro.santilli@arm.com } 22913576Sciro.santilli@arm.com 23013576Sciro.santilli@arm.com if (inst->isStore()) { 23113576Sciro.santilli@arm.com DPRINTF(MemDepUnit, "Inserting store PC %s [sn:%lli].\n", 23213576Sciro.santilli@arm.com inst->pcState(), inst->seqNum); 23313576Sciro.santilli@arm.com 23413576Sciro.santilli@arm.com depPred.insertStore(inst->instAddr(), inst->seqNum, inst->threadNumber); 23513576Sciro.santilli@arm.com 23613576Sciro.santilli@arm.com ++insertedStores; 23713576Sciro.santilli@arm.com } else if (inst->isLoad()) { 23813576Sciro.santilli@arm.com ++insertedLoads; 23913576Sciro.santilli@arm.com } else { 24013576Sciro.santilli@arm.com panic("Unknown type! (most likely a barrier)."); 24113576Sciro.santilli@arm.com } 24213576Sciro.santilli@arm.com} 24313576Sciro.santilli@arm.com 24413576Sciro.santilli@arm.comtemplate <class MemDepPred, class Impl> 24513576Sciro.santilli@arm.comvoid 24613576Sciro.santilli@arm.comMemDepUnit<MemDepPred, Impl>::insertNonSpec(DynInstPtr &inst) 24713576Sciro.santilli@arm.com{ 24813576Sciro.santilli@arm.com ThreadID tid = inst->threadNumber; 24913576Sciro.santilli@arm.com 25013576Sciro.santilli@arm.com MemDepEntryPtr inst_entry = new MemDepEntry(inst); 25113576Sciro.santilli@arm.com 25213576Sciro.santilli@arm.com // Insert the MemDepEntry into the hash. 25313576Sciro.santilli@arm.com memDepHash.insert( 25413576Sciro.santilli@arm.com std::pair<InstSeqNum, MemDepEntryPtr>(inst->seqNum, inst_entry)); 25513576Sciro.santilli@arm.com#ifdef DEBUG 25613576Sciro.santilli@arm.com MemDepEntry::memdep_insert++; 25713576Sciro.santilli@arm.com#endif 25813576Sciro.santilli@arm.com 25913576Sciro.santilli@arm.com // Add the instruction to the list. 26013576Sciro.santilli@arm.com instList[tid].push_back(inst); 26113576Sciro.santilli@arm.com 26213576Sciro.santilli@arm.com inst_entry->listIt = --(instList[tid].end()); 26313576Sciro.santilli@arm.com 26413576Sciro.santilli@arm.com // Might want to turn this part into an inline function or something. 26513576Sciro.santilli@arm.com // It's shared between both insert functions. 26613576Sciro.santilli@arm.com if (inst->isStore()) { 26713576Sciro.santilli@arm.com DPRINTF(MemDepUnit, "Inserting store PC %s [sn:%lli].\n", 26813576Sciro.santilli@arm.com inst->pcState(), inst->seqNum); 26913576Sciro.santilli@arm.com 27013576Sciro.santilli@arm.com depPred.insertStore(inst->instAddr(), inst->seqNum, inst->threadNumber); 27113576Sciro.santilli@arm.com 27213576Sciro.santilli@arm.com ++insertedStores; 27313576Sciro.santilli@arm.com } else if (inst->isLoad()) { 27413576Sciro.santilli@arm.com ++insertedLoads; 27513576Sciro.santilli@arm.com } else { 27613576Sciro.santilli@arm.com panic("Unknown type! (most likely a barrier)."); 27713576Sciro.santilli@arm.com } 27813576Sciro.santilli@arm.com} 27913576Sciro.santilli@arm.com 28013576Sciro.santilli@arm.comtemplate <class MemDepPred, class Impl> 28113576Sciro.santilli@arm.comvoid 28213576Sciro.santilli@arm.comMemDepUnit<MemDepPred, Impl>::insertBarrier(DynInstPtr &barr_inst) 28313576Sciro.santilli@arm.com{ 28413576Sciro.santilli@arm.com InstSeqNum barr_sn = barr_inst->seqNum; 28513576Sciro.santilli@arm.com // Memory barriers block loads and stores, write barriers only stores. 28613576Sciro.santilli@arm.com if (barr_inst->isMemBarrier()) { 28713576Sciro.santilli@arm.com loadBarrier = true; 28813576Sciro.santilli@arm.com loadBarrierSN = barr_sn; 28913576Sciro.santilli@arm.com storeBarrier = true; 29013576Sciro.santilli@arm.com storeBarrierSN = barr_sn; 29113576Sciro.santilli@arm.com DPRINTF(MemDepUnit, "Inserted a memory barrier %s SN:%lli\n", 29213576Sciro.santilli@arm.com barr_inst->pcState(),barr_sn); 29313576Sciro.santilli@arm.com } else if (barr_inst->isWriteBarrier()) { 29413576Sciro.santilli@arm.com storeBarrier = true; 29513576Sciro.santilli@arm.com storeBarrierSN = barr_sn; 2966143Snate@binkert.org DPRINTF(MemDepUnit, "Inserted a write barrier\n"); 29712302Sgabeblack@google.com } 29812302Sgabeblack@google.com 29912302Sgabeblack@google.com ThreadID tid = barr_inst->threadNumber; 30012302Sgabeblack@google.com 30112302Sgabeblack@google.com MemDepEntryPtr inst_entry = new MemDepEntry(barr_inst); 30212302Sgabeblack@google.com 30312302Sgabeblack@google.com // Add the MemDepEntry to the hash. 30412302Sgabeblack@google.com memDepHash.insert( 30511983Sgabeblack@google.com std::pair<InstSeqNum, MemDepEntryPtr>(barr_sn, inst_entry)); 30611983Sgabeblack@google.com#ifdef DEBUG 30711983Sgabeblack@google.com MemDepEntry::memdep_insert++; 30812302Sgabeblack@google.com#endif 30912302Sgabeblack@google.com 31012302Sgabeblack@google.com // Add the instruction to the instruction list. 31112302Sgabeblack@google.com instList[tid].push_back(barr_inst); 31212302Sgabeblack@google.com 31312302Sgabeblack@google.com inst_entry->listIt = --(instList[tid].end()); 31411983Sgabeblack@google.com} 3156143Snate@binkert.org 31612305Sgabeblack@google.comtemplate <class MemDepPred, class Impl> 31712302Sgabeblack@google.comvoid 31812302Sgabeblack@google.comMemDepUnit<MemDepPred, Impl>::regsReady(DynInstPtr &inst) 31912302Sgabeblack@google.com{ 3206143Snate@binkert.org DPRINTF(MemDepUnit, "Marking registers as ready for " 3216143Snate@binkert.org "instruction PC %s [sn:%lli].\n", 3226143Snate@binkert.org inst->pcState(), inst->seqNum); 3235522Snate@binkert.org 3246143Snate@binkert.org MemDepEntryPtr inst_entry = findInHash(inst); 3256143Snate@binkert.org 3266143Snate@binkert.org inst_entry->regsReady = true; 3279982Satgutier@umich.edu 32812302Sgabeblack@google.com if (inst_entry->memDepReady) { 32912302Sgabeblack@google.com DPRINTF(MemDepUnit, "Instruction has its memory " 33012302Sgabeblack@google.com "dependencies resolved, adding it to the ready list.\n"); 3316143Snate@binkert.org 3326143Snate@binkert.org moveToReady(inst_entry); 3336143Snate@binkert.org } else { 3346143Snate@binkert.org DPRINTF(MemDepUnit, "Instruction still waiting on " 3355522Snate@binkert.org "memory dependency.\n"); 3365522Snate@binkert.org } 3375522Snate@binkert.org} 3385522Snate@binkert.org 3395604Snate@binkert.orgtemplate <class MemDepPred, class Impl> 3405604Snate@binkert.orgvoid 3416143Snate@binkert.orgMemDepUnit<MemDepPred, Impl>::nonSpecInstReady(DynInstPtr &inst) 3426143Snate@binkert.org{ 3434762Snate@binkert.org DPRINTF(MemDepUnit, "Marking non speculative " 3444762Snate@binkert.org "instruction PC %s as ready [sn:%lli].\n", 3456143Snate@binkert.org inst->pcState(), inst->seqNum); 3466727Ssteve.reinhardt@amd.com 3476727Ssteve.reinhardt@amd.com MemDepEntryPtr inst_entry = findInHash(inst); 3486727Ssteve.reinhardt@amd.com 3494762Snate@binkert.org moveToReady(inst_entry); 3506143Snate@binkert.org} 3516143Snate@binkert.org 3526143Snate@binkert.orgtemplate <class MemDepPred, class Impl> 3536143Snate@binkert.orgvoid 3546727Ssteve.reinhardt@amd.comMemDepUnit<MemDepPred, Impl>::reschedule(DynInstPtr &inst) 3556143Snate@binkert.org{ 3567674Snate@binkert.org instsToReplay.push_back(inst); 3577674Snate@binkert.org} 3585604Snate@binkert.org 3596143Snate@binkert.orgtemplate <class MemDepPred, class Impl> 3606143Snate@binkert.orgvoid 3616143Snate@binkert.orgMemDepUnit<MemDepPred, Impl>::replay(DynInstPtr &inst) 3624762Snate@binkert.org{ 3636143Snate@binkert.org DynInstPtr temp_inst; 3644762Snate@binkert.org 3654762Snate@binkert.org // For now this replay function replays all waiting memory ops. 3664762Snate@binkert.org while (!instsToReplay.empty()) { 3676143Snate@binkert.org temp_inst = instsToReplay.front(); 3686143Snate@binkert.org 3694762Snate@binkert.org MemDepEntryPtr inst_entry = findInHash(temp_inst); 37012302Sgabeblack@google.com 37112302Sgabeblack@google.com DPRINTF(MemDepUnit, "Replaying mem instruction PC %s [sn:%lli].\n", 3728233Snate@binkert.org temp_inst->pcState(), temp_inst->seqNum); 37312302Sgabeblack@google.com 3746143Snate@binkert.org moveToReady(inst_entry); 3756143Snate@binkert.org 3764762Snate@binkert.org instsToReplay.pop_front(); 3776143Snate@binkert.org } 3784762Snate@binkert.org} 3799396Sandreas.hansson@arm.com 3809396Sandreas.hansson@arm.comtemplate <class MemDepPred, class Impl> 3819396Sandreas.hansson@arm.comvoid 38212302Sgabeblack@google.comMemDepUnit<MemDepPred, Impl>::completed(DynInstPtr &inst) 38312302Sgabeblack@google.com{ 38412302Sgabeblack@google.com DPRINTF(MemDepUnit, "Completed mem instruction PC %s [sn:%lli].\n", 3859396Sandreas.hansson@arm.com inst->pcState(), inst->seqNum); 3869396Sandreas.hansson@arm.com 3879396Sandreas.hansson@arm.com ThreadID tid = inst->threadNumber; 3889396Sandreas.hansson@arm.com 3899396Sandreas.hansson@arm.com // Remove the instruction from the hash and the list. 3909396Sandreas.hansson@arm.com MemDepHashIt hash_it = memDepHash.find(inst->seqNum); 3919396Sandreas.hansson@arm.com 3929930Sandreas.hansson@arm.com assert(hash_it != memDepHash.end()); 3939930Sandreas.hansson@arm.com 3949396Sandreas.hansson@arm.com instList[tid].erase((*hash_it).second->listIt); 3956143Snate@binkert.org 39612797Sgabeblack@google.com (*hash_it).second = NULL; 39712797Sgabeblack@google.com 39812797Sgabeblack@google.com memDepHash.erase(hash_it); 3998235Snate@binkert.org#ifdef DEBUG 40012797Sgabeblack@google.com MemDepEntry::memdep_erase++; 40112797Sgabeblack@google.com#endif 40212797Sgabeblack@google.com} 40312797Sgabeblack@google.com 40412797Sgabeblack@google.comtemplate <class MemDepPred, class Impl> 40512797Sgabeblack@google.comvoid 40612797Sgabeblack@google.comMemDepUnit<MemDepPred, Impl>::completeBarrier(DynInstPtr &inst) 40712797Sgabeblack@google.com{ 40812797Sgabeblack@google.com wakeDependents(inst); 40912797Sgabeblack@google.com completed(inst); 41012797Sgabeblack@google.com 41112797Sgabeblack@google.com InstSeqNum barr_sn = inst->seqNum; 41212797Sgabeblack@google.com DPRINTF(MemDepUnit, "barrier completed: %s SN:%lli\n", inst->pcState(), 41312797Sgabeblack@google.com inst->seqNum); 41412797Sgabeblack@google.com if (inst->isMemBarrier()) { 41512757Sgabeblack@google.com if (loadBarrierSN == barr_sn) 41612757Sgabeblack@google.com loadBarrier = false; 41712797Sgabeblack@google.com if (storeBarrierSN == barr_sn) 41812797Sgabeblack@google.com storeBarrier = false; 41912797Sgabeblack@google.com } else if (inst->isWriteBarrier()) { 42012757Sgabeblack@google.com if (storeBarrierSN == barr_sn) 42112757Sgabeblack@google.com storeBarrier = false; 42212757Sgabeblack@google.com } 42312757Sgabeblack@google.com} 4248235Snate@binkert.org 42512302Sgabeblack@google.comtemplate <class MemDepPred, class Impl> 4268235Snate@binkert.orgvoid 4278235Snate@binkert.orgMemDepUnit<MemDepPred, Impl>::wakeDependents(DynInstPtr &inst) 42812757Sgabeblack@google.com{ 4298235Snate@binkert.org // Only stores and barriers have dependents. 4308235Snate@binkert.org if (!inst->isStore() && !inst->isMemBarrier() && !inst->isWriteBarrier()) { 4318235Snate@binkert.org return; 43212757Sgabeblack@google.com } 43312313Sgabeblack@google.com 43412797Sgabeblack@google.com MemDepEntryPtr inst_entry = findInHash(inst); 43512797Sgabeblack@google.com 43612797Sgabeblack@google.com for (int i = 0; i < inst_entry->dependInsts.size(); ++i ) { 43712797Sgabeblack@google.com MemDepEntryPtr woken_inst = inst_entry->dependInsts[i]; 43812797Sgabeblack@google.com 43912797Sgabeblack@google.com if (!woken_inst->inst) { 44012797Sgabeblack@google.com // Potentially removed mem dep entries could be on this list 44112797Sgabeblack@google.com continue; 44212797Sgabeblack@google.com } 44312797Sgabeblack@google.com 44412797Sgabeblack@google.com DPRINTF(MemDepUnit, "Waking up a dependent inst, " 44512797Sgabeblack@google.com "[sn:%lli].\n", 44612797Sgabeblack@google.com woken_inst->inst->seqNum); 44712797Sgabeblack@google.com 44812797Sgabeblack@google.com if (woken_inst->regsReady && !woken_inst->squashed) { 44912797Sgabeblack@google.com moveToReady(woken_inst); 45012797Sgabeblack@google.com } else { 45112797Sgabeblack@google.com woken_inst->memDepReady = true; 45212797Sgabeblack@google.com } 45312797Sgabeblack@google.com } 45412797Sgabeblack@google.com 45512797Sgabeblack@google.com inst_entry->dependInsts.clear(); 45612797Sgabeblack@google.com} 45712797Sgabeblack@google.com 45812797Sgabeblack@google.comtemplate <class MemDepPred, class Impl> 45912797Sgabeblack@google.comvoid 46012797Sgabeblack@google.comMemDepUnit<MemDepPred, Impl>::squash(const InstSeqNum &squashed_num, 46112797Sgabeblack@google.com ThreadID tid) 46212797Sgabeblack@google.com{ 46312797Sgabeblack@google.com if (!instsToReplay.empty()) { 46412797Sgabeblack@google.com ListIt replay_it = instsToReplay.begin(); 46512797Sgabeblack@google.com while (replay_it != instsToReplay.end()) { 46612797Sgabeblack@google.com if ((*replay_it)->threadNumber == tid && 46712797Sgabeblack@google.com (*replay_it)->seqNum > squashed_num) { 46812797Sgabeblack@google.com instsToReplay.erase(replay_it++); 46912797Sgabeblack@google.com } else { 47012797Sgabeblack@google.com ++replay_it; 47112797Sgabeblack@google.com } 47212797Sgabeblack@google.com } 47312797Sgabeblack@google.com } 47412797Sgabeblack@google.com 47512797Sgabeblack@google.com ListIt squash_it = instList[tid].end(); 47612797Sgabeblack@google.com --squash_it; 47712797Sgabeblack@google.com 47812313Sgabeblack@google.com MemDepHashIt hash_it; 47912313Sgabeblack@google.com 48012797Sgabeblack@google.com while (!instList[tid].empty() && 48112797Sgabeblack@google.com (*squash_it)->seqNum > squashed_num) { 48212797Sgabeblack@google.com 48312371Sgabeblack@google.com DPRINTF(MemDepUnit, "Squashing inst [sn:%lli]\n", 4845584Snate@binkert.org (*squash_it)->seqNum); 48512797Sgabeblack@google.com 48612797Sgabeblack@google.com if ((*squash_it)->seqNum == loadBarrierSN) 48712797Sgabeblack@google.com loadBarrier = false; 48812797Sgabeblack@google.com 48912797Sgabeblack@google.com if ((*squash_it)->seqNum == storeBarrierSN) 49012797Sgabeblack@google.com storeBarrier = false; 49112797Sgabeblack@google.com 49212797Sgabeblack@google.com hash_it = memDepHash.find((*squash_it)->seqNum); 49312797Sgabeblack@google.com 49412797Sgabeblack@google.com assert(hash_it != memDepHash.end()); 49512797Sgabeblack@google.com 49612797Sgabeblack@google.com (*hash_it).second->squashed = true; 49712797Sgabeblack@google.com 49812797Sgabeblack@google.com (*hash_it).second = NULL; 49912797Sgabeblack@google.com 50012797Sgabeblack@google.com memDepHash.erase(hash_it); 50112797Sgabeblack@google.com#ifdef DEBUG 50212797Sgabeblack@google.com MemDepEntry::memdep_erase++; 50312797Sgabeblack@google.com#endif 50412797Sgabeblack@google.com 50512797Sgabeblack@google.com instList[tid].erase(squash_it--); 50612797Sgabeblack@google.com } 50712797Sgabeblack@google.com 50812797Sgabeblack@google.com // Tell the dependency predictor to squash as well. 50912797Sgabeblack@google.com depPred.squash(squashed_num, tid); 51012797Sgabeblack@google.com} 51112797Sgabeblack@google.com 51212797Sgabeblack@google.comtemplate <class MemDepPred, class Impl> 51312797Sgabeblack@google.comvoid 51412797Sgabeblack@google.comMemDepUnit<MemDepPred, Impl>::violation(DynInstPtr &store_inst, 51512797Sgabeblack@google.com DynInstPtr &violating_load) 51612797Sgabeblack@google.com{ 51712797Sgabeblack@google.com DPRINTF(MemDepUnit, "Passing violating PCs to store sets," 51812797Sgabeblack@google.com " load: %#x, store: %#x\n", violating_load->instAddr(), 51912797Sgabeblack@google.com store_inst->instAddr()); 52012797Sgabeblack@google.com // Tell the memory dependence unit of the violation. 52112797Sgabeblack@google.com depPred.violation(store_inst->instAddr(), violating_load->instAddr()); 52212797Sgabeblack@google.com} 5234382Sbinkertn@umich.edu 52413576Sciro.santilli@arm.comtemplate <class MemDepPred, class Impl> 5254202Sbinkertn@umich.eduvoid 5264382Sbinkertn@umich.eduMemDepUnit<MemDepPred, Impl>::issue(DynInstPtr &inst) 5274382Sbinkertn@umich.edu{ 5289396Sandreas.hansson@arm.com DPRINTF(MemDepUnit, "Issuing instruction PC %#x [sn:%lli].\n", 52912797Sgabeblack@google.com inst->instAddr(), inst->seqNum); 5305584Snate@binkert.org 53112313Sgabeblack@google.com depPred.issued(inst->instAddr(), inst->seqNum, inst->isStore()); 5324382Sbinkertn@umich.edu} 5334382Sbinkertn@umich.edu 5344382Sbinkertn@umich.edutemplate <class MemDepPred, class Impl> 5358232Snate@binkert.orginline typename MemDepUnit<MemDepPred,Impl>::MemDepEntryPtr & 5365192Ssaidi@eecs.umich.eduMemDepUnit<MemDepPred, Impl>::findInHash(const DynInstPtr &inst) 5378232Snate@binkert.org{ 5388232Snate@binkert.org MemDepHashIt hash_it = memDepHash.find(inst->seqNum); 5398232Snate@binkert.org 5405192Ssaidi@eecs.umich.edu assert(hash_it != memDepHash.end()); 5418232Snate@binkert.org 5425192Ssaidi@eecs.umich.edu return (*hash_it).second; 5435799Snate@binkert.org} 5448232Snate@binkert.org 5455192Ssaidi@eecs.umich.edutemplate <class MemDepPred, class Impl> 5465192Ssaidi@eecs.umich.eduinline void 5475192Ssaidi@eecs.umich.eduMemDepUnit<MemDepPred, Impl>::moveToReady(MemDepEntryPtr &woken_inst_entry) 5488232Snate@binkert.org{ 5495192Ssaidi@eecs.umich.edu DPRINTF(MemDepUnit, "Adding instruction [sn:%lli] " 5508232Snate@binkert.org "to the ready list.\n", woken_inst_entry->inst->seqNum); 5515192Ssaidi@eecs.umich.edu 5525192Ssaidi@eecs.umich.edu assert(!woken_inst_entry->squashed); 5535192Ssaidi@eecs.umich.edu 5545192Ssaidi@eecs.umich.edu iqPtr->addReadyMemInst(woken_inst_entry->inst); 5554382Sbinkertn@umich.edu} 5564382Sbinkertn@umich.edu 5574382Sbinkertn@umich.edu 5582667Sstever@eecs.umich.edutemplate <class MemDepPred, class Impl> 5592667Sstever@eecs.umich.eduvoid 5602667Sstever@eecs.umich.eduMemDepUnit<MemDepPred, Impl>::dumpLists() 5612667Sstever@eecs.umich.edu{ 5622667Sstever@eecs.umich.edu for (ThreadID tid = 0; tid < Impl::MaxThreads; tid++) { 5632667Sstever@eecs.umich.edu cprintf("Instruction list %i size: %i\n", 5645742Snate@binkert.org tid, instList[tid].size()); 5655742Snate@binkert.org 5665742Snate@binkert.org ListIt inst_list_it = instList[tid].begin(); 5675793Snate@binkert.org int num = 0; 5688334Snate@binkert.org 5695793Snate@binkert.org while (inst_list_it != instList[tid].end()) { 5705793Snate@binkert.org cprintf("Instruction:%i\nPC: %s\n[sn:%i]\n[tid:%i]\nIssued:%i\n" 5715793Snate@binkert.org "Squashed:%i\n\n", 5724382Sbinkertn@umich.edu num, (*inst_list_it)->pcState(), 5734762Snate@binkert.org (*inst_list_it)->seqNum, 5745344Sstever@gmail.com (*inst_list_it)->threadNumber, 5754382Sbinkertn@umich.edu (*inst_list_it)->isIssued(), 5765341Sstever@gmail.com (*inst_list_it)->isSquashed()); 5775742Snate@binkert.org inst_list_it++; 5785742Snate@binkert.org ++num; 5795742Snate@binkert.org } 5805742Snate@binkert.org } 5815742Snate@binkert.org 5824762Snate@binkert.org cprintf("Memory dependence hash size: %i\n", memDepHash.size()); 5835742Snate@binkert.org 5845742Snate@binkert.org#ifdef DEBUG 58511984Sgabeblack@google.com cprintf("Memory dependence entries: %i\n", MemDepEntry::memdep_count); 5867722Sgblack@eecs.umich.edu#endif 5875742Snate@binkert.org} 5885742Snate@binkert.org