40 #include "debug/MemDepUnit.hh"
41 #include "params/O3CPU.hh"
50 int MemDepUnit::MemDepEntry::memdep_count = 0;
51 int MemDepUnit::MemDepEntry::memdep_insert = 0;
52 int MemDepUnit::MemDepEntry::memdep_erase = 0;
58 : _name(params.
name +
".memdepunit"),
59 depPred(params.store_set_clear_period, params.SSITSize,
76 hash_it =
memDepHash.find((*inst_list_it)->seqNum);
87 assert(MemDepEntry::memdep_count == 0);
99 depPred.
init(params.store_set_clear_period, params.SSITSize,
102 std::string stats_group_name =
csprintf(
"MemDepUnit__%i", tid);
107 : statistics::
Group(parent),
108 ADD_STAT(insertedLoads, statistics::units::Count::get(),
109 "Number of loads inserted to the mem dependence unit."),
110 ADD_STAT(insertedStores, statistics::units::Count::get(),
111 "Number of stores inserted to the mem dependence unit."),
112 ADD_STAT(conflictingLoads, statistics::units::Count::get(),
113 "Number of conflicting loads."),
114 ADD_STAT(conflictingStores, statistics::units::Count::get(),
115 "Number of conflicting stores.")
126 drained = drained &&
instList[
i].empty();
162 if (barr_inst->isReadBarrier() || barr_inst->isHtmCmd())
164 if (barr_inst->isWriteBarrier() || barr_inst->isHtmCmd())
167 if (debug::MemDepUnit) {
168 const char *barrier_type =
nullptr;
169 if (barr_inst->isReadBarrier() && barr_inst->isWriteBarrier())
170 barrier_type =
"memory";
171 else if (barr_inst->isReadBarrier())
172 barrier_type =
"read";
173 else if (barr_inst->isWriteBarrier())
174 barrier_type =
"write";
178 barrier_type, barr_inst->pcState(), barr_sn);
183 "store barriers = %d\n",
200 MemDepEntry::memdep_insert++;
205 inst_entry->listIt = --(
instList[tid].end());
213 producing_stores.insert(std::end(producing_stores),
216 }
else if ((inst->isStore() || inst->isAtomic()) &&
hasStoreBarrier()) {
219 producing_stores.insert(std::end(producing_stores),
225 producing_stores.push_back(dep);
231 for (
auto producing_store : producing_stores) {
237 store_entries.push_back((*hash_it).second);
244 if (store_entries.empty()) {
246 "%s [sn:%lli].\n", inst->pcState(), inst->seqNum);
248 assert(inst_entry->memDeps == 0);
250 if (inst->readyToIssue()) {
251 inst_entry->regsReady =
true;
258 for (GEM5_VAR_USED
auto producing_store : producing_stores)
260 inst->pcState(), producing_store);
262 if (inst->readyToIssue()) {
263 inst_entry->regsReady =
true;
267 inst->clearCanIssue();
270 for (
auto store_entry : store_entries)
271 store_entry->dependInsts.push_back(inst_entry);
273 inst_entry->memDeps = store_entries.size();
275 if (inst->isLoad()) {
285 if (inst->isStore() || inst->isAtomic()) {
287 inst->pcState(), inst->seqNum);
293 }
else if (inst->isLoad()) {
296 panic(
"Unknown type! (most likely a barrier).");
307 if (inst->isStore() || inst->isAtomic()) {
309 inst->pcState(), inst->seqNum);
315 }
else if (inst->isLoad()) {
318 panic(
"Unknown type! (most likely a barrier).");
325 ThreadID tid = barr_inst->threadNumber;
327 MemDepEntryPtr inst_entry = std::make_shared<MemDepEntry>(barr_inst);
333 MemDepEntry::memdep_insert++;
339 inst_entry->listIt = --(
instList[tid].end());
348 "instruction PC %s [sn:%lli].\n",
349 inst->pcState(), inst->seqNum);
353 inst_entry->regsReady =
true;
355 if (inst_entry->memDeps == 0) {
357 "dependencies resolved, adding it to the ready list.\n");
362 "memory dependency.\n");
370 "instruction PC %s as ready [sn:%lli].\n",
371 inst->pcState(), inst->seqNum);
396 temp_inst->pcState(), temp_inst->seqNum);
408 inst->pcState(), inst->seqNum);
417 instList[tid].erase((*hash_it).second->listIt);
419 (*hash_it).second = NULL;
423 MemDepEntry::memdep_erase++;
434 if (inst->isWriteBarrier() || inst->isHtmCmd()) {
438 if (inst->isReadBarrier() || inst->isHtmCmd()) {
442 if (debug::MemDepUnit) {
443 const char *barrier_type =
nullptr;
444 if (inst->isWriteBarrier() && inst->isReadBarrier())
445 barrier_type =
"Memory";
446 else if (inst->isWriteBarrier())
447 barrier_type =
"Write";
448 else if (inst->isReadBarrier())
449 barrier_type =
"Read";
453 barrier_type, inst->pcState(), inst->seqNum);
462 if (!inst->isStore() && !inst->isAtomic() && !inst->isReadBarrier() &&
463 !inst->isWriteBarrier() && !inst->isHtmCmd()) {
469 for (
int i = 0;
i < inst_entry->dependInsts.size(); ++
i ) {
472 if (!woken_inst->inst) {
479 woken_inst->inst->seqNum);
481 assert(woken_inst->memDeps > 0);
482 woken_inst->memDeps -= 1;
484 if ((woken_inst->memDeps == 0) &&
485 woken_inst->regsReady &&
486 !woken_inst->squashed) {
491 inst_entry->dependInsts.clear();
501 "Memory dependency entry created. memdep_count=%i %s\n",
502 memdep_count,
inst->pcState());
508 for (
int i = 0;
i < dependInsts.size(); ++
i) {
509 dependInsts[
i] = NULL;
515 "Memory dependency entry deleted. memdep_count=%i %s\n",
516 memdep_count, inst->pcState());
526 if ((*replay_it)->threadNumber == tid &&
527 (*replay_it)->seqNum > squashed_num) {
541 (*squash_it)->seqNum > squashed_num) {
544 (*squash_it)->seqNum);
550 hash_it =
memDepHash.find((*squash_it)->seqNum);
554 (*hash_it).second->squashed =
true;
556 (*hash_it).second = NULL;
560 MemDepEntry::memdep_erase++;
575 " load: %#x, store: %#x\n", violating_load->instAddr(),
576 store_inst->instAddr());
585 inst->instAddr(), inst->seqNum);
587 depPred.
issued(inst->instAddr(), inst->seqNum, inst->isStore());
597 return (*hash_it).second;
604 "to the ready list.\n", woken_inst_entry->inst->seqNum);
606 assert(!woken_inst_entry->squashed);
616 cprintf(
"Instruction list %i size: %i\n",
622 while (inst_list_it !=
instList[tid].end()) {
623 cprintf(
"Instruction:%i\nPC: %s\n[sn:%llu]\n[tid:%i]\nIssued:%i\n"
625 num, (*inst_list_it)->pcState(),
626 (*inst_list_it)->seqNum,
627 (*inst_list_it)->threadNumber,
628 (*inst_list_it)->isIssued(),
629 (*inst_list_it)->isSquashed());
638 cprintf(
"Memory dependence entries: %i\n", MemDepEntry::memdep_count);