mem_dep_unit_impl.hh revision 1061
11689SN/A
22326SN/A#include <map>
31689SN/A
41689SN/A#include "cpu/beta_cpu/mem_dep_unit.hh"
51689SN/A
61689SN/A// Hack: dependence predictor sizes are hardcoded.
71689SN/Atemplate <class MemDepPred, class Impl>
81689SN/AMemDepUnit<MemDepPred, Impl>::MemDepUnit(Params &params)
91689SN/A    : depPred(4028, 128)
101689SN/A{
111689SN/A    DPRINTF(MemDepUnit, "MemDepUnit: Creating MemDepUnit object.\n");
121689SN/A}
131689SN/A
141689SN/Atemplate <class MemDepPred, class Impl>
151689SN/Avoid
161689SN/AMemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst)
171689SN/A{
181689SN/A    InstSeqNum inst_seq_num = inst->seqNum;
191689SN/A
201689SN/A
211689SN/A    InstSeqNum producing_store = depPred.checkInst(inst->readPC());
221689SN/A
231689SN/A    if (producing_store == 0 ||
241689SN/A        dependencies.find(producing_store) == dependencies.end()) {
251689SN/A        readyInsts.insert(inst_seq_num);
261689SN/A    } else {
272665Ssaidi@eecs.umich.edu        // If it's not already ready, then add it to the renamed
282665Ssaidi@eecs.umich.edu        // list and the dependencies.
291689SN/A        renamedInsts.insert(inst_seq_num);
301689SN/A
312292SN/A        dependencies[producing_store].push_back(inst_seq_num);
322292SN/A    }
331060SN/A
341060SN/A    if (inst->isStore()) {
351061SN/A        depPred.insertStore(inst->readPC(), inst_seq_num);
361060SN/A
371061SN/A        // Make sure this store isn't already in this list.
381060SN/A        assert(dependencies.find(inst_seq_num) == dependencies.end());
391062SN/A
401060SN/A        // Put a dependency entry in at the store's sequence number.
411061SN/A        // Uh, not sure how this works...I want to create an entry but
422326SN/A        // I don't have anything to put into the value yet.
432669Sktlim@umich.edu        dependencies[inst_seq_num];
441710SN/A    } else if (!inst->isLoad()) {
451060SN/A        panic("MemDepUnit: Unknown type! (most likely a barrier).");
462292SN/A    }
472292SN/A}
482292SN/A
491060SN/Atemplate <class MemDepPred, class Impl>
501689SN/Abool
511689SN/AMemDepUnit<MemDepPred, Impl>::readyToIssue(DynInstPtr &inst)
521689SN/A{
531689SN/A    InstSeqNum inst_seq_num = inst->seqNum;
541060SN/A
551060SN/A    if (readyInsts.find(inst_seq_num) == readyInsts.end()) {
561060SN/A        return false;
572292SN/A    } else {
582292SN/A        return true;
592292SN/A    }
602292SN/A}
612292SN/A
622292SN/Atemplate <class MemDepPred, class Impl>
632292SN/Avoid
642292SN/AMemDepUnit<MemDepPred, Impl>::issue(DynInstPtr &inst)
651060SN/A{
661061SN/A    assert(readyInsts.find(inst->seqNum) != readyInsts.end());
671060SN/A
681060SN/A    // Remove the instruction from the ready list.
691060SN/A    readyInsts.erase(inst->seqNum);
701060SN/A}
712733Sktlim@umich.edu
721061SN/Atemplate <class MemDepPred, class Impl>
731060SN/Avoid
741060SN/AMemDepUnit<MemDepPred, Impl>::wakeDependents(DynInstPtr &inst)
752292SN/A{
761061SN/A    // Wake any dependencies.
771061SN/A    dep_it_t dep_it = dependencies.find(inst);
781061SN/A
791060SN/A    // If there's no entry, then return.  Really there should only be
802292SN/A    // no entry if the instruction is a load.
811061SN/A    if (dep_it == dependencies.end()) {
821060SN/A        return;
832733Sktlim@umich.edu    }
842292SN/A
852292SN/A    assert(inst->isStore());
862292SN/A
872292SN/A    for(int i = 0; i < (*dep_it).second.size(); ++i ) {
882292SN/A        InstSeqNum woken_inst = (*dep_it).second[i];
892292SN/A
902292SN/A        // Should we have reached instructions that are actually squashed,
912292SN/A        // there will be no more useful instructions in this dependency
922292SN/A        // list.  Break out early.
932292SN/A        if (renamedInsts.find(woken_inst) == renamedInsts.end()) {
942292SN/A            DPRINTF(MemDepUnit, "MemDepUnit: Dependents on inst PC %#x "
952292SN/A                    "are squashed, starting at SN %i.  Breaking early.\n",
962292SN/A                    inst->readPC(), woken_inst);
972348SN/A            break;
982348SN/A        }
992348SN/A
1002326SN/A        // Remove it from the renamed instructions.
1012326SN/A        renamedInsts.erase(woken_inst);
1022292SN/A
1032292SN/A        // Add it to the ready list.
1042292SN/A        readyInsts.insert(woken_inst);
1052292SN/A    }
1062292SN/A
1072292SN/A    dependencies.erase(dep_it);
1082292SN/A}
1092326SN/A
1101060SN/Atemplate <class MemDepPred, class Impl>
1111060SN/Avoid
1122292SN/AMemDepUnit<MemDepPred, Impl>::squash(const InstSeqNum &squashed_num)
1132292SN/A{
1141061SN/A
1152292SN/A    if (!renamedInsts.empty()) {
1162292SN/A        sn_it_t renamed_it = renamedInsts.end();
1171061SN/A
1182292SN/A        --renamed_it;
1192292SN/A
1201060SN/A        // Remove entries from the renamed list as long as we haven't reached
1212292SN/A        // the end and the entries continue to be younger than the squashed.
1221062SN/A        while (!renamedInsts.empty() &&
1231062SN/A               (*renamed_it) > squashed_num)
1242348SN/A        {
1252307SN/A            renamedInsts.erase(renamed_it--);
1261060SN/A        }
1272292SN/A    }
1282733Sktlim@umich.edu
1291755SN/A    if (!readyInsts.empty()) {
1302292SN/A        sn_it_t ready_it = readyInsts.end();
1312292SN/A
1322292SN/A        --ready_it;
1332292SN/A
1342292SN/A        // Same for the ready list.
1352292SN/A        while (!readyInsts.empty() &&
1362292SN/A               (*ready_it) > squashed_num)
1371060SN/A        {
1381060SN/A            readyInsts.erase(ready_it--);
1392292SN/A        }
1401060SN/A    }
1411060SN/A
1422348SN/A    if (!dependencies.empty()) {
1432307SN/A        dep_it_t dep_it = dependencies.end();
1442307SN/A
1452348SN/A        --dep_it;
1462307SN/A
1472307SN/A        // Same for the dependencies list.
1482348SN/A        while (!dependencies.empty() &&
1492307SN/A               (*dep_it).first > squashed_num)
1502307SN/A        {
1512292SN/A            dependencies.erase(dep_it--);
1522292SN/A        }
1532292SN/A    }
1542292SN/A
1552292SN/A    // Tell the dependency predictor to squash as well.
1562292SN/A    depPred.squash(squashed_num);
1572292SN/A}
1581060SN/A
1591060SN/Atemplate <class MemDepPred, class Impl>
1602292SN/Avoid
1612292SN/AMemDepUnit<MemDepPred, Impl>::violation(DynInstPtr &store_inst,
1622292SN/A                                        DynInstPtr &violating_load)
1632292SN/A{
1641060SN/A    // Tell the memory dependence unit of the violation.
1651060SN/A    depPred.violation(violating_load->readPC(), store_inst->readPC());
1662292SN/A}
1672292SN/A