mem_dep_unit_impl.hh revision 1061
15643Sgblack@eecs.umich.edu
25643Sgblack@eecs.umich.edu#include <map>
35643Sgblack@eecs.umich.edu
45643Sgblack@eecs.umich.edu#include "cpu/beta_cpu/mem_dep_unit.hh"
55643Sgblack@eecs.umich.edu
65643Sgblack@eecs.umich.edu// Hack: dependence predictor sizes are hardcoded.
75643Sgblack@eecs.umich.edutemplate <class MemDepPred, class Impl>
85643Sgblack@eecs.umich.eduMemDepUnit<MemDepPred, Impl>::MemDepUnit(Params &params)
95643Sgblack@eecs.umich.edu    : depPred(4028, 128)
105643Sgblack@eecs.umich.edu{
115643Sgblack@eecs.umich.edu    DPRINTF(MemDepUnit, "MemDepUnit: Creating MemDepUnit object.\n");
125643Sgblack@eecs.umich.edu}
135643Sgblack@eecs.umich.edu
145643Sgblack@eecs.umich.edutemplate <class MemDepPred, class Impl>
155643Sgblack@eecs.umich.eduvoid
165643Sgblack@eecs.umich.eduMemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst)
175643Sgblack@eecs.umich.edu{
185643Sgblack@eecs.umich.edu    InstSeqNum inst_seq_num = inst->seqNum;
195643Sgblack@eecs.umich.edu
205643Sgblack@eecs.umich.edu
215643Sgblack@eecs.umich.edu    InstSeqNum producing_store = depPred.checkInst(inst->readPC());
225643Sgblack@eecs.umich.edu
235643Sgblack@eecs.umich.edu    if (producing_store == 0 ||
245643Sgblack@eecs.umich.edu        dependencies.find(producing_store) == dependencies.end()) {
255643Sgblack@eecs.umich.edu        readyInsts.insert(inst_seq_num);
265643Sgblack@eecs.umich.edu    } else {
275643Sgblack@eecs.umich.edu        // If it's not already ready, then add it to the renamed
285643Sgblack@eecs.umich.edu        // list and the dependencies.
295643Sgblack@eecs.umich.edu        renamedInsts.insert(inst_seq_num);
305643Sgblack@eecs.umich.edu
3111793Sbrandon.potter@amd.com        dependencies[producing_store].push_back(inst_seq_num);
3211793Sbrandon.potter@amd.com    }
336138Sgblack@eecs.umich.edu
345651Sgblack@eecs.umich.edu    if (inst->isStore()) {
358746Sgblack@eecs.umich.edu        depPred.insertStore(inst->readPC(), inst_seq_num);
368232Snate@binkert.org
375657Sgblack@eecs.umich.edu        // Make sure this store isn't already in this list.
385643Sgblack@eecs.umich.edu        assert(dependencies.find(inst_seq_num) == dependencies.end());
395643Sgblack@eecs.umich.edu
405643Sgblack@eecs.umich.edu        // Put a dependency entry in at the store's sequence number.
415643Sgblack@eecs.umich.edu        // Uh, not sure how this works...I want to create an entry but
429805Sstever@gmail.com        // I don't have anything to put into the value yet.
439808Sstever@gmail.com        dependencies[inst_seq_num];
449805Sstever@gmail.com    } else if (!inst->isLoad()) {
455643Sgblack@eecs.umich.edu        panic("MemDepUnit: Unknown type! (most likely a barrier).");
467913SBrad.Beckmann@amd.com    }
477913SBrad.Beckmann@amd.com}
487913SBrad.Beckmann@amd.com
497913SBrad.Beckmann@amd.comtemplate <class MemDepPred, class Impl>
507913SBrad.Beckmann@amd.combool
516136Sgblack@eecs.umich.eduMemDepUnit<MemDepPred, Impl>::readyToIssue(DynInstPtr &inst)
525643Sgblack@eecs.umich.edu{
535643Sgblack@eecs.umich.edu    InstSeqNum inst_seq_num = inst->seqNum;
545653Sgblack@eecs.umich.edu
555653Sgblack@eecs.umich.edu    if (readyInsts.find(inst_seq_num) == readyInsts.end()) {
565653Sgblack@eecs.umich.edu        return false;
575653Sgblack@eecs.umich.edu    } else {
585827Sgblack@eecs.umich.edu        return true;
595653Sgblack@eecs.umich.edu    }
605643Sgblack@eecs.umich.edu}
615643Sgblack@eecs.umich.edu
627913SBrad.Beckmann@amd.comtemplate <class MemDepPred, class Impl>
637913SBrad.Beckmann@amd.comvoid
647913SBrad.Beckmann@amd.comMemDepUnit<MemDepPred, Impl>::issue(DynInstPtr &inst)
657913SBrad.Beckmann@amd.com{
667913SBrad.Beckmann@amd.com    assert(readyInsts.find(inst->seqNum) != readyInsts.end());
679807Sstever@gmail.com
687913SBrad.Beckmann@amd.com    // Remove the instruction from the ready list.
699805Sstever@gmail.com    readyInsts.erase(inst->seqNum);
709807Sstever@gmail.com}
717913SBrad.Beckmann@amd.com
727913SBrad.Beckmann@amd.comtemplate <class MemDepPred, class Impl>
7313784Sgabeblack@google.comvoid
7413784Sgabeblack@google.comMemDepUnit<MemDepPred, Impl>::wakeDependents(DynInstPtr &inst)
759805Sstever@gmail.com{
769805Sstever@gmail.com    // Wake any dependencies.
779805Sstever@gmail.com    dep_it_t dep_it = dependencies.find(inst);
7813784Sgabeblack@google.com
799805Sstever@gmail.com    // If there's no entry, then return.  Really there should only be
809805Sstever@gmail.com    // no entry if the instruction is a load.
819805Sstever@gmail.com    if (dep_it == dependencies.end()) {
829805Sstever@gmail.com        return;
839805Sstever@gmail.com    }
849805Sstever@gmail.com
859805Sstever@gmail.com    assert(inst->isStore());
869805Sstever@gmail.com
879805Sstever@gmail.com    for(int i = 0; i < (*dep_it).second.size(); ++i ) {
889805Sstever@gmail.com        InstSeqNum woken_inst = (*dep_it).second[i];
899805Sstever@gmail.com
909805Sstever@gmail.com        // Should we have reached instructions that are actually squashed,
915643Sgblack@eecs.umich.edu        // there will be no more useful instructions in this dependency
9211144Sjthestness@gmail.com        // list.  Break out early.
9311144Sjthestness@gmail.com        if (renamedInsts.find(woken_inst) == renamedInsts.end()) {
9411144Sjthestness@gmail.com            DPRINTF(MemDepUnit, "MemDepUnit: Dependents on inst PC %#x "
9511144Sjthestness@gmail.com                    "are squashed, starting at SN %i.  Breaking early.\n",
9611144Sjthestness@gmail.com                    inst->readPC(), woken_inst);
9711144Sjthestness@gmail.com            break;
9811144Sjthestness@gmail.com        }
9911144Sjthestness@gmail.com
1005643Sgblack@eecs.umich.edu        // Remove it from the renamed instructions.
1015643Sgblack@eecs.umich.edu        renamedInsts.erase(woken_inst);
1025643Sgblack@eecs.umich.edu
1035643Sgblack@eecs.umich.edu        // Add it to the ready list.
1045643Sgblack@eecs.umich.edu        readyInsts.insert(woken_inst);
1055643Sgblack@eecs.umich.edu    }
10613229Sgabeblack@google.com
1075643Sgblack@eecs.umich.edu    dependencies.erase(dep_it);
1085643Sgblack@eecs.umich.edu}
10913229Sgabeblack@google.com
1105643Sgblack@eecs.umich.edutemplate <class MemDepPred, class Impl>
1115643Sgblack@eecs.umich.eduvoid
1125643Sgblack@eecs.umich.eduMemDepUnit<MemDepPred, Impl>::squash(const InstSeqNum &squashed_num)
1135643Sgblack@eecs.umich.edu{
1145898Sgblack@eecs.umich.edu
1159805Sstever@gmail.com    if (!renamedInsts.empty()) {
1165643Sgblack@eecs.umich.edu        sn_it_t renamed_it = renamedInsts.end();
1175643Sgblack@eecs.umich.edu
1185643Sgblack@eecs.umich.edu        --renamed_it;
1195643Sgblack@eecs.umich.edu
1205643Sgblack@eecs.umich.edu        // Remove entries from the renamed list as long as we haven't reached
1215643Sgblack@eecs.umich.edu        // the end and the entries continue to be younger than the squashed.
1225643Sgblack@eecs.umich.edu        while (!renamedInsts.empty() &&
1235643Sgblack@eecs.umich.edu               (*renamed_it) > squashed_num)
1245643Sgblack@eecs.umich.edu        {
12513229Sgabeblack@google.com            renamedInsts.erase(renamed_it--);
1265643Sgblack@eecs.umich.edu        }
1275643Sgblack@eecs.umich.edu    }
12813229Sgabeblack@google.com
1295643Sgblack@eecs.umich.edu    if (!readyInsts.empty()) {
1305643Sgblack@eecs.umich.edu        sn_it_t ready_it = readyInsts.end();
1315643Sgblack@eecs.umich.edu
1325643Sgblack@eecs.umich.edu        --ready_it;
1335898Sgblack@eecs.umich.edu
1349805Sstever@gmail.com        // Same for the ready list.
1355643Sgblack@eecs.umich.edu        while (!readyInsts.empty() &&
1365643Sgblack@eecs.umich.edu               (*ready_it) > squashed_num)
1375643Sgblack@eecs.umich.edu        {
1385643Sgblack@eecs.umich.edu            readyInsts.erase(ready_it--);
1395643Sgblack@eecs.umich.edu        }
1405643Sgblack@eecs.umich.edu    }
1417913SBrad.Beckmann@amd.com
1425643Sgblack@eecs.umich.edu    if (!dependencies.empty()) {
1435643Sgblack@eecs.umich.edu        dep_it_t dep_it = dependencies.end();
1445643Sgblack@eecs.umich.edu
1457913SBrad.Beckmann@amd.com        --dep_it;
1465643Sgblack@eecs.umich.edu
1475643Sgblack@eecs.umich.edu        // Same for the dependencies list.
1485643Sgblack@eecs.umich.edu        while (!dependencies.empty() &&
1495643Sgblack@eecs.umich.edu               (*dep_it).first > squashed_num)
1505643Sgblack@eecs.umich.edu        {
1515643Sgblack@eecs.umich.edu            dependencies.erase(dep_it--);
1525643Sgblack@eecs.umich.edu        }
1535643Sgblack@eecs.umich.edu    }
1545643Sgblack@eecs.umich.edu
1555643Sgblack@eecs.umich.edu    // Tell the dependency predictor to squash as well.
1565643Sgblack@eecs.umich.edu    depPred.squash(squashed_num);
1575643Sgblack@eecs.umich.edu}
1585643Sgblack@eecs.umich.edu
1595643Sgblack@eecs.umich.edutemplate <class MemDepPred, class Impl>
1605643Sgblack@eecs.umich.eduvoid
1615643Sgblack@eecs.umich.eduMemDepUnit<MemDepPred, Impl>::violation(DynInstPtr &store_inst,
1625643Sgblack@eecs.umich.edu                                        DynInstPtr &violating_load)
1635643Sgblack@eecs.umich.edu{
1645643Sgblack@eecs.umich.edu    // Tell the memory dependence unit of the violation.
1655643Sgblack@eecs.umich.edu    depPred.violation(violating_load->readPC(), store_inst->readPC());
1665643Sgblack@eecs.umich.edu}
1675643Sgblack@eecs.umich.edu