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