gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
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 <map>
30#include <memory>
31#include <vector>
32
33#include "base/compiler.hh"
34#include "base/debug.hh"
35#include "cpu/o3/dyn_inst.hh"
36#include "cpu/o3/inst_queue.hh"
37#include "cpu/o3/limits.hh"
39#include "debug/MemDepUnit.hh"
40#include "params/BaseO3CPU.hh"
41
42namespace gem5
43{
44
45namespace o3
46{
47
48#ifdef GEM5_DEBUG
49int MemDepUnit::MemDepEntry::memdep_count = 0;
50int MemDepUnit::MemDepEntry::memdep_insert = 0;
51int MemDepUnit::MemDepEntry::memdep_erase = 0;
52#endif
53
54MemDepUnit::MemDepUnit() : iqPtr(NULL), stats(nullptr) {}
55
56MemDepUnit::MemDepUnit(const BaseO3CPUParams &params)
57 : _name(params.name + ".memdepunit"),
58 depPred(_name + ".storesets", params.store_set_clear_period,
59 params.SSITSize, params.SSITAssoc, params.SSITReplPolicy,
60 params.SSITIndexingPolicy, 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 GEM5_DEBUG
87 assert(MemDepEntry::memdep_count == 0);
88#endif
89}
90
91void
92MemDepUnit::init(const BaseO3CPUParams &params, ThreadID tid, CPU *cpu)
93{
94 _name = csprintf("%s.memDep%d", params.name, tid);
95
96 DPRINTF(MemDepUnit, "Creating MemDepUnit %i object.\n",tid);
97
98 id = tid;
99
100 depPred.init(params.store_set_clear_period,
101 params.SSITSize, params.SSITAssoc, params.SSITReplPolicy,
102 params.SSITIndexingPolicy, params.LFSTSize);
103
104 std::string stats_group_name = csprintf("MemDepUnit__%i", tid);
105 cpu->addStatGroup(stats_group_name.c_str(), &stats);
106}
107
109 : statistics::Group(parent),
110 ADD_STAT(insertedLoads, statistics::units::Count::get(),
111 "Number of loads inserted to the mem dependence unit."),
112 ADD_STAT(insertedStores, statistics::units::Count::get(),
113 "Number of stores inserted to the mem dependence unit."),
115 "Number of conflicting loads."),
117 "Number of conflicting stores.")
118{
119}
120
121bool
123{
124 bool drained = instsToReplay.empty()
125 && memDepHash.empty()
126 && instsToReplay.empty();
127 for (int i = 0; i < MaxThreads; ++i)
128 drained = drained && instList[i].empty();
129
130 return drained;
131}
132
133void
135{
136 assert(instsToReplay.empty());
137 assert(memDepHash.empty());
138 for (int i = 0; i < MaxThreads; ++i)
139 assert(instList[i].empty());
140 assert(instsToReplay.empty());
141 assert(memDepHash.empty());
142}
143
144void
146{
147 // Be sure to reset all state.
148 loadBarrierSNs.clear();
149 storeBarrierSNs.clear();
150 depPred.clear();
151}
152
153void
155{
156 iqPtr = iq_ptr;
157}
158
159void
161{
162 InstSeqNum barr_sn = barr_inst->seqNum;
163
164 if (barr_inst->isReadBarrier() || barr_inst->isHtmCmd())
165 loadBarrierSNs.insert(barr_sn);
166 if (barr_inst->isWriteBarrier() || barr_inst->isHtmCmd())
167 storeBarrierSNs.insert(barr_sn);
168
169 if (debug::MemDepUnit) {
170 const char *barrier_type = nullptr;
171 if (barr_inst->isReadBarrier() && barr_inst->isWriteBarrier())
172 barrier_type = "memory";
173 else if (barr_inst->isReadBarrier())
174 barrier_type = "read";
175 else if (barr_inst->isWriteBarrier())
176 barrier_type = "write";
177
178 if (barrier_type) {
179 DPRINTF(MemDepUnit, "Inserted a %s barrier %s SN:%lli\n",
180 barrier_type, barr_inst->pcState(), barr_sn);
181 }
182
183 if (loadBarrierSNs.size() || storeBarrierSNs.size()) {
184 DPRINTF(MemDepUnit, "Outstanding load barriers = %d; "
185 "store barriers = %d\n",
186 loadBarrierSNs.size(), storeBarrierSNs.size());
187 }
188 }
189}
190
191void
193{
194 ThreadID tid = inst->threadNumber;
195
196 MemDepEntryPtr inst_entry = std::make_shared<MemDepEntry>(inst);
197
198 // Add the MemDepEntry to the hash.
199 memDepHash.insert(
200 std::pair<InstSeqNum, MemDepEntryPtr>(inst->seqNum, inst_entry));
201#ifdef GEM5_DEBUG
202 MemDepEntry::memdep_insert++;
203#endif
204
205 instList[tid].push_back(inst);
206
207 inst_entry->listIt = --(instList[tid].end());
208
209 // Check any barriers and the dependence predictor for any
210 // producing memrefs/stores.
211 std::vector<InstSeqNum> producing_stores;
212 if ((inst->isLoad() || inst->isAtomic()) && hasLoadBarrier()) {
213 DPRINTF(MemDepUnit, "%d load barriers in flight\n",
214 loadBarrierSNs.size());
215 producing_stores.insert(std::end(producing_stores),
216 std::begin(loadBarrierSNs),
217 std::end(loadBarrierSNs));
218 } else if ((inst->isStore() || inst->isAtomic()) && hasStoreBarrier()) {
219 DPRINTF(MemDepUnit, "%d store barriers in flight\n",
220 storeBarrierSNs.size());
221 producing_stores.insert(std::end(producing_stores),
222 std::begin(storeBarrierSNs),
223 std::end(storeBarrierSNs));
224 } else {
225 InstSeqNum dep = depPred.checkInst(inst->pcState().instAddr());
226 if (dep != 0)
227 producing_stores.push_back(dep);
228 }
229
230 std::vector<MemDepEntryPtr> store_entries;
231
232 // If there is a producing store, try to find the entry.
233 for (auto producing_store : producing_stores) {
234 DPRINTF(MemDepUnit, "Searching for producer [sn:%lli]\n",
235 producing_store);
236 MemDepHashIt hash_it = memDepHash.find(producing_store);
237
238 if (hash_it != memDepHash.end()) {
239 store_entries.push_back((*hash_it).second);
240 DPRINTF(MemDepUnit, "Producer found\n");
241 }
242 }
243
244 // If no store entry, then instruction can issue as soon as the registers
245 // are ready.
246 if (store_entries.empty()) {
247 DPRINTF(MemDepUnit, "No dependency for inst PC "
248 "%s [sn:%lli].\n", inst->pcState(), inst->seqNum);
249
250 assert(inst_entry->memDeps == 0);
251
252 if (inst->readyToIssue()) {
253 inst_entry->regsReady = true;
254
255 moveToReady(inst_entry);
256 }
257 } else {
258 // Otherwise make the instruction dependent on the store/barrier.
259 DPRINTF(MemDepUnit, "Adding to dependency list\n");
260 for ([[maybe_unused]] auto producing_store : producing_stores)
261 DPRINTF(MemDepUnit, "\tinst PC %s is dependent on [sn:%lli].\n",
262 inst->pcState(), producing_store);
263
264 if (inst->readyToIssue()) {
265 inst_entry->regsReady = true;
266 }
267
268 // Clear the bit saying this instruction can issue.
269 inst->clearCanIssue();
270
271 // Add this instruction to the list of dependents.
272 for (auto store_entry : store_entries)
273 store_entry->dependInsts.push_back(inst_entry);
274
275 inst_entry->memDeps = store_entries.size();
276
277 if (inst->isLoad()) {
278 ++stats.conflictingLoads;
279 } else {
280 ++stats.conflictingStores;
281 }
282 }
283
284 // for load-acquire store-release that could also be a barrier
285 insertBarrierSN(inst);
286
287 if (inst->isStore() || inst->isAtomic()) {
288 DPRINTF(MemDepUnit, "Inserting store/atomic PC %s [sn:%lli].\n",
289 inst->pcState(), inst->seqNum);
290
291 depPred.insertStore(inst->pcState().instAddr(), inst->seqNum,
292 inst->threadNumber);
293
294 ++stats.insertedStores;
295 } else if (inst->isLoad()) {
296 ++stats.insertedLoads;
297 } else {
298 panic("Unknown type! (most likely a barrier).");
299 }
300}
301
302void
304{
305 insertBarrier(inst);
306
307 // Might want to turn this part into an inline function or something.
308 // It's shared between both insert functions.
309 if (inst->isStore() || inst->isAtomic()) {
310 DPRINTF(MemDepUnit, "Inserting store/atomic PC %s [sn:%lli].\n",
311 inst->pcState(), inst->seqNum);
312
313 depPred.insertStore(inst->pcState().instAddr(), inst->seqNum,
314 inst->threadNumber);
315
316 ++stats.insertedStores;
317 } else if (inst->isLoad()) {
318 ++stats.insertedLoads;
319 } else {
320 panic("Unknown type! (most likely a barrier).");
321 }
322}
323
324void
326{
327 ThreadID tid = barr_inst->threadNumber;
328
329 MemDepEntryPtr inst_entry = std::make_shared<MemDepEntry>(barr_inst);
330
331 // Add the MemDepEntry to the hash.
332 memDepHash.insert(
333 std::pair<InstSeqNum, MemDepEntryPtr>(barr_inst->seqNum, inst_entry));
334#ifdef GEM5_DEBUG
335 MemDepEntry::memdep_insert++;
336#endif
337
338 // Add the instruction to the instruction list.
339 instList[tid].push_back(barr_inst);
340
341 inst_entry->listIt = --(instList[tid].end());
342
343 insertBarrierSN(barr_inst);
344}
345
346void
348{
349 DPRINTF(MemDepUnit, "Marking registers as ready for "
350 "instruction PC %s [sn:%lli].\n",
351 inst->pcState(), inst->seqNum);
352
353 MemDepEntryPtr inst_entry = findInHash(inst);
354
355 inst_entry->regsReady = true;
356
357 if (inst_entry->memDeps == 0) {
358 DPRINTF(MemDepUnit, "Instruction has its memory "
359 "dependencies resolved, adding it to the ready list.\n");
360
361 moveToReady(inst_entry);
362 } else {
363 DPRINTF(MemDepUnit, "Instruction still waiting on "
364 "memory dependency.\n");
365 }
366}
367
368void
370{
371 DPRINTF(MemDepUnit, "Marking non speculative "
372 "instruction PC %s as ready [sn:%lli].\n",
373 inst->pcState(), inst->seqNum);
374
375 MemDepEntryPtr inst_entry = findInHash(inst);
376
377 moveToReady(inst_entry);
378}
379
380void
382{
383 instsToReplay.push_back(inst);
384}
385
386void
388{
389 DynInstPtr temp_inst;
390
391 // For now this replay function replays all waiting memory ops.
392 while (!instsToReplay.empty()) {
393 temp_inst = instsToReplay.front();
394
395 MemDepEntryPtr inst_entry = findInHash(temp_inst);
396
397 DPRINTF(MemDepUnit, "Replaying mem instruction PC %s [sn:%lli].\n",
398 temp_inst->pcState(), temp_inst->seqNum);
399
400 moveToReady(inst_entry);
401
402 instsToReplay.pop_front();
403 }
404}
405
406void
408{
409 DPRINTF(MemDepUnit, "Completed mem instruction PC %s [sn:%lli].\n",
410 inst->pcState(), inst->seqNum);
411
412 ThreadID tid = inst->threadNumber;
413
414 // Remove the instruction from the hash and the list.
415 MemDepHashIt hash_it = memDepHash.find(inst->seqNum);
416
417 assert(hash_it != memDepHash.end());
418
419 instList[tid].erase((*hash_it).second->listIt);
420
421 (*hash_it).second = NULL;
422
423 memDepHash.erase(hash_it);
424#ifdef GEM5_DEBUG
425 MemDepEntry::memdep_erase++;
426#endif
427}
428
429void
431{
432 wakeDependents(inst);
433 completed(inst);
434 InstSeqNum barr_sn = inst->seqNum;
435
436 if (inst->isWriteBarrier() || inst->isHtmCmd()) {
437 assert(hasStoreBarrier());
438 storeBarrierSNs.erase(barr_sn);
439 }
440 if (inst->isReadBarrier() || inst->isHtmCmd()) {
441 assert(hasLoadBarrier());
442 loadBarrierSNs.erase(barr_sn);
443 }
444 if (debug::MemDepUnit) {
445 const char *barrier_type = nullptr;
446 if (inst->isWriteBarrier() && inst->isReadBarrier())
447 barrier_type = "Memory";
448 else if (inst->isWriteBarrier())
449 barrier_type = "Write";
450 else if (inst->isReadBarrier())
451 barrier_type = "Read";
452
453 if (barrier_type) {
454 DPRINTF(MemDepUnit, "%s barrier completed: %s SN:%lli\n",
455 barrier_type, inst->pcState(), inst->seqNum);
456 }
457 }
458}
459
460void
462{
463 // Only stores, atomics and barriers have dependents.
464 if (!inst->isStore() && !inst->isAtomic() && !inst->isReadBarrier() &&
465 !inst->isWriteBarrier() && !inst->isHtmCmd()) {
466 return;
467 }
468
469 MemDepEntryPtr inst_entry = findInHash(inst);
470
471 for (int i = 0; i < inst_entry->dependInsts.size(); ++i ) {
472 MemDepEntryPtr woken_inst = inst_entry->dependInsts[i];
473
474 if (!woken_inst->inst) {
475 // Potentially removed mem dep entries could be on this list
476 continue;
477 }
478
479 DPRINTF(MemDepUnit, "Waking up a dependent inst, "
480 "[sn:%lli].\n",
481 woken_inst->inst->seqNum);
482
483 assert(woken_inst->memDeps > 0);
484 woken_inst->memDeps -= 1;
485
486 if ((woken_inst->memDeps == 0) &&
487 woken_inst->regsReady &&
488 !woken_inst->squashed) {
489 moveToReady(woken_inst);
490 }
491 }
492
493 inst_entry->dependInsts.clear();
494}
495
497 inst(new_inst)
498{
499#ifdef GEM5_DEBUG
500 ++memdep_count;
501
503 "Memory dependency entry created. memdep_count=%i %s\n",
504 memdep_count, inst->pcState());
505#endif
506}
507
509{
510 for (int i = 0; i < dependInsts.size(); ++i) {
511 dependInsts[i] = NULL;
512 }
513#ifdef GEM5_DEBUG
514 --memdep_count;
515
517 "Memory dependency entry deleted. memdep_count=%i %s\n",
518 memdep_count, inst->pcState());
519#endif
520}
521
522void
523MemDepUnit::squash(const InstSeqNum &squashed_num, ThreadID tid)
524{
525 if (!instsToReplay.empty()) {
526 ListIt replay_it = instsToReplay.begin();
527 while (replay_it != instsToReplay.end()) {
528 if ((*replay_it)->threadNumber == tid &&
529 (*replay_it)->seqNum > squashed_num) {
530 instsToReplay.erase(replay_it++);
531 } else {
532 ++replay_it;
533 }
534 }
535 }
536
537 ListIt squash_it = instList[tid].end();
538 --squash_it;
539
540 MemDepHashIt hash_it;
541
542 while (!instList[tid].empty() &&
543 (*squash_it)->seqNum > squashed_num) {
544
545 DPRINTF(MemDepUnit, "Squashing inst [sn:%lli]\n",
546 (*squash_it)->seqNum);
547
548 loadBarrierSNs.erase((*squash_it)->seqNum);
549
550 storeBarrierSNs.erase((*squash_it)->seqNum);
551
552 hash_it = memDepHash.find((*squash_it)->seqNum);
553
554 assert(hash_it != memDepHash.end());
555
556 (*hash_it).second->squashed = true;
557
558 (*hash_it).second = NULL;
559
560 memDepHash.erase(hash_it);
561#ifdef GEM5_DEBUG
562 MemDepEntry::memdep_erase++;
563#endif
564
565 instList[tid].erase(squash_it--);
566 }
567
568 // Tell the dependency predictor to squash as well.
569 depPred.squash(squashed_num, tid);
570}
571
572void
574 const DynInstPtr &violating_load)
575{
576 DPRINTF(MemDepUnit, "Passing violating PCs to store sets,"
577 " load: %#x, store: %#x\n", violating_load->pcState().instAddr(),
578 store_inst->pcState().instAddr());
579 // Tell the memory dependence unit of the violation.
580 depPred.violation(store_inst->pcState().instAddr(),
581 violating_load->pcState().instAddr());
582}
583
584void
586{
587 DPRINTF(MemDepUnit, "Issuing instruction PC %#x [sn:%lli].\n",
588 inst->pcState().instAddr(), inst->seqNum);
589
590 depPred.issued(inst->pcState().instAddr(), inst->seqNum, inst->isStore());
591}
592
595{
596 MemDepHashIt hash_it = memDepHash.find(inst->seqNum);
597
598 assert(hash_it != memDepHash.end());
599
600 return (*hash_it).second;
601}
602
603void
605{
606 DPRINTF(MemDepUnit, "Adding instruction [sn:%lli] "
607 "to the ready list.\n", woken_inst_entry->inst->seqNum);
608
609 assert(!woken_inst_entry->squashed);
610
611 iqPtr->addReadyMemInst(woken_inst_entry->inst);
612}
613
614
615void
617{
618 for (ThreadID tid = 0; tid < MaxThreads; tid++) {
619 cprintf("Instruction list %i size: %i\n",
620 tid, instList[tid].size());
621
622 ListIt inst_list_it = instList[tid].begin();
623 int num = 0;
624
625 while (inst_list_it != instList[tid].end()) {
626 cprintf("Instruction:%i\nPC: %s\n[sn:%llu]\n[tid:%i]\nIssued:%i\n"
627 "Squashed:%i\n\n",
628 num, (*inst_list_it)->pcState(),
629 (*inst_list_it)->seqNum,
630 (*inst_list_it)->threadNumber,
631 (*inst_list_it)->isIssued(),
632 (*inst_list_it)->isSquashed());
633 inst_list_it++;
634 ++num;
635 }
636 }
637
638 cprintf("Memory dependence hash size: %i\n", memDepHash.size());
639
640#ifdef GEM5_DEBUG
641 cprintf("Memory dependence entries: %i\n", MemDepEntry::memdep_count);
642#endif
643}
644
645} // namespace o3
646} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
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
std::vector< MemDepEntryPtr > dependInsts
A vector of any dependent instructions.
~MemDepEntry()
Frees any pointers.
MemDepEntry(const DynInstPtr &new_inst)
Constructs a memory dependence entry.
DynInstPtr inst
The instruction being tracked.
bool isDrained() const
Determine if we are drained.
void completeInst(const DynInstPtr &inst)
Notifies completion of an instruction.
std::string name() const
Returns the name of the memory dependence unit.
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.
void completed(const DynInstPtr &inst)
Completes a memory instruction.
~MemDepUnit()
Frees up any memory allocated.
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.
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.
Statistics container.
Definition group.hh:93
STL pair class.
Definition stl.hh:58
STL vector class.
Definition stl.hh:37
#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:220
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
RefCountingPtr< DynInst > DynInstPtr
RefCountingPtr< const DynInst > DynInstConstPtr
Units for Stats.
Definition units.hh:113
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
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.

Generated on Mon May 26 2025 09:19:08 for gem5 by doxygen 1.13.2