gem5  v22.1.0.0
mem_dep_unit.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004-2005 The Regents of The University of Michigan
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "cpu/o3/mem_dep_unit.hh"
30 
31 #include <map>
32 #include <memory>
33 #include <vector>
34 
35 #include "base/compiler.hh"
36 #include "base/debug.hh"
37 #include "cpu/o3/dyn_inst.hh"
38 #include "cpu/o3/inst_queue.hh"
39 #include "cpu/o3/limits.hh"
40 #include "debug/MemDepUnit.hh"
41 #include "params/BaseO3CPU.hh"
42 
43 namespace gem5
44 {
45 
46 namespace o3
47 {
48 
49 #ifdef DEBUG
50 int MemDepUnit::MemDepEntry::memdep_count = 0;
51 int MemDepUnit::MemDepEntry::memdep_insert = 0;
52 int MemDepUnit::MemDepEntry::memdep_erase = 0;
53 #endif
54 
55 MemDepUnit::MemDepUnit() : iqPtr(NULL), stats(nullptr) {}
56 
57 MemDepUnit::MemDepUnit(const BaseO3CPUParams &params)
58  : _name(params.name + ".memdepunit"),
59  depPred(params.store_set_clear_period, params.SSITSize,
60  params.LFSTSize),
61  iqPtr(NULL),
62  stats(nullptr)
63 {
64  DPRINTF(MemDepUnit, "Creating MemDepUnit object.\n");
65 }
66 
68 {
69  for (ThreadID tid = 0; tid < MaxThreads; tid++) {
70 
71  ListIt inst_list_it = instList[tid].begin();
72 
73  MemDepHashIt hash_it;
74 
75  while (!instList[tid].empty()) {
76  hash_it = memDepHash.find((*inst_list_it)->seqNum);
77 
78  assert(hash_it != memDepHash.end());
79 
80  memDepHash.erase(hash_it);
81 
82  instList[tid].erase(inst_list_it++);
83  }
84  }
85 
86 #ifdef DEBUG
87  assert(MemDepEntry::memdep_count == 0);
88 #endif
89 }
90 
91 void
92 MemDepUnit::init(const BaseO3CPUParams &params, ThreadID tid, CPU *cpu)
93 {
94  DPRINTF(MemDepUnit, "Creating MemDepUnit %i object.\n",tid);
95 
96  _name = csprintf("%s.memDep%d", params.name, tid);
97  id = tid;
98 
99  depPred.init(params.store_set_clear_period, params.SSITSize,
100  params.LFSTSize);
101 
102  std::string stats_group_name = csprintf("MemDepUnit__%i", tid);
103  cpu->addStatGroup(stats_group_name.c_str(), &stats);
104 }
105 
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.")
116 {
117 }
118 
119 bool
121 {
122  bool drained = instsToReplay.empty()
123  && memDepHash.empty()
124  && instsToReplay.empty();
125  for (int i = 0; i < MaxThreads; ++i)
126  drained = drained && instList[i].empty();
127 
128  return drained;
129 }
130 
131 void
133 {
134  assert(instsToReplay.empty());
135  assert(memDepHash.empty());
136  for (int i = 0; i < MaxThreads; ++i)
137  assert(instList[i].empty());
138  assert(instsToReplay.empty());
139  assert(memDepHash.empty());
140 }
141 
142 void
144 {
145  // Be sure to reset all state.
146  loadBarrierSNs.clear();
147  storeBarrierSNs.clear();
148  depPred.clear();
149 }
150 
151 void
153 {
154  iqPtr = iq_ptr;
155 }
156 
157 void
159 {
160  InstSeqNum barr_sn = barr_inst->seqNum;
161 
162  if (barr_inst->isReadBarrier() || barr_inst->isHtmCmd())
163  loadBarrierSNs.insert(barr_sn);
164  if (barr_inst->isWriteBarrier() || barr_inst->isHtmCmd())
165  storeBarrierSNs.insert(barr_sn);
166 
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";
175 
176  if (barrier_type) {
177  DPRINTF(MemDepUnit, "Inserted a %s barrier %s SN:%lli\n",
178  barrier_type, barr_inst->pcState(), barr_sn);
179  }
180 
181  if (loadBarrierSNs.size() || storeBarrierSNs.size()) {
182  DPRINTF(MemDepUnit, "Outstanding load barriers = %d; "
183  "store barriers = %d\n",
184  loadBarrierSNs.size(), storeBarrierSNs.size());
185  }
186  }
187 }
188 
189 void
191 {
192  ThreadID tid = inst->threadNumber;
193 
194  MemDepEntryPtr inst_entry = std::make_shared<MemDepEntry>(inst);
195 
196  // Add the MemDepEntry to the hash.
197  memDepHash.insert(
198  std::pair<InstSeqNum, MemDepEntryPtr>(inst->seqNum, inst_entry));
199 #ifdef DEBUG
200  MemDepEntry::memdep_insert++;
201 #endif
202 
203  instList[tid].push_back(inst);
204 
205  inst_entry->listIt = --(instList[tid].end());
206 
207  // Check any barriers and the dependence predictor for any
208  // producing memrefs/stores.
209  std::vector<InstSeqNum> producing_stores;
210  if ((inst->isLoad() || inst->isAtomic()) && hasLoadBarrier()) {
211  DPRINTF(MemDepUnit, "%d load barriers in flight\n",
212  loadBarrierSNs.size());
213  producing_stores.insert(std::end(producing_stores),
214  std::begin(loadBarrierSNs),
215  std::end(loadBarrierSNs));
216  } else if ((inst->isStore() || inst->isAtomic()) && hasStoreBarrier()) {
217  DPRINTF(MemDepUnit, "%d store barriers in flight\n",
218  storeBarrierSNs.size());
219  producing_stores.insert(std::end(producing_stores),
220  std::begin(storeBarrierSNs),
221  std::end(storeBarrierSNs));
222  } else {
223  InstSeqNum dep = depPred.checkInst(inst->pcState().instAddr());
224  if (dep != 0)
225  producing_stores.push_back(dep);
226  }
227 
228  std::vector<MemDepEntryPtr> store_entries;
229 
230  // If there is a producing store, try to find the entry.
231  for (auto producing_store : producing_stores) {
232  DPRINTF(MemDepUnit, "Searching for producer [sn:%lli]\n",
233  producing_store);
234  MemDepHashIt hash_it = memDepHash.find(producing_store);
235 
236  if (hash_it != memDepHash.end()) {
237  store_entries.push_back((*hash_it).second);
238  DPRINTF(MemDepUnit, "Producer found\n");
239  }
240  }
241 
242  // If no store entry, then instruction can issue as soon as the registers
243  // are ready.
244  if (store_entries.empty()) {
245  DPRINTF(MemDepUnit, "No dependency for inst PC "
246  "%s [sn:%lli].\n", inst->pcState(), inst->seqNum);
247 
248  assert(inst_entry->memDeps == 0);
249 
250  if (inst->readyToIssue()) {
251  inst_entry->regsReady = true;
252 
253  moveToReady(inst_entry);
254  }
255  } else {
256  // Otherwise make the instruction dependent on the store/barrier.
257  DPRINTF(MemDepUnit, "Adding to dependency list\n");
258  for ([[maybe_unused]] auto producing_store : producing_stores)
259  DPRINTF(MemDepUnit, "\tinst PC %s is dependent on [sn:%lli].\n",
260  inst->pcState(), producing_store);
261 
262  if (inst->readyToIssue()) {
263  inst_entry->regsReady = true;
264  }
265 
266  // Clear the bit saying this instruction can issue.
267  inst->clearCanIssue();
268 
269  // Add this instruction to the list of dependents.
270  for (auto store_entry : store_entries)
271  store_entry->dependInsts.push_back(inst_entry);
272 
273  inst_entry->memDeps = store_entries.size();
274 
275  if (inst->isLoad()) {
277  } else {
279  }
280  }
281 
282  // for load-acquire store-release that could also be a barrier
283  insertBarrierSN(inst);
284 
285  if (inst->isStore() || inst->isAtomic()) {
286  DPRINTF(MemDepUnit, "Inserting store/atomic PC %s [sn:%lli].\n",
287  inst->pcState(), inst->seqNum);
288 
289  depPred.insertStore(inst->pcState().instAddr(), inst->seqNum,
290  inst->threadNumber);
291 
293  } else if (inst->isLoad()) {
295  } else {
296  panic("Unknown type! (most likely a barrier).");
297  }
298 }
299 
300 void
302 {
303  insertBarrier(inst);
304 
305  // Might want to turn this part into an inline function or something.
306  // It's shared between both insert functions.
307  if (inst->isStore() || inst->isAtomic()) {
308  DPRINTF(MemDepUnit, "Inserting store/atomic PC %s [sn:%lli].\n",
309  inst->pcState(), inst->seqNum);
310 
311  depPred.insertStore(inst->pcState().instAddr(), inst->seqNum,
312  inst->threadNumber);
313 
315  } else if (inst->isLoad()) {
317  } else {
318  panic("Unknown type! (most likely a barrier).");
319  }
320 }
321 
322 void
324 {
325  ThreadID tid = barr_inst->threadNumber;
326 
327  MemDepEntryPtr inst_entry = std::make_shared<MemDepEntry>(barr_inst);
328 
329  // Add the MemDepEntry to the hash.
330  memDepHash.insert(
331  std::pair<InstSeqNum, MemDepEntryPtr>(barr_inst->seqNum, inst_entry));
332 #ifdef DEBUG
333  MemDepEntry::memdep_insert++;
334 #endif
335 
336  // Add the instruction to the instruction list.
337  instList[tid].push_back(barr_inst);
338 
339  inst_entry->listIt = --(instList[tid].end());
340 
341  insertBarrierSN(barr_inst);
342 }
343 
344 void
346 {
347  DPRINTF(MemDepUnit, "Marking registers as ready for "
348  "instruction PC %s [sn:%lli].\n",
349  inst->pcState(), inst->seqNum);
350 
351  MemDepEntryPtr inst_entry = findInHash(inst);
352 
353  inst_entry->regsReady = true;
354 
355  if (inst_entry->memDeps == 0) {
356  DPRINTF(MemDepUnit, "Instruction has its memory "
357  "dependencies resolved, adding it to the ready list.\n");
358 
359  moveToReady(inst_entry);
360  } else {
361  DPRINTF(MemDepUnit, "Instruction still waiting on "
362  "memory dependency.\n");
363  }
364 }
365 
366 void
368 {
369  DPRINTF(MemDepUnit, "Marking non speculative "
370  "instruction PC %s as ready [sn:%lli].\n",
371  inst->pcState(), inst->seqNum);
372 
373  MemDepEntryPtr inst_entry = findInHash(inst);
374 
375  moveToReady(inst_entry);
376 }
377 
378 void
380 {
381  instsToReplay.push_back(inst);
382 }
383 
384 void
386 {
387  DynInstPtr temp_inst;
388 
389  // For now this replay function replays all waiting memory ops.
390  while (!instsToReplay.empty()) {
391  temp_inst = instsToReplay.front();
392 
393  MemDepEntryPtr inst_entry = findInHash(temp_inst);
394 
395  DPRINTF(MemDepUnit, "Replaying mem instruction PC %s [sn:%lli].\n",
396  temp_inst->pcState(), temp_inst->seqNum);
397 
398  moveToReady(inst_entry);
399 
400  instsToReplay.pop_front();
401  }
402 }
403 
404 void
406 {
407  DPRINTF(MemDepUnit, "Completed mem instruction PC %s [sn:%lli].\n",
408  inst->pcState(), inst->seqNum);
409 
410  ThreadID tid = inst->threadNumber;
411 
412  // Remove the instruction from the hash and the list.
413  MemDepHashIt hash_it = memDepHash.find(inst->seqNum);
414 
415  assert(hash_it != memDepHash.end());
416 
417  instList[tid].erase((*hash_it).second->listIt);
418 
419  (*hash_it).second = NULL;
420 
421  memDepHash.erase(hash_it);
422 #ifdef DEBUG
423  MemDepEntry::memdep_erase++;
424 #endif
425 }
426 
427 void
429 {
430  wakeDependents(inst);
431  completed(inst);
432  InstSeqNum barr_sn = inst->seqNum;
433 
434  if (inst->isWriteBarrier() || inst->isHtmCmd()) {
435  assert(hasStoreBarrier());
436  storeBarrierSNs.erase(barr_sn);
437  }
438  if (inst->isReadBarrier() || inst->isHtmCmd()) {
439  assert(hasLoadBarrier());
440  loadBarrierSNs.erase(barr_sn);
441  }
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";
450 
451  if (barrier_type) {
452  DPRINTF(MemDepUnit, "%s barrier completed: %s SN:%lli\n",
453  barrier_type, inst->pcState(), inst->seqNum);
454  }
455  }
456 }
457 
458 void
460 {
461  // Only stores, atomics and barriers have dependents.
462  if (!inst->isStore() && !inst->isAtomic() && !inst->isReadBarrier() &&
463  !inst->isWriteBarrier() && !inst->isHtmCmd()) {
464  return;
465  }
466 
467  MemDepEntryPtr inst_entry = findInHash(inst);
468 
469  for (int i = 0; i < inst_entry->dependInsts.size(); ++i ) {
470  MemDepEntryPtr woken_inst = inst_entry->dependInsts[i];
471 
472  if (!woken_inst->inst) {
473  // Potentially removed mem dep entries could be on this list
474  continue;
475  }
476 
477  DPRINTF(MemDepUnit, "Waking up a dependent inst, "
478  "[sn:%lli].\n",
479  woken_inst->inst->seqNum);
480 
481  assert(woken_inst->memDeps > 0);
482  woken_inst->memDeps -= 1;
483 
484  if ((woken_inst->memDeps == 0) &&
485  woken_inst->regsReady &&
486  !woken_inst->squashed) {
487  moveToReady(woken_inst);
488  }
489  }
490 
491  inst_entry->dependInsts.clear();
492 }
493 
495  inst(new_inst)
496 {
497 #ifdef DEBUG
498  ++memdep_count;
499 
501  "Memory dependency entry created. memdep_count=%i %s\n",
502  memdep_count, inst->pcState());
503 #endif
504 }
505 
507 {
508  for (int i = 0; i < dependInsts.size(); ++i) {
509  dependInsts[i] = NULL;
510  }
511 #ifdef DEBUG
512  --memdep_count;
513 
515  "Memory dependency entry deleted. memdep_count=%i %s\n",
516  memdep_count, inst->pcState());
517 #endif
518 }
519 
520 void
521 MemDepUnit::squash(const InstSeqNum &squashed_num, ThreadID tid)
522 {
523  if (!instsToReplay.empty()) {
524  ListIt replay_it = instsToReplay.begin();
525  while (replay_it != instsToReplay.end()) {
526  if ((*replay_it)->threadNumber == tid &&
527  (*replay_it)->seqNum > squashed_num) {
528  instsToReplay.erase(replay_it++);
529  } else {
530  ++replay_it;
531  }
532  }
533  }
534 
535  ListIt squash_it = instList[tid].end();
536  --squash_it;
537 
538  MemDepHashIt hash_it;
539 
540  while (!instList[tid].empty() &&
541  (*squash_it)->seqNum > squashed_num) {
542 
543  DPRINTF(MemDepUnit, "Squashing inst [sn:%lli]\n",
544  (*squash_it)->seqNum);
545 
546  loadBarrierSNs.erase((*squash_it)->seqNum);
547 
548  storeBarrierSNs.erase((*squash_it)->seqNum);
549 
550  hash_it = memDepHash.find((*squash_it)->seqNum);
551 
552  assert(hash_it != memDepHash.end());
553 
554  (*hash_it).second->squashed = true;
555 
556  (*hash_it).second = NULL;
557 
558  memDepHash.erase(hash_it);
559 #ifdef DEBUG
560  MemDepEntry::memdep_erase++;
561 #endif
562 
563  instList[tid].erase(squash_it--);
564  }
565 
566  // Tell the dependency predictor to squash as well.
567  depPred.squash(squashed_num, tid);
568 }
569 
570 void
572  const DynInstPtr &violating_load)
573 {
574  DPRINTF(MemDepUnit, "Passing violating PCs to store sets,"
575  " load: %#x, store: %#x\n", violating_load->pcState().instAddr(),
576  store_inst->pcState().instAddr());
577  // Tell the memory dependence unit of the violation.
578  depPred.violation(store_inst->pcState().instAddr(),
579  violating_load->pcState().instAddr());
580 }
581 
582 void
584 {
585  DPRINTF(MemDepUnit, "Issuing instruction PC %#x [sn:%lli].\n",
586  inst->pcState().instAddr(), inst->seqNum);
587 
588  depPred.issued(inst->pcState().instAddr(), inst->seqNum, inst->isStore());
589 }
590 
593 {
594  MemDepHashIt hash_it = memDepHash.find(inst->seqNum);
595 
596  assert(hash_it != memDepHash.end());
597 
598  return (*hash_it).second;
599 }
600 
601 void
603 {
604  DPRINTF(MemDepUnit, "Adding instruction [sn:%lli] "
605  "to the ready list.\n", woken_inst_entry->inst->seqNum);
606 
607  assert(!woken_inst_entry->squashed);
608 
609  iqPtr->addReadyMemInst(woken_inst_entry->inst);
610 }
611 
612 
613 void
615 {
616  for (ThreadID tid = 0; tid < MaxThreads; tid++) {
617  cprintf("Instruction list %i size: %i\n",
618  tid, instList[tid].size());
619 
620  ListIt inst_list_it = instList[tid].begin();
621  int num = 0;
622 
623  while (inst_list_it != instList[tid].end()) {
624  cprintf("Instruction:%i\nPC: %s\n[sn:%llu]\n[tid:%i]\nIssued:%i\n"
625  "Squashed:%i\n\n",
626  num, (*inst_list_it)->pcState(),
627  (*inst_list_it)->seqNum,
628  (*inst_list_it)->threadNumber,
629  (*inst_list_it)->isIssued(),
630  (*inst_list_it)->isSquashed());
631  inst_list_it++;
632  ++num;
633  }
634  }
635 
636  cprintf("Memory dependence hash size: %i\n", memDepHash.size());
637 
638 #ifdef DEBUG
639  cprintf("Memory dependence entries: %i\n", MemDepEntry::memdep_count);
640 #endif
641 }
642 
643 } // namespace o3
644 } // namespace gem5
#define DPRINTF(x,...)
Definition: trace.hh:186
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
Definition: cpu.hh:94
A standard instruction queue class.
Definition: inst_queue.hh:99
void addReadyMemInst(const DynInstPtr &ready_inst)
Adds a ready memory instruction to the ready list.
Definition: inst_queue.cc:1066
~MemDepEntry()
Frees any pointers.
MemDepEntry(const DynInstPtr &new_inst)
Constructs a memory dependence entry.
DynInstPtr inst
The instruction being tracked.
Memory dependency unit class.
Definition: mem_dep_unit.hh:91
bool isDrained() const
Determine if we are drained.
void completeInst(const DynInstPtr &inst)
Notifies completion of an instruction.
void takeOverFrom()
Takes over from another CPU's thread.
std::list< DynInstPtr > instList[MaxThreads]
A list of all instructions in the memory dependence unit.
void moveToReady(MemDepEntryPtr &ready_inst_entry)
Moves an entry to the ready list.
bool hasStoreBarrier() const
Is there an outstanding store barrier that loads must wait on.
void nonSpecInstReady(const DynInstPtr &inst)
Indicate that a non-speculative instruction is ready.
std::shared_ptr< MemDepEntry > MemDepEntryPtr
std::list< DynInstPtr >::iterator ListIt
MemDepUnit()
Empty constructor.
Definition: mem_dep_unit.cc:55
void completed(const DynInstPtr &inst)
Completes a memory instruction.
~MemDepUnit()
Frees up any memory allocated.
Definition: mem_dep_unit.cc:67
void dumpLists()
Debugging function to dump the lists of instructions.
std::unordered_set< InstSeqNum > loadBarrierSNs
Sequence numbers of outstanding load barriers.
void issue(const DynInstPtr &inst)
Issues the given instruction.
void insert(const DynInstPtr &inst)
Inserts a memory instruction.
void squash(const InstSeqNum &squashed_num, ThreadID tid)
Squashes all instructions up until a given sequence number for a specific thread.
void violation(const DynInstPtr &store_inst, const DynInstPtr &violating_load)
Indicates an ordering violation between a store and a younger load.
StoreSet depPred
The memory dependence predictor.
void replay()
Replays all instructions that have been rescheduled by moving them to the ready list.
void wakeDependents(const DynInstPtr &inst)
Wakes any dependents of a memory instruction.
void init(const BaseO3CPUParams &params, ThreadID tid, CPU *cpu)
Initializes the unit with parameters and a thread id.
Definition: mem_dep_unit.cc:92
MemDepHash memDepHash
A hash map of all memory dependence entries.
std::list< DynInstPtr > instsToReplay
A list of all instructions that are going to be replayed.
void regsReady(const DynInstPtr &inst)
Indicate that an instruction has its registers ready.
void insertBarrierSN(const DynInstPtr &barr_inst)
Inserts the SN of a barrier inst.
std::unordered_set< InstSeqNum > storeBarrierSNs
Sequence numbers of outstanding store barriers.
bool hasLoadBarrier() const
Is there an outstanding load barrier that loads must wait on.
MemDepEntryPtr & findInHash(const DynInstConstPtr &inst)
Finds the memory dependence entry in the hash map.
InstructionQueue * iqPtr
Pointer to the IQ.
MemDepHash::iterator MemDepHashIt
gem5::o3::MemDepUnit::MemDepUnitStats stats
void insertNonSpec(const DynInstPtr &inst)
Inserts a non-speculative memory instruction.
void drainSanityCheck() const
Perform sanity checks after a drain.
void reschedule(const DynInstPtr &inst)
Reschedules an instruction to be re-executed.
void insertBarrier(const DynInstPtr &barr_inst)
Inserts a barrier instruction.
void setIQ(InstructionQueue *iq_ptr)
Sets the pointer to the IQ.
void squash(InstSeqNum squashed_num, ThreadID tid)
Squashes for a specific thread until the given sequence number.
Definition: store_set.cc:315
void clear()
Resets all tables.
Definition: store_set.cc:345
void insertStore(Addr store_PC, InstSeqNum store_seq_num, ThreadID tid)
Inserts a store into the store set predictor.
Definition: store_set.cc:213
void init(uint64_t clear_period, int SSIT_size, int LFST_size)
Initializes the store set predictor with the given table sizes.
Definition: store_set.cc:85
void issued(Addr issued_PC, InstSeqNum issued_seq_num, bool is_store)
Records this PC/sequence number as issued.
Definition: store_set.cc:278
InstSeqNum checkInst(Addr PC)
Checks if the instruction with the given PC is dependent upon any store.
Definition: store_set.cc:243
void violation(Addr store_PC, Addr load_PC)
Records a memory ordering violation between the younger load and the older store.
Definition: store_set.cc:120
Statistics container.
Definition: group.hh:94
STL pair class.
Definition: stl.hh:58
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
void addStatGroup(const char *name, Group *block)
Add a stat block as a child of this block.
Definition: group.cc:117
Bitfield< 7 > i
Definition: misc_types.hh:67
static constexpr int MaxThreads
Definition: limits.hh:38
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:235
void cprintf(const char *format, const Args &...args)
Definition: cprintf.hh:155
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
uint64_t InstSeqNum
Definition: inst_seq.hh:40
statistics::Scalar conflictingLoads
Stat for number of conflicting loads that had to wait for a store.
MemDepUnitStats(statistics::Group *parent)
statistics::Scalar conflictingStores
Stat for number of conflicting stores that had to wait for a store.
statistics::Scalar insertedLoads
Stat for number of inserted loads.
statistics::Scalar insertedStores
Stat for number of inserted stores.
const std::string & name()
Definition: trace.cc:49

Generated on Wed Dec 21 2022 10:22:31 for gem5 by doxygen 1.9.1