mem_dep_unit_impl.hh revision 1061
1 2#include <map> 3 4#include "cpu/beta_cpu/mem_dep_unit.hh" 5 6// Hack: dependence predictor sizes are hardcoded. 7template <class MemDepPred, class Impl> 8MemDepUnit<MemDepPred, Impl>::MemDepUnit(Params ¶ms) 9 : depPred(4028, 128) 10{ 11 DPRINTF(MemDepUnit, "MemDepUnit: Creating MemDepUnit object.\n"); 12} 13 14template <class MemDepPred, class Impl> 15void 16MemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst) 17{ 18 InstSeqNum inst_seq_num = inst->seqNum; 19 20 21 InstSeqNum producing_store = depPred.checkInst(inst->readPC()); 22 23 if (producing_store == 0 || 24 dependencies.find(producing_store) == dependencies.end()) { 25 readyInsts.insert(inst_seq_num); 26 } else { 27 // If it's not already ready, then add it to the renamed 28 // list and the dependencies. 29 renamedInsts.insert(inst_seq_num); 30 31 dependencies[producing_store].push_back(inst_seq_num); 32 } 33 34 if (inst->isStore()) { 35 depPred.insertStore(inst->readPC(), inst_seq_num); 36 37 // Make sure this store isn't already in this list. 38 assert(dependencies.find(inst_seq_num) == dependencies.end()); 39 40 // Put a dependency entry in at the store's sequence number. 41 // Uh, not sure how this works...I want to create an entry but 42 // I don't have anything to put into the value yet. 43 dependencies[inst_seq_num]; 44 } else if (!inst->isLoad()) { 45 panic("MemDepUnit: Unknown type! (most likely a barrier)."); 46 } 47} 48 49template <class MemDepPred, class Impl> 50bool 51MemDepUnit<MemDepPred, Impl>::readyToIssue(DynInstPtr &inst) 52{ 53 InstSeqNum inst_seq_num = inst->seqNum; 54 55 if (readyInsts.find(inst_seq_num) == readyInsts.end()) { 56 return false; 57 } else { 58 return true; 59 } 60} 61 62template <class MemDepPred, class Impl> 63void 64MemDepUnit<MemDepPred, Impl>::issue(DynInstPtr &inst) 65{ 66 assert(readyInsts.find(inst->seqNum) != readyInsts.end()); 67 68 // Remove the instruction from the ready list. 69 readyInsts.erase(inst->seqNum); 70} 71 72template <class MemDepPred, class Impl> 73void 74MemDepUnit<MemDepPred, Impl>::wakeDependents(DynInstPtr &inst) 75{ 76 // Wake any dependencies. 77 dep_it_t dep_it = dependencies.find(inst); 78 79 // If there's no entry, then return. Really there should only be 80 // no entry if the instruction is a load. 81 if (dep_it == dependencies.end()) { 82 return; 83 } 84 85 assert(inst->isStore()); 86 87 for(int i = 0; i < (*dep_it).second.size(); ++i ) { 88 InstSeqNum woken_inst = (*dep_it).second[i]; 89 90 // Should we have reached instructions that are actually squashed, 91 // there will be no more useful instructions in this dependency 92 // list. Break out early. 93 if (renamedInsts.find(woken_inst) == renamedInsts.end()) { 94 DPRINTF(MemDepUnit, "MemDepUnit: Dependents on inst PC %#x " 95 "are squashed, starting at SN %i. Breaking early.\n", 96 inst->readPC(), woken_inst); 97 break; 98 } 99 100 // Remove it from the renamed instructions. 101 renamedInsts.erase(woken_inst); 102 103 // Add it to the ready list. 104 readyInsts.insert(woken_inst); 105 } 106 107 dependencies.erase(dep_it); 108} 109 110template <class MemDepPred, class Impl> 111void 112MemDepUnit<MemDepPred, Impl>::squash(const InstSeqNum &squashed_num) 113{ 114 115 if (!renamedInsts.empty()) { 116 sn_it_t renamed_it = renamedInsts.end(); 117 118 --renamed_it; 119 120 // Remove entries from the renamed list as long as we haven't reached 121 // the end and the entries continue to be younger than the squashed. 122 while (!renamedInsts.empty() && 123 (*renamed_it) > squashed_num) 124 { 125 renamedInsts.erase(renamed_it--); 126 } 127 } 128 129 if (!readyInsts.empty()) { 130 sn_it_t ready_it = readyInsts.end(); 131 132 --ready_it; 133 134 // Same for the ready list. 135 while (!readyInsts.empty() && 136 (*ready_it) > squashed_num) 137 { 138 readyInsts.erase(ready_it--); 139 } 140 } 141 142 if (!dependencies.empty()) { 143 dep_it_t dep_it = dependencies.end(); 144 145 --dep_it; 146 147 // Same for the dependencies list. 148 while (!dependencies.empty() && 149 (*dep_it).first > squashed_num) 150 { 151 dependencies.erase(dep_it--); 152 } 153 } 154 155 // Tell the dependency predictor to squash as well. 156 depPred.squash(squashed_num); 157} 158 159template <class MemDepPred, class Impl> 160void 161MemDepUnit<MemDepPred, Impl>::violation(DynInstPtr &store_inst, 162 DynInstPtr &violating_load) 163{ 164 // Tell the memory dependence unit of the violation. 165 depPred.violation(violating_load->readPC(), store_inst->readPC()); 166} 167