gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
store_set.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2004-2006 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 "base/intmath.hh"
30#include "base/logging.hh"
31#include "base/trace.hh"
32#include "cpu/o3/store_set.hh"
33#include "debug/StoreSet.hh"
36
37namespace gem5
38{
39
40namespace o3
41{
42
43StoreSet::StoreSet(std::string_view name_, uint64_t clear_period,
44 size_t _SSIT_entries, int _SSIT_assoc,
45 replacement_policy::Base *_replPolicy,
46 BaseIndexingPolicy *_indexingPolicy, int _LFST_size)
47 : Named(name_),
48 SSIT("SSIT", _SSIT_entries, _SSIT_assoc,
49 _replPolicy, _indexingPolicy,
50 SSITEntry(genTagExtractor(_indexingPolicy))),
51 clearPeriod(clear_period), SSITSize(_SSIT_entries),
52 LFSTSize(_LFST_size)
53{
54 DPRINTF(StoreSet, "StoreSet: Creating store set object.\n");
55 DPRINTF(StoreSet, "StoreSet: SSIT size: %i, LFST size: %i.\n",
57
58 if (!isPowerOf2(SSITSize)) {
59 fatal("Invalid SSIT size!\n");
60 }
61
62 if (!isPowerOf2(LFSTSize)) {
63 fatal("Invalid LFST size!\n");
64 }
65
66 LFST.resize(LFSTSize);
67
68 validLFST.resize(LFSTSize);
69
70 for (int i = 0; i < LFSTSize; ++i) {
71 validLFST[i] = false;
72 LFST[i] = 0;
73 }
74
75 memOpsPred = 0;
76}
77
81
82void
83StoreSet::init(uint64_t clear_period, size_t _SSIT_entries,
84 int _SSIT_assoc, replacement_policy::Base *_replPolicy,
85 BaseIndexingPolicy *_indexingPolicy, int _LFST_size)
86{
87 SSITSize = _SSIT_entries;
88 LFSTSize = _LFST_size;
89 clearPeriod = clear_period;
90
91 DPRINTF(StoreSet, "StoreSet: Creating store set object.\n");
92 DPRINTF(StoreSet, "StoreSet: SSIT size: %i, LFST size: %i.\n",
94
95 SSIT.init(SSITSize, _SSIT_assoc, _replPolicy, _indexingPolicy,
96 SSITEntry(genTagExtractor(_indexingPolicy)));
97
98 LFST.resize(LFSTSize);
99
100 validLFST.resize(LFSTSize);
101
102 for (int i = 0; i < LFSTSize; ++i) {
103 validLFST[i] = false;
104 LFST[i] = 0;
105 }
106
107 memOpsPred = 0;
108}
109
110
111void
112StoreSet::violation(Addr store_PC, Addr load_PC)
113{
114 auto ld_entry = SSIT.findEntry({load_PC});
115 auto st_entry = SSIT.findEntry({store_PC});
116
117 bool valid_load_SSID = ld_entry && ld_entry->isValid();
118 bool valid_store_SSID = st_entry && st_entry->isValid();
119
120 if (!valid_load_SSID && !valid_store_SSID) {
121 // Calculate a new SSID here.
122 SSID new_set = calcSSID(load_PC);
123
124 assert(new_set < LFSTSize);
125
126 SSITEntry *ld_entry = SSIT.findVictim({load_PC});
127 ld_entry->setSSID(new_set);
128 SSIT.insertEntry({load_PC}, ld_entry);
129
130 SSITEntry *st_entry = SSIT.findVictim({store_PC});
131 st_entry->setSSID(new_set);
132 SSIT.insertEntry({store_PC}, st_entry);
133
134 DPRINTF(StoreSet, "StoreSet: Neither load nor store had a valid "
135 "storeset, creating a new one: %i for load %#x, store %#x\n",
136 new_set, load_PC, store_PC);
137 } else if (valid_load_SSID && !valid_store_SSID) {
138 SSID load_SSID = ld_entry->getSSID();
139 SSITEntry *st_entry = SSIT.findVictim({store_PC});
140 st_entry->setSSID(load_SSID);
141 SSIT.insertEntry({store_PC}, st_entry);
142
143 assert(load_SSID < LFSTSize);
144
145 DPRINTF(StoreSet, "StoreSet: Load had a valid store set. Adding "
146 "store to that set: %i for load %#x, store %#x\n",
147 load_SSID, load_PC, store_PC);
148 } else if (!valid_load_SSID && valid_store_SSID) {
149 SSID store_SSID = st_entry->getSSID();
150 SSITEntry *ld_entry = SSIT.findVictim({load_PC});
151 ld_entry->setSSID(store_SSID);
152 SSIT.insertEntry({load_PC}, ld_entry);
153
154 DPRINTF(StoreSet, "StoreSet: Store had a valid store set: %i for "
155 "load %#x, store %#x\n",
156 store_SSID, load_PC, store_PC);
157 } else {
158 SSID load_SSID = ld_entry->getSSID();
159 SSID store_SSID = st_entry->getSSID();
160
161 assert(load_SSID < LFSTSize && store_SSID < LFSTSize);
162
163 // The store set with the lower number wins
164 if (store_SSID > load_SSID) {
165 st_entry->setSSID(load_SSID);
166
167 DPRINTF(StoreSet, "StoreSet: Load had smaller store set: %i; "
168 "for load %#x, store %#x\n",
169 load_SSID, load_PC, store_PC);
170 } else {
171 ld_entry->setSSID(store_SSID);
172
173 DPRINTF(StoreSet, "StoreSet: Store had smaller store set: %i; "
174 "for load %#x, store %#x\n",
175 store_SSID, load_PC, store_PC);
176 }
177 }
178}
179
180void
182{
183 memOpsPred++;
184 if (memOpsPred > clearPeriod) {
185 DPRINTF(StoreSet, "Wiping predictor state beacuse %d ld/st executed\n",
187 memOpsPred = 0;
188 clear();
189 }
190}
191
192void
194{
195 checkClear();
196 // Does nothing.
197 return;
198}
199
200void
201StoreSet::insertStore(Addr store_PC, InstSeqNum store_seq_num, ThreadID tid)
202{
203 auto st_entry = SSIT.findEntry({store_PC});
204
205 bool valid_entry = st_entry && st_entry->isValid();
206
207 int store_SSID;
208
209 checkClear();
210
211 if (!valid_entry) {
212 // Do nothing if there's no valid entry.
213 return;
214 } else {
215 store_SSID = st_entry->getSSID();
216
217 assert(store_SSID < LFSTSize);
218
219 // Update the last store that was fetched with the current one.
220 LFST[store_SSID] = store_seq_num;
221
222 validLFST[store_SSID] = 1;
223
224 storeList[store_seq_num] = store_SSID;
225
226 DPRINTF(StoreSet, "Store %#x updated the LFST, SSID: %i\n",
227 store_PC, store_SSID);
228 }
229}
230
233{
234 auto entry = SSIT.findEntry({PC});
235 bool valid_ssit = entry && entry->isValid();
236
237 int inst_SSID;
238
239 if (!valid_ssit) {
240 DPRINTF(StoreSet, "Inst %#x has no SSID\n", PC);
241
242 // Return 0 if there's no valid entry.
243 return 0;
244 } else {
245 inst_SSID = entry->getSSID();
246
247 assert(inst_SSID < LFSTSize);
248
249 if (!validLFST[inst_SSID]) {
250
251 DPRINTF(StoreSet, "Inst %#x with SSID %i had no "
252 "dependency\n", PC, inst_SSID);
253
254 return 0;
255 } else {
256 DPRINTF(StoreSet, "Inst %#x with SSID %i had LFST "
257 "inum of %i\n", PC, inst_SSID, LFST[inst_SSID]);
258
259 return LFST[inst_SSID];
260 }
261 }
262}
263
264void
265StoreSet::issued(Addr issued_PC, InstSeqNum issued_seq_num, bool is_store)
266{
267 // This only is updated upon a store being issued.
268 if (!is_store) {
269 return;
270 }
271
272 auto entry = SSIT.findEntry({issued_PC});
273 bool valid_ssit = entry && entry->isValid();
274
275 int store_SSID;
276
277 SeqNumMapIt store_list_it = storeList.find(issued_seq_num);
278
279 if (store_list_it != storeList.end()) {
280 storeList.erase(store_list_it);
281 }
282
283 // Make sure the SSIT still has a valid entry for the issued store.
284 if (!valid_ssit) {
285 return;
286 }
287
288 store_SSID = entry->getSSID();
289
290 assert(store_SSID < LFSTSize);
291
292 // If the last fetched store in the store set refers to the store that
293 // was just issued, then invalidate the entry.
294 if (validLFST[store_SSID] && LFST[store_SSID] == issued_seq_num) {
295 DPRINTF(StoreSet, "StoreSet: store invalidated itself in LFST.\n");
296 validLFST[store_SSID] = false;
297 }
298}
299
300void
302{
303 DPRINTF(StoreSet, "StoreSet: Squashing until inum %i\n",
304 squashed_num);
305
306 int idx;
307 SeqNumMapIt store_list_it = storeList.begin();
308
309 //@todo:Fix to only delete from correct thread
310 while (!storeList.empty()) {
311 idx = (*store_list_it).second;
312
313 if ((*store_list_it).first <= squashed_num) {
314 break;
315 }
316
317 bool younger = LFST[idx] > squashed_num;
318
319 if (validLFST[idx] && younger) {
320 DPRINTF(StoreSet, "Squashed [sn:%lli]\n", LFST[idx]);
321 validLFST[idx] = false;
322
323 storeList.erase(store_list_it++);
324 } else if (!validLFST[idx] && younger) {
325 storeList.erase(store_list_it++);
326 }
327 }
328}
329
330void
332{
333 SSIT.clear();
334
335 for (int i = 0; i < LFSTSize; ++i) {
336 validLFST[i] = false;
337 }
338
339 storeList.clear();
340}
341
342void
344{
345 cprintf("storeList.size(): %i\n", storeList.size());
346 SeqNumMapIt store_list_it = storeList.begin();
347
348 int num = 0;
349
350 while (store_list_it != storeList.end()) {
351 cprintf("%i: [sn:%lli] SSID:%i\n",
352 num, (*store_list_it).first, (*store_list_it).second);
353 num++;
354 store_list_it++;
355 }
356}
357
358} // namespace o3
359} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
Named(std::string_view name_)
Definition named.hh:57
void insertLoad(Addr load_PC, InstSeqNum load_seq_num)
Inserts a load into the store set predictor.
Definition store_set.cc:193
void checkClear()
Clears the store set predictor every so often so that all the entries aren't used and stores are cons...
Definition store_set.cc:181
std::vector< InstSeqNum > LFST
Last Fetched Store Table.
Definition store_set.hh:155
void squash(InstSeqNum squashed_num, ThreadID tid)
Squashes for a specific thread until the given sequence number.
Definition store_set.cc:301
uint64_t clearPeriod
Number of loads/stores to process before wiping predictor so all entries don't get saturated.
Definition store_set.hh:170
void dump()
Debug function to dump the contents of the store list.
Definition store_set.cc:343
void clear()
Resets all tables.
Definition store_set.cc:331
void insertStore(Addr store_PC, InstSeqNum store_seq_num, ThreadID tid)
Inserts a store into the store set predictor.
Definition store_set.cc:201
~StoreSet()
Default destructor.
Definition store_set.cc:78
SSID calcSSID(Addr PC)
Calculates a Store Set ID based on the PC.
Definition store_set.hh:148
std::vector< bool > validLFST
Bit vector to tell if the LFST has a valid entry.
Definition store_set.hh:158
int LFSTSize
Last Fetched Store Table size, in entries.
Definition store_set.hh:176
void issued(Addr issued_PC, InstSeqNum issued_seq_num, bool is_store)
Records this PC/sequence number as issued.
Definition store_set.cc:265
InstSeqNum checkInst(Addr PC)
Checks if the instruction with the given PC is dependent upon any store.
Definition store_set.cc:232
AssociativeCache< SSITEntry > SSIT
The Store Set ID Table.
Definition store_set.hh:152
std::map< InstSeqNum, int, ltseqnum >::iterator SeqNumMapIt
Definition store_set.hh:165
int SSITSize
Store Set ID Table size, in entries.
Definition store_set.hh:173
StoreSet()
Default constructor.
Definition store_set.hh:92
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:112
std::map< InstSeqNum, int, ltseqnum > storeList
Map of stores that have been inserted into the store set, but not yet issued or squashed.
Definition store_set.hh:163
void init(uint64_t clear_period, size_t SSIT_entries, int SSIT_assoc, replacement_policy::Base *_replPolicy, BaseIndexingPolicy *_indexingPolicy, int LFST_size)
Initializes the store set predictor with the given table sizes.
Definition store_set.cc:83
int memOpsPred
Number of memory operations predicted since last clear of predictor.
Definition store_set.hh:179
A common base class of cache replacement policy objects.
Definition base.hh:55
static constexpr bool isPowerOf2(const T &n)
Definition intmath.hh:98
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:232
Declaration of a common framework for indexing policies.
Bitfield< 7 > i
Definition misc_types.hh:67
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
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
IndexingPolicyTemplate< AddrTypes > BaseIndexingPolicy
Definition base.hh:215
static constexpr auto genTagExtractor(BTBIndexingPolicy *ip)
This helper generates a tag extractor function object which will be typically used by Replaceable ent...
Definition btb_entry.hh:281
uint64_t InstSeqNum
Definition inst_seq.hh:40

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