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