mem_dep_unit_impl.hh revision 1062
1837SN/A 21762SN/A#include <map> 3837SN/A 4837SN/A#include "cpu/beta_cpu/mem_dep_unit.hh" 5837SN/A 6837SN/Atemplate <class MemDepPred, class Impl> 7837SN/AMemDepUnit<MemDepPred, Impl>::MemDepUnit(Params ¶ms) 8837SN/A : depPred(params.SSITSize, params.LFSTSize) 9837SN/A{ 10837SN/A DPRINTF(MemDepUnit, "MemDepUnit: Creating MemDepUnit object.\n"); 11837SN/A} 12837SN/A 13837SN/Atemplate <class MemDepPred, class Impl> 14837SN/Avoid 15837SN/AMemDepUnit<MemDepPred, Impl>::regStats() 16837SN/A{ 17837SN/A insertedLoads 18837SN/A .name(name() + ".memDep.insertedLoads") 19837SN/A .desc("Number of loads inserted to the mem dependence unit."); 20837SN/A 21837SN/A insertedStores 22837SN/A .name(name() + ".memDep.insertedStores") 23837SN/A .desc("Number of stores inserted to the mem dependence unit."); 24837SN/A 25837SN/A conflictingLoads 26837SN/A .name(name() + ".memDep.conflictingLoads") 272665SN/A .desc("Number of conflicting loads."); 282760SN/A 292760SN/A conflictingStores 30837SN/A .name(name() + ".memDep.conflictingStores") 31837SN/A .desc("Number of conflicting stores."); 321730SN/A} 33837SN/A 34837SN/Atemplate <class MemDepPred, class Impl> 35837SN/Avoid 3611263Sandreas.sandberg@arm.comMemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst) 3711263Sandreas.sandberg@arm.com{ 3811263Sandreas.sandberg@arm.com InstSeqNum inst_seq_num = inst->seqNum; 39837SN/A 4010469SN/A Dependency unresolved_dependencies(inst_seq_num); 41837SN/A 42837SN/A InstSeqNum producing_store = depPred.checkInst(inst->readPC()); 435882SN/A 44837SN/A if (producing_store == 0 || 456216SN/A storeDependents.find(producing_store) == storeDependents.end()) { 466658SN/A 478232SN/A DPRINTF(MemDepUnit, "MemDepUnit: No dependency for inst PC " 4811263Sandreas.sandberg@arm.com "%#x.\n", inst->readPC()); 492566SN/A 503348SN/A unresolved_dependencies.storeDep = storeDependents.end(); 514762SN/A 522566SN/A if (inst->readyToIssue()) { 53854SN/A readyInsts.insert(inst_seq_num); 548737SN/A } else { 558737SN/A unresolved_dependencies.memDepReady = true; 5610469SN/A 578737SN/A waitingInsts.insert(unresolved_dependencies); 588737SN/A } 598737SN/A } else { 608737SN/A DPRINTF(MemDepUnit, "MemDepUnit: Adding to dependency list; " 61854SN/A "inst PC %#x is dependent on seq num %i.\n", 62854SN/A inst->readPC(), producing_store); 63854SN/A 64854SN/A if (inst->readyToIssue()) { 65854SN/A unresolved_dependencies.regsReady = true; 66854SN/A } 67854SN/A 68854SN/A // Find the store that this instruction is dependent on. 69854SN/A sd_it_t store_loc = storeDependents.find(producing_store); 70854SN/A 71854SN/A assert(store_loc != storeDependents.end()); 72854SN/A 73854SN/A // Record the location of the store that this instruction is 74854SN/A // dependent on. 75854SN/A unresolved_dependencies.storeDep = store_loc; 76854SN/A 77854SN/A // If it's not already ready, then add it to the renamed 78854SN/A // list and the dependencies. 79854SN/A dep_it_t inst_loc = 80854SN/A (waitingInsts.insert(unresolved_dependencies)).first; 81854SN/A 82854SN/A // Add this instruction to the list of dependents. 83854SN/A (*store_loc).second.push_back(inst_loc); 84854SN/A 85854SN/A assert(!(*store_loc).second.empty()); 86854SN/A 87854SN/A if (inst->isLoad()) { 88854SN/A ++conflictingLoads; 89854SN/A } else { 90854SN/A ++conflictingStores; 91837SN/A } 921114SN/A } 932107SN/A 94927SN/A if (inst->isStore()) { 95837SN/A DPRINTF(MemDepUnit, "MemDepUnit: Inserting store PC %#x.\n", 96837SN/A inst->readPC()); 97879SN/A 98837SN/A depPred.insertStore(inst->readPC(), inst_seq_num); 991149SN/A 1009339SN/A // Make sure this store isn't already in this list. 1011149SN/A assert(storeDependents.find(inst_seq_num) == storeDependents.end()); 102915SN/A 1034093SN/A // Put a dependency entry in at the store's sequence number. 1044093SN/A // Uh, not sure how this works...I want to create an entry but 105854SN/A // I don't have anything to put into the value yet. 1064093SN/A storeDependents[inst_seq_num]; 107854SN/A 1084093SN/A assert(storeDependents.size() != 0); 1094093SN/A 1104093SN/A ++insertedStores; 1114093SN/A 1124093SN/A } else if (inst->isLoad()) { 1134093SN/A ++insertedLoads; 11412087Sspwilson2@wisc.edu } else { 11512087Sspwilson2@wisc.edu panic("MemDepUnit: Unknown type! (most likely a barrier)."); 11612087Sspwilson2@wisc.edu } 11712087Sspwilson2@wisc.edu 1181149SN/A memInsts[inst_seq_num] = inst; 1191149SN/A} 12012087Sspwilson2@wisc.edu 12112087Sspwilson2@wisc.edutemplate <class MemDepPred, class Impl> 12212087Sspwilson2@wisc.eduvoid 12312087Sspwilson2@wisc.eduMemDepUnit<MemDepPred, Impl>::insertNonSpec(DynInstPtr &inst) 12412087Sspwilson2@wisc.edu{ 12512087Sspwilson2@wisc.edu InstSeqNum inst_seq_num = inst->seqNum; 1264093SN/A 1271843SN/A Dependency non_spec_inst(inst_seq_num); 1284093SN/A 129995SN/A non_spec_inst.storeDep = storeDependents.end(); 130837SN/A 131854SN/A waitingInsts.insert(non_spec_inst); 132854SN/A 1334981SN/A // Might want to turn this part into an inline function or something. 1344981SN/A // It's shared between both insert functions. 135837SN/A if (inst->isStore()) { 1364762SN/A DPRINTF(MemDepUnit, "MemDepUnit: Inserting store PC %#x.\n", 1371909SN/A inst->readPC()); 1381909SN/A 1391909SN/A depPred.insertStore(inst->readPC(), inst_seq_num); 1401909SN/A 1411909SN/A // Make sure this store isn't already in this list. 142837SN/A assert(storeDependents.find(inst_seq_num) == storeDependents.end()); 143837SN/A 144879SN/A // Put a dependency entry in at the store's sequence number. 1459086SN/A // Uh, not sure how this works...I want to create an entry but 1469086SN/A // I don't have anything to put into the value yet. 1479086SN/A storeDependents[inst_seq_num]; 148837SN/A 149855SN/A assert(storeDependents.size() != 0); 150855SN/A 151855SN/A ++insertedStores; 1522846SN/A 1533349SN/A } else if (inst->isLoad()) { 154837SN/A ++insertedLoads; 1552846SN/A } else { 156837SN/A panic("MemDepUnit: Unknown type! (most likely a barrier)."); 1579807SN/A } 158837SN/A 159897SN/A memInsts[inst_seq_num] = inst; 160897SN/A} 161897SN/A 1621027SN/Atemplate <class MemDepPred, class Impl> 1631027SN/Atypename Impl::DynInstPtr & 1641027SN/AMemDepUnit<MemDepPred, Impl>::top() 165917SN/A{ 166917SN/A topInst = memInsts.find( (*readyInsts.begin()) ); 167927SN/A 168917SN/A DPRINTF(MemDepUnit, "MemDepUnit: Top instruction is PC %#x.\n", 169927SN/A (*topInst).second->readPC()); 170897SN/A 171897SN/A return (*topInst).second; 1724875SN/A} 1732846SN/A 174837SN/Atemplate <class MemDepPred, class Impl> 175837SN/Avoid 1764981SN/AMemDepUnit<MemDepPred, Impl>::pop() 1774981SN/A{ 1784981SN/A DPRINTF(MemDepUnit, "MemDepUnit: Removing instruction PC %#x.\n", 1794981SN/A (*topInst).second->readPC()); 1804981SN/A 1814981SN/A wakeDependents((*topInst).second); 1824981SN/A 1834981SN/A issue((*topInst).second); 1844981SN/A 1854981SN/A memInsts.erase(topInst); 1864981SN/A 187855SN/A topInst = memInsts.end(); 188855SN/A} 189855SN/A 190855SN/Atemplate <class MemDepPred, class Impl> 1912566SN/Avoid 1923349SN/AMemDepUnit<MemDepPred, Impl>::regsReady(DynInstPtr &inst) 193837SN/A{ 194927SN/A DPRINTF(MemDepUnit, "MemDepUnit: Marking registers as ready for " 195917SN/A "instruction PC %#x.\n", 196855SN/A inst->readPC()); 1972641SN/A 1982566SN/A InstSeqNum inst_seq_num = inst->seqNum; 1992641SN/A 200837SN/A Dependency inst_to_find(inst_seq_num); 201855SN/A 2021027SN/A dep_it_t waiting_inst = waitingInsts.find(inst_to_find); 2031027SN/A 204854SN/A assert(waiting_inst != waitingInsts.end()); 205837SN/A 206854SN/A if ((*waiting_inst).memDepReady) { 2072846SN/A DPRINTF(MemDepUnit, "MemDepUnit: Instruction has its memory " 208854SN/A "dependencies resolved, adding it to the ready list.\n"); 209854SN/A 210854SN/A moveToReady(waiting_inst); 211855SN/A } else { 2122630SN/A DPRINTF(MemDepUnit, "MemDepUnit: Instruction still waiting on " 2134870SN/A "memory dependency.\n"); 2142566SN/A 215854SN/A (*waiting_inst).regsReady = true; 216854SN/A } 217837SN/A} 2182641SN/A 2192630SN/Atemplate <class MemDepPred, class Impl> 2202566SN/Avoid 2212566SN/AMemDepUnit<MemDepPred, Impl>::nonSpecInstReady(DynInstPtr &inst) 2222566SN/A{ 2232566SN/A DPRINTF(MemDepUnit, "MemDepUnit: Marking non speculative " 2242566SN/A "instruction PC %#x as ready.\n", 2252566SN/A inst->readPC()); 2262566SN/A 2272566SN/A InstSeqNum inst_seq_num = inst->seqNum; 2282566SN/A 2292566SN/A Dependency inst_to_find(inst_seq_num); 2302566SN/A 2312566SN/A dep_it_t waiting_inst = waitingInsts.find(inst_to_find); 2322566SN/A 2332566SN/A assert(waiting_inst != waitingInsts.end()); 2342566SN/A 2352566SN/A moveToReady(waiting_inst); 2362566SN/A} 2372566SN/A 2382566SN/Atemplate <class MemDepPred, class Impl> 2392566SN/Avoid 2402566SN/AMemDepUnit<MemDepPred, Impl>::issue(DynInstPtr &inst) 2412566SN/A{ 2422566SN/A assert(readyInsts.find(inst->seqNum) != readyInsts.end()); 2432566SN/A 2442566SN/A DPRINTF(MemDepUnit, "MemDepUnit: Issuing instruction PC %#x.\n", 2452566SN/A inst->readPC()); 2462566SN/A 2472566SN/A // Remove the instruction from the ready list. 2482566SN/A readyInsts.erase(inst->seqNum); 2492566SN/A 2502566SN/A depPred.issued(inst->readPC(), inst->seqNum, inst->isStore()); 2512566SN/A} 2522566SN/A 2532566SN/Atemplate <class MemDepPred, class Impl> 2542566SN/Avoid 2552566SN/AMemDepUnit<MemDepPred, Impl>::wakeDependents(DynInstPtr &inst) 2562566SN/A{ 2572566SN/A // Only stores have dependents. 2582566SN/A if (!inst->isStore()) { 2592566SN/A return; 2602566SN/A } 2612566SN/A 2622566SN/A // Wake any dependencies. 2632566SN/A sd_it_t sd_it = storeDependents.find(inst->seqNum); 2642566SN/A 2652566SN/A // If there's no entry, then return. Really there should only be 2662566SN/A // no entry if the instruction is a load. 2672566SN/A if (sd_it == storeDependents.end()) { 2682566SN/A DPRINTF(MemDepUnit, "MemDepUnit: Instruction PC %#x, sequence " 2692566SN/A "number %i has no dependents.\n", 2702566SN/A inst->readPC(), inst->seqNum); 2712566SN/A 2722566SN/A return; 2732566SN/A } 2742566SN/A 2752566SN/A for (int i = 0; i < (*sd_it).second.size(); ++i ) { 2762566SN/A dep_it_t woken_inst = (*sd_it).second[i]; 2772566SN/A 2782566SN/A DPRINTF(MemDepUnit, "MemDepUnit: Waking up a dependent inst, " 2792566SN/A "sequence number %i.\n", 2802566SN/A (*woken_inst).seqNum); 2812566SN/A#if 0 2822566SN/A // Should we have reached instructions that are actually squashed, 2832566SN/A // there will be no more useful instructions in this dependency 2842566SN/A // list. Break out early. 2852566SN/A if (waitingInsts.find(woken_inst) == waitingInsts.end()) { 2862566SN/A DPRINTF(MemDepUnit, "MemDepUnit: Dependents on inst PC %#x " 2872566SN/A "are squashed, starting at SN %i. Breaking early.\n", 2882566SN/A inst->readPC(), woken_inst); 2892566SN/A break; 2902566SN/A } 2912566SN/A#endif 2922566SN/A 2932566SN/A if ((*woken_inst).regsReady) { 2942566SN/A moveToReady(woken_inst); 2952566SN/A } else { 2962566SN/A (*woken_inst).memDepReady = true; 2972566SN/A } 2982566SN/A } 2992566SN/A 3002566SN/A storeDependents.erase(sd_it); 3012566SN/A} 3022566SN/A 3032566SN/Atemplate <class MemDepPred, class Impl> 3042566SN/Avoid 3052566SN/AMemDepUnit<MemDepPred, Impl>::squash(const InstSeqNum &squashed_num) 3062566SN/A{ 3072566SN/A 3082566SN/A if (!waitingInsts.empty()) { 3092566SN/A dep_it_t waiting_it = waitingInsts.end(); 3102566SN/A 3112566SN/A --waiting_it; 3122566SN/A 3132566SN/A // Remove entries from the renamed list as long as we haven't reached 3142566SN/A // the end and the entries continue to be younger than the squashed. 315837SN/A while (!waitingInsts.empty() && 3162566SN/A (*waiting_it).seqNum > squashed_num) 3172566SN/A { 3182566SN/A if (!(*waiting_it).memDepReady && 319837SN/A (*waiting_it).storeDep != storeDependents.end()) { 3202566SN/A sd_it_t sd_it = (*waiting_it).storeDep; 3212566SN/A 3222566SN/A // Make sure the iterator that the store has pointing 323837SN/A // back is actually to this instruction. 3242566SN/A assert((*sd_it).second.back() == waiting_it); 3252566SN/A 3262566SN/A // Now remove this from the store's list of dependent 3272566SN/A // instructions. 3282566SN/A (*sd_it).second.pop_back(); 3292566SN/A } 3302566SN/A 3312566SN/A waitingInsts.erase(waiting_it--); 3322566SN/A } 3332566SN/A } 3342566SN/A 335837SN/A if (!readyInsts.empty()) { 336837SN/A sn_it_t ready_it = readyInsts.end(); 3372566SN/A 3382566SN/A --ready_it; 3392566SN/A 340837SN/A // Same for the ready list. 3412566SN/A while (!readyInsts.empty() && 3422566SN/A (*ready_it) > squashed_num) 3432566SN/A { 3442566SN/A readyInsts.erase(ready_it--); 3452566SN/A } 3462566SN/A } 3472566SN/A 3482566SN/A if (!storeDependents.empty()) { 3492566SN/A sd_it_t dep_it = storeDependents.end(); 3502566SN/A 3512566SN/A --dep_it; 3522566SN/A 3532566SN/A // Same for the dependencies list. 3542566SN/A while (!storeDependents.empty() && 3552566SN/A (*dep_it).first > squashed_num) 3562566SN/A { 3572566SN/A // This store's list of dependent instructions should be empty. 3582566SN/A assert((*dep_it).second.empty()); 3592566SN/A 3602566SN/A storeDependents.erase(dep_it--); 3612566SN/A } 3622566SN/A } 3632566SN/A 3642566SN/A // Tell the dependency predictor to squash as well. 3652566SN/A depPred.squash(squashed_num); 3662566SN/A} 3672566SN/A 3682566SN/Atemplate <class MemDepPred, class Impl> 3692566SN/Avoid 3702566SN/AMemDepUnit<MemDepPred, Impl>::violation(DynInstPtr &store_inst, 3712566SN/A DynInstPtr &violating_load) 3722566SN/A{ 3732566SN/A DPRINTF(MemDepUnit, "MemDepUnit: Passing violating PCs to store sets," 3742566SN/A " load: %#x, store: %#x\n", violating_load->readPC(), 3752566SN/A store_inst->readPC()); 3762566SN/A // Tell the memory dependence unit of the violation. 3772566SN/A depPred.violation(violating_load->readPC(), store_inst->readPC()); 3782566SN/A} 3792566SN/A 3802566SN/Atemplate <class MemDepPred, class Impl> 3812566SN/Ainline void 3822566SN/AMemDepUnit<MemDepPred, Impl>::moveToReady(dep_it_t &woken_inst) 3832566SN/A{ 3842566SN/A DPRINTF(MemDepUnit, "MemDepUnit: Adding instruction sequence number %i " 3852566SN/A "to the ready list.\n", (*woken_inst).seqNum); 3862566SN/A 3872566SN/A // Add it to the ready list. 3882566SN/A readyInsts.insert((*woken_inst).seqNum); 3892566SN/A 3902566SN/A // Remove it from the waiting instructions. 3912566SN/A waitingInsts.erase(woken_inst); 3922566SN/A} 3932566SN/A