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 ¶ms) 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