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

Generated on Mon Jun 8 2020 15:45:08 for gem5 by doxygen 1.8.13