gem5  v21.0.0.0
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 <memory>
46 #include <vector>
47 
48 #include "base/debug.hh"
49 #include "cpu/o3/inst_queue.hh"
50 #include "cpu/o3/mem_dep_unit.hh"
51 #include "debug/MemDepUnit.hh"
52 #include "params/DerivO3CPU.hh"
53 
54 template <class MemDepPred, class Impl>
56  : iqPtr(NULL),
57  stats(nullptr)
58 {
59 }
60 
61 template <class MemDepPred, class Impl>
62 MemDepUnit<MemDepPred, Impl>::MemDepUnit(const DerivO3CPUParams &params)
63  : _name(params.name + ".memdepunit"),
64  depPred(params.store_set_clear_period, params.SSITSize,
65  params.LFSTSize),
66  iqPtr(NULL),
67  stats(nullptr)
68 {
69  DPRINTF(MemDepUnit, "Creating MemDepUnit object.\n");
70 }
71 
72 template <class MemDepPred, class Impl>
74 {
75  for (ThreadID tid = 0; tid < Impl::MaxThreads; tid++) {
76 
77  ListIt inst_list_it = instList[tid].begin();
78 
79  MemDepHashIt hash_it;
80 
81  while (!instList[tid].empty()) {
82  hash_it = memDepHash.find((*inst_list_it)->seqNum);
83 
84  assert(hash_it != memDepHash.end());
85 
86  memDepHash.erase(hash_it);
87 
88  instList[tid].erase(inst_list_it++);
89  }
90  }
91 
92 #ifdef DEBUG
93  assert(MemDepEntry::memdep_count == 0);
94 #endif
95 }
96 
97 template <class MemDepPred, class Impl>
98 void
100  const DerivO3CPUParams &params, ThreadID tid, O3CPU *cpu)
101 {
102  DPRINTF(MemDepUnit, "Creating MemDepUnit %i object.\n",tid);
103 
104  _name = csprintf("%s.memDep%d", params.name, tid);
105  id = tid;
106 
107  depPred.init(params.store_set_clear_period, params.SSITSize,
108  params.LFSTSize);
109 
110  std::string stats_group_name = csprintf("MemDepUnit__%i", tid);
111  cpu->addStatGroup(stats_group_name.c_str(), &stats);
112 }
113 
114 template <class MemDepPred, class Impl>
117  : Stats::Group(parent),
118  ADD_STAT(insertedLoads, UNIT_COUNT,
119  "Number of loads inserted to the mem dependence unit."),
120  ADD_STAT(insertedStores, UNIT_COUNT,
121  "Number of stores inserted to the mem dependence unit."),
122  ADD_STAT(conflictingLoads, UNIT_COUNT, "Number of conflicting loads."),
123  ADD_STAT(conflictingStores, UNIT_COUNT, "Number of conflicting stores.")
124 {
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 
175  if (barr_inst->isReadBarrier() || barr_inst->isHtmCmd())
176  loadBarrierSNs.insert(barr_sn);
177  if (barr_inst->isWriteBarrier() || barr_inst->isHtmCmd())
178  storeBarrierSNs.insert(barr_sn);
179 
180  if (DTRACE(MemDepUnit)) {
181  const char *barrier_type = nullptr;
182  if (barr_inst->isReadBarrier() && barr_inst->isWriteBarrier())
183  barrier_type = "memory";
184  else if (barr_inst->isReadBarrier())
185  barrier_type = "read";
186  else if (barr_inst->isWriteBarrier())
187  barrier_type = "write";
188 
189  if (barrier_type) {
190  DPRINTF(MemDepUnit, "Inserted a %s barrier %s SN:%lli\n",
191  barrier_type, barr_inst->pcState(), barr_sn);
192  }
193 
194  if (loadBarrierSNs.size() || storeBarrierSNs.size()) {
195  DPRINTF(MemDepUnit, "Outstanding load barriers = %d; "
196  "store barriers = %d\n",
197  loadBarrierSNs.size(), storeBarrierSNs.size());
198  }
199  }
200 }
201 
202 template <class MemDepPred, class Impl>
203 void
205 {
206  ThreadID tid = inst->threadNumber;
207 
208  MemDepEntryPtr inst_entry = std::make_shared<MemDepEntry>(inst);
209 
210  // Add the MemDepEntry to the hash.
211  memDepHash.insert(
212  std::pair<InstSeqNum, MemDepEntryPtr>(inst->seqNum, inst_entry));
213 #ifdef DEBUG
214  MemDepEntry::memdep_insert++;
215 #endif
216 
217  instList[tid].push_back(inst);
218 
219  inst_entry->listIt = --(instList[tid].end());
220 
221  // Check any barriers and the dependence predictor for any
222  // producing memrefs/stores.
223  std::vector<InstSeqNum> producing_stores;
224  if ((inst->isLoad() || inst->isAtomic()) && hasLoadBarrier()) {
225  DPRINTF(MemDepUnit, "%d load barriers in flight\n",
226  loadBarrierSNs.size());
227  producing_stores.insert(std::end(producing_stores),
228  std::begin(loadBarrierSNs),
229  std::end(loadBarrierSNs));
230  } else if ((inst->isStore() || inst->isAtomic()) && hasStoreBarrier()) {
231  DPRINTF(MemDepUnit, "%d store barriers in flight\n",
232  storeBarrierSNs.size());
233  producing_stores.insert(std::end(producing_stores),
234  std::begin(storeBarrierSNs),
235  std::end(storeBarrierSNs));
236  } else {
237  InstSeqNum dep = depPred.checkInst(inst->instAddr());
238  if (dep != 0)
239  producing_stores.push_back(dep);
240  }
241 
242  std::vector<MemDepEntryPtr> store_entries;
243 
244  // If there is a producing store, try to find the entry.
245  for (auto producing_store : producing_stores) {
246  DPRINTF(MemDepUnit, "Searching for producer [sn:%lli]\n",
247  producing_store);
248  MemDepHashIt hash_it = memDepHash.find(producing_store);
249 
250  if (hash_it != memDepHash.end()) {
251  store_entries.push_back((*hash_it).second);
252  DPRINTF(MemDepUnit, "Producer found\n");
253  }
254  }
255 
256  // If no store entry, then instruction can issue as soon as the registers
257  // are ready.
258  if (store_entries.empty()) {
259  DPRINTF(MemDepUnit, "No dependency for inst PC "
260  "%s [sn:%lli].\n", inst->pcState(), inst->seqNum);
261 
262  assert(inst_entry->memDeps == 0);
263 
264  if (inst->readyToIssue()) {
265  inst_entry->regsReady = true;
266 
267  moveToReady(inst_entry);
268  }
269  } else {
270  // Otherwise make the instruction dependent on the store/barrier.
271  DPRINTF(MemDepUnit, "Adding to dependency list\n");
272  for (M5_VAR_USED auto producing_store : producing_stores)
273  DPRINTF(MemDepUnit, "\tinst PC %s is dependent on [sn:%lli].\n",
274  inst->pcState(), producing_store);
275 
276  if (inst->readyToIssue()) {
277  inst_entry->regsReady = true;
278  }
279 
280  // Clear the bit saying this instruction can issue.
281  inst->clearCanIssue();
282 
283  // Add this instruction to the list of dependents.
284  for (auto store_entry : store_entries)
285  store_entry->dependInsts.push_back(inst_entry);
286 
287  inst_entry->memDeps = store_entries.size();
288 
289  if (inst->isLoad()) {
291  } else {
293  }
294  }
295 
296  // for load-acquire store-release that could also be a barrier
297  insertBarrierSN(inst);
298 
299  if (inst->isStore() || inst->isAtomic()) {
300  DPRINTF(MemDepUnit, "Inserting store/atomic PC %s [sn:%lli].\n",
301  inst->pcState(), inst->seqNum);
302 
303  depPred.insertStore(inst->instAddr(), inst->seqNum, inst->threadNumber);
304 
306  } else if (inst->isLoad()) {
308  } else {
309  panic("Unknown type! (most likely a barrier).");
310  }
311 }
312 
313 template <class MemDepPred, class Impl>
314 void
316 {
317  insertBarrier(inst);
318 
319  // Might want to turn this part into an inline function or something.
320  // It's shared between both insert functions.
321  if (inst->isStore() || inst->isAtomic()) {
322  DPRINTF(MemDepUnit, "Inserting store/atomic PC %s [sn:%lli].\n",
323  inst->pcState(), inst->seqNum);
324 
325  depPred.insertStore(inst->instAddr(), inst->seqNum, inst->threadNumber);
326 
328  } else if (inst->isLoad()) {
330  } else {
331  panic("Unknown type! (most likely a barrier).");
332  }
333 }
334 
335 template <class MemDepPred, class Impl>
336 void
338 {
339  ThreadID tid = barr_inst->threadNumber;
340 
341  MemDepEntryPtr inst_entry = std::make_shared<MemDepEntry>(barr_inst);
342 
343  // Add the MemDepEntry to the hash.
344  memDepHash.insert(
345  std::pair<InstSeqNum, MemDepEntryPtr>(barr_inst->seqNum, inst_entry));
346 #ifdef DEBUG
347  MemDepEntry::memdep_insert++;
348 #endif
349 
350  // Add the instruction to the instruction list.
351  instList[tid].push_back(barr_inst);
352 
353  inst_entry->listIt = --(instList[tid].end());
354 
355  insertBarrierSN(barr_inst);
356 }
357 
358 template <class MemDepPred, class Impl>
359 void
361 {
362  DPRINTF(MemDepUnit, "Marking registers as ready for "
363  "instruction PC %s [sn:%lli].\n",
364  inst->pcState(), inst->seqNum);
365 
366  MemDepEntryPtr inst_entry = findInHash(inst);
367 
368  inst_entry->regsReady = true;
369 
370  if (inst_entry->memDeps == 0) {
371  DPRINTF(MemDepUnit, "Instruction has its memory "
372  "dependencies resolved, adding it to the ready list.\n");
373 
374  moveToReady(inst_entry);
375  } else {
376  DPRINTF(MemDepUnit, "Instruction still waiting on "
377  "memory dependency.\n");
378  }
379 }
380 
381 template <class MemDepPred, class Impl>
382 void
384 {
385  DPRINTF(MemDepUnit, "Marking non speculative "
386  "instruction PC %s as ready [sn:%lli].\n",
387  inst->pcState(), inst->seqNum);
388 
389  MemDepEntryPtr inst_entry = findInHash(inst);
390 
391  moveToReady(inst_entry);
392 }
393 
394 template <class MemDepPred, class Impl>
395 void
397 {
398  instsToReplay.push_back(inst);
399 }
400 
401 template <class MemDepPred, class Impl>
402 void
404 {
405  DynInstPtr temp_inst;
406 
407  // For now this replay function replays all waiting memory ops.
408  while (!instsToReplay.empty()) {
409  temp_inst = instsToReplay.front();
410 
411  MemDepEntryPtr inst_entry = findInHash(temp_inst);
412 
413  DPRINTF(MemDepUnit, "Replaying mem instruction PC %s [sn:%lli].\n",
414  temp_inst->pcState(), temp_inst->seqNum);
415 
416  moveToReady(inst_entry);
417 
418  instsToReplay.pop_front();
419  }
420 }
421 
422 template <class MemDepPred, class Impl>
423 void
425 {
426  DPRINTF(MemDepUnit, "Completed mem instruction PC %s [sn:%lli].\n",
427  inst->pcState(), inst->seqNum);
428 
429  ThreadID tid = inst->threadNumber;
430 
431  // Remove the instruction from the hash and the list.
432  MemDepHashIt hash_it = memDepHash.find(inst->seqNum);
433 
434  assert(hash_it != memDepHash.end());
435 
436  instList[tid].erase((*hash_it).second->listIt);
437 
438  (*hash_it).second = NULL;
439 
440  memDepHash.erase(hash_it);
441 #ifdef DEBUG
442  MemDepEntry::memdep_erase++;
443 #endif
444 }
445 
446 template <class MemDepPred, class Impl>
447 void
449 {
450  wakeDependents(inst);
451  completed(inst);
452  InstSeqNum barr_sn = inst->seqNum;
453 
454  if (inst->isWriteBarrier() || inst->isHtmCmd()) {
455  assert(hasStoreBarrier());
456  storeBarrierSNs.erase(barr_sn);
457  }
458  if (inst->isReadBarrier() || inst->isHtmCmd()) {
459  assert(hasLoadBarrier());
460  loadBarrierSNs.erase(barr_sn);
461  }
462  if (DTRACE(MemDepUnit)) {
463  const char *barrier_type = nullptr;
464  if (inst->isWriteBarrier() && inst->isReadBarrier())
465  barrier_type = "Memory";
466  else if (inst->isWriteBarrier())
467  barrier_type = "Write";
468  else if (inst->isReadBarrier())
469  barrier_type = "Read";
470 
471  if (barrier_type) {
472  DPRINTF(MemDepUnit, "%s barrier completed: %s SN:%lli\n",
473  barrier_type, inst->pcState(), inst->seqNum);
474  }
475  }
476 }
477 
478 template <class MemDepPred, class Impl>
479 void
481 {
482  // Only stores, atomics and barriers have dependents.
483  if (!inst->isStore() && !inst->isAtomic() && !inst->isReadBarrier() &&
484  !inst->isWriteBarrier() && !inst->isHtmCmd()) {
485  return;
486  }
487 
488  MemDepEntryPtr inst_entry = findInHash(inst);
489 
490  for (int i = 0; i < inst_entry->dependInsts.size(); ++i ) {
491  MemDepEntryPtr woken_inst = inst_entry->dependInsts[i];
492 
493  if (!woken_inst->inst) {
494  // Potentially removed mem dep entries could be on this list
495  continue;
496  }
497 
498  DPRINTF(MemDepUnit, "Waking up a dependent inst, "
499  "[sn:%lli].\n",
500  woken_inst->inst->seqNum);
501 
502  assert(woken_inst->memDeps > 0);
503  woken_inst->memDeps -= 1;
504 
505  if ((woken_inst->memDeps == 0) &&
506  woken_inst->regsReady &&
507  !woken_inst->squashed) {
508  moveToReady(woken_inst);
509  }
510  }
511 
512  inst_entry->dependInsts.clear();
513 }
514 
515 template <class MemDepPred, class Impl>
516 void
518  ThreadID tid)
519 {
520  if (!instsToReplay.empty()) {
521  ListIt replay_it = instsToReplay.begin();
522  while (replay_it != instsToReplay.end()) {
523  if ((*replay_it)->threadNumber == tid &&
524  (*replay_it)->seqNum > squashed_num) {
525  instsToReplay.erase(replay_it++);
526  } else {
527  ++replay_it;
528  }
529  }
530  }
531 
532  ListIt squash_it = instList[tid].end();
533  --squash_it;
534 
535  MemDepHashIt hash_it;
536 
537  while (!instList[tid].empty() &&
538  (*squash_it)->seqNum > squashed_num) {
539 
540  DPRINTF(MemDepUnit, "Squashing inst [sn:%lli]\n",
541  (*squash_it)->seqNum);
542 
543  loadBarrierSNs.erase((*squash_it)->seqNum);
544 
545  storeBarrierSNs.erase((*squash_it)->seqNum);
546 
547  hash_it = memDepHash.find((*squash_it)->seqNum);
548 
549  assert(hash_it != memDepHash.end());
550 
551  (*hash_it).second->squashed = true;
552 
553  (*hash_it).second = NULL;
554 
555  memDepHash.erase(hash_it);
556 #ifdef DEBUG
557  MemDepEntry::memdep_erase++;
558 #endif
559 
560  instList[tid].erase(squash_it--);
561  }
562 
563  // Tell the dependency predictor to squash as well.
564  depPred.squash(squashed_num, tid);
565 }
566 
567 template <class MemDepPred, class Impl>
568 void
570  const DynInstPtr &violating_load)
571 {
572  DPRINTF(MemDepUnit, "Passing violating PCs to store sets,"
573  " load: %#x, store: %#x\n", violating_load->instAddr(),
574  store_inst->instAddr());
575  // Tell the memory dependence unit of the violation.
576  depPred.violation(store_inst->instAddr(), violating_load->instAddr());
577 }
578 
579 template <class MemDepPred, class Impl>
580 void
582 {
583  DPRINTF(MemDepUnit, "Issuing instruction PC %#x [sn:%lli].\n",
584  inst->instAddr(), inst->seqNum);
585 
586  depPred.issued(inst->instAddr(), inst->seqNum, inst->isStore());
587 }
588 
589 template <class MemDepPred, class Impl>
592 {
593  MemDepHashIt hash_it = memDepHash.find(inst->seqNum);
594 
595  assert(hash_it != memDepHash.end());
596 
597  return (*hash_it).second;
598 }
599 
600 template <class MemDepPred, class Impl>
601 inline 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 template <class MemDepPred, class Impl>
614 void
616 {
617  for (ThreadID tid = 0; tid < Impl::MaxThreads; tid++) {
618  cprintf("Instruction list %i size: %i\n",
619  tid, instList[tid].size());
620 
621  ListIt inst_list_it = instList[tid].begin();
622  int num = 0;
623 
624  while (inst_list_it != instList[tid].end()) {
625  cprintf("Instruction:%i\nPC: %s\n[sn:%llu]\n[tid:%i]\nIssued:%i\n"
626  "Squashed:%i\n\n",
627  num, (*inst_list_it)->pcState(),
628  (*inst_list_it)->seqNum,
629  (*inst_list_it)->threadNumber,
630  (*inst_list_it)->isIssued(),
631  (*inst_list_it)->isSquashed());
632  inst_list_it++;
633  ++num;
634  }
635  }
636 
637  cprintf("Memory dependence hash size: %i\n", memDepHash.size());
638 
639 #ifdef DEBUG
640  cprintf("Memory dependence entries: %i\n", MemDepEntry::memdep_count);
641 #endif
642 }
643 
644 #endif//__CPU_O3_MEM_DEP_UNIT_IMPL_HH__
MemDepUnit::MemDepHashIt
MemDepHash::iterator MemDepHashIt
Definition: mem_dep_unit.hh:242
MemDepUnit::replay
void replay()
Replays all instructions that have been rescheduled by moving them to the ready list.
Definition: mem_dep_unit_impl.hh:403
MemDepUnit::DynInstConstPtr
Impl::DynInstConstPtr DynInstConstPtr
Definition: mem_dep_unit.hh:87
MemDepUnit::takeOverFrom
void takeOverFrom()
Takes over from another CPU's thread.
Definition: mem_dep_unit_impl.hh:154
MemDepUnit::ListIt
std::list< DynInstPtr >::iterator ListIt
Definition: mem_dep_unit.hh:166
MemDepUnit::nonSpecInstReady
void nonSpecInstReady(const DynInstPtr &inst)
Indicate that a non-speculative instruction is ready.
Definition: mem_dep_unit_impl.hh:383
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
ThreadID
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:233
MemDepUnit::wakeDependents
void wakeDependents(const DynInstPtr &inst)
Wakes any dependents of a memory instruction.
Definition: mem_dep_unit_impl.hh:480
MemDepUnit::isDrained
bool isDrained() const
Determine if we are drained.
Definition: mem_dep_unit_impl.hh:129
MemDepUnit::hasLoadBarrier
bool hasLoadBarrier() const
Is there an outstanding load barrier that loads must wait on.
Definition: mem_dep_unit.hh:267
MemDepUnit::issue
void issue(const DynInstPtr &inst)
Issues the given instruction.
Definition: mem_dep_unit_impl.hh:581
DTRACE
#define DTRACE(x)
Definition: debug.hh:156
std::vector< InstSeqNum >
MemDepUnit::MemDepUnit
MemDepUnit()
Empty constructor.
Definition: mem_dep_unit_impl.hh:55
MemDepUnit::memDepHash
MemDepHash memDepHash
A hash map of all memory dependence entries.
Definition: mem_dep_unit.hh:245
MemDepUnit::completeInst
void completeInst(const DynInstPtr &inst)
Notifies completion of an instruction.
Definition: mem_dep_unit_impl.hh:448
MemDepUnit::MemDepUnitStats::insertedLoads
Stats::Scalar insertedLoads
Stat for number of inserted loads.
Definition: mem_dep_unit.hh:284
MemDepUnit::violation
void violation(const DynInstPtr &store_inst, const DynInstPtr &violating_load)
Indicates an ordering violation between a store and a younger load.
Definition: mem_dep_unit_impl.hh:569
MemDepUnit::iqPtr
InstructionQueue< Impl > * iqPtr
Pointer to the IQ.
Definition: mem_dep_unit.hh:276
MemDepUnit::findInHash
MemDepEntryPtr & findInHash(const DynInstConstPtr &inst)
Finds the memory dependence entry in the hash map.
Definition: mem_dep_unit_impl.hh:591
MemDepUnit::MemDepUnitStats::insertedStores
Stats::Scalar insertedStores
Stat for number of inserted stores.
Definition: mem_dep_unit.hh:286
MemDepUnit::squash
void squash(const InstSeqNum &squashed_num, ThreadID tid)
Squashes all instructions up until a given sequence number for a specific thread.
Definition: mem_dep_unit_impl.hh:517
MemDepUnit::instsToReplay
std::list< DynInstPtr > instsToReplay
A list of all instructions that are going to be replayed.
Definition: mem_dep_unit.hh:251
MemDepUnit::dumpLists
void dumpLists()
Debugging function to dump the lists of instructions.
Definition: mem_dep_unit_impl.hh:615
MemDepUnit::insertNonSpec
void insertNonSpec(const DynInstPtr &inst)
Inserts a non-speculative memory instruction.
Definition: mem_dep_unit_impl.hh:315
MemDepUnit::init
void init(const DerivO3CPUParams &params, ThreadID tid, O3CPU *cpu)
Initializes the unit with parameters and a thread id.
Definition: mem_dep_unit_impl.hh:99
cprintf
void cprintf(const char *format, const Args &...args)
Definition: cprintf.hh:152
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:71
MemDepUnit::~MemDepUnit
~MemDepUnit()
Frees up any memory allocated.
Definition: mem_dep_unit_impl.hh:73
mem_dep_unit.hh
MemDepUnit::reschedule
void reschedule(const DynInstPtr &inst)
Reschedules an instruction to be re-executed.
Definition: mem_dep_unit_impl.hh:396
debug.hh
MemDepUnit::moveToReady
void moveToReady(MemDepEntryPtr &ready_inst_entry)
Moves an entry to the ready list.
Definition: mem_dep_unit_impl.hh:602
std::pair
STL pair class.
Definition: stl.hh:58
InstSeqNum
uint64_t InstSeqNum
Definition: inst_seq.hh:37
UNIT_COUNT
#define UNIT_COUNT
Definition: units.hh:49
MemDepUnit::setIQ
void setIQ(InstructionQueue< Impl > *iq_ptr)
Sets the pointer to the IQ.
Definition: mem_dep_unit_impl.hh:164
name
const std::string & name()
Definition: trace.cc:48
MemDepUnit::instList
std::list< DynInstPtr > instList[Impl::MaxThreads]
A list of all instructions in the memory dependence unit.
Definition: mem_dep_unit.hh:248
MemDepUnit::insertBarrier
void insertBarrier(const DynInstPtr &barr_inst)
Inserts a barrier instruction.
Definition: mem_dep_unit_impl.hh:337
MemDepUnit::regsReady
void regsReady(const DynInstPtr &inst)
Indicate that an instruction has its registers ready.
Definition: mem_dep_unit_impl.hh:360
MemDepUnit::stats
MemDepUnit::MemDepUnitStats stats
MemDepUnit::storeBarrierSNs
std::unordered_set< InstSeqNum > storeBarrierSNs
Sequence numbers of outstanding store barriers.
Definition: mem_dep_unit.hh:264
MemDepUnit::insert
void insert(const DynInstPtr &inst)
Inserts a memory instruction.
Definition: mem_dep_unit_impl.hh:204
MemDepUnit::MemDepUnitStats::conflictingLoads
Stats::Scalar conflictingLoads
Stat for number of conflicting loads that had to wait for a store.
Definition: mem_dep_unit.hh:289
MemDepUnit::insertBarrierSN
void insertBarrierSN(const DynInstPtr &barr_inst)
Inserts the SN of a barrier inst.
Definition: mem_dep_unit_impl.hh:171
MemDepUnit::depPred
MemDepPred depPred
The memory dependence predictor.
Definition: mem_dep_unit.hh:258
Stats::Group
Statistics container.
Definition: group.hh:87
InstructionQueue
A standard instruction queue class.
Definition: inst_queue.hh:81
MemDepUnit::DynInstPtr
Impl::DynInstPtr DynInstPtr
Definition: mem_dep_unit.hh:86
MemDepUnit::MemDepEntryPtr
std::shared_ptr< MemDepEntry > MemDepEntryPtr
Definition: mem_dep_unit.hh:168
MemDepUnit::drainSanityCheck
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: mem_dep_unit_impl.hh:142
Stats
Definition: statistics.cc:53
inst_queue.hh
MemDepUnit
Memory dependency unit class.
Definition: mem_dep_unit.hh:80
MemDepUnit::O3CPU
Impl::O3CPU O3CPU
Definition: mem_dep_unit.hh:88
MemDepUnit::hasStoreBarrier
bool hasStoreBarrier() const
Is there an outstanding store barrier that loads must wait on.
Definition: mem_dep_unit.hh:270
MemDepUnit::completed
void completed(const DynInstPtr &inst)
Completes a memory instruction.
Definition: mem_dep_unit_impl.hh:424
MemDepUnit::MemDepUnitStats::conflictingStores
Stats::Scalar conflictingStores
Stat for number of conflicting stores that had to wait for a store.
Definition: mem_dep_unit.hh:292
csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:158
MemDepUnit::loadBarrierSNs
std::unordered_set< InstSeqNum > loadBarrierSNs
Sequence numbers of outstanding load barriers.
Definition: mem_dep_unit.hh:261
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
MemDepUnit::MemDepUnitStats::MemDepUnitStats
MemDepUnitStats(Stats::Group *parent)
Definition: mem_dep_unit_impl.hh:116

Generated on Tue Mar 23 2021 19:41:25 for gem5 by doxygen 1.8.17