gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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  * Authors: Kevin Lim
29  */
30 
31 #include "cpu/o3/store_set.hh"
32 
33 #include "base/intmath.hh"
34 #include "base/misc.hh"
35 #include "base/trace.hh"
36 #include "debug/StoreSet.hh"
37 
38 StoreSet::StoreSet(uint64_t clear_period, int _SSIT_size, int _LFST_size)
39  : clearPeriod(clear_period), SSITSize(_SSIT_size), LFSTSize(_LFST_size)
40 {
41  DPRINTF(StoreSet, "StoreSet: Creating store set object.\n");
42  DPRINTF(StoreSet, "StoreSet: SSIT size: %i, LFST size: %i.\n",
44 
45  if (!isPowerOf2(SSITSize)) {
46  fatal("Invalid SSIT size!\n");
47  }
48 
49  SSIT.resize(SSITSize);
50 
51  validSSIT.resize(SSITSize);
52 
53  for (int i = 0; i < SSITSize; ++i)
54  validSSIT[i] = false;
55 
56  if (!isPowerOf2(LFSTSize)) {
57  fatal("Invalid LFST size!\n");
58  }
59 
60  LFST.resize(LFSTSize);
61 
62  validLFST.resize(LFSTSize);
63 
64  for (int i = 0; i < LFSTSize; ++i) {
65  validLFST[i] = false;
66  LFST[i] = 0;
67  }
68 
69  indexMask = SSITSize - 1;
70 
71  offsetBits = 2;
72 
73  memOpsPred = 0;
74 }
75 
77 {
78 }
79 
80 void
81 StoreSet::init(uint64_t clear_period, int _SSIT_size, int _LFST_size)
82 {
83  SSITSize = _SSIT_size;
84  LFSTSize = _LFST_size;
85  clearPeriod = clear_period;
86 
87  DPRINTF(StoreSet, "StoreSet: Creating store set object.\n");
88  DPRINTF(StoreSet, "StoreSet: SSIT size: %i, LFST size: %i.\n",
90 
91  SSIT.resize(SSITSize);
92 
93  validSSIT.resize(SSITSize);
94 
95  for (int i = 0; i < SSITSize; ++i)
96  validSSIT[i] = false;
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  indexMask = SSITSize - 1;
108 
109  offsetBits = 2;
110 
111  memOpsPred = 0;
112 }
113 
114 
115 void
116 StoreSet::violation(Addr store_PC, Addr load_PC)
117 {
118  int load_index = calcIndex(load_PC);
119  int store_index = calcIndex(store_PC);
120 
121  assert(load_index < SSITSize && store_index < SSITSize);
122 
123  bool valid_load_SSID = validSSIT[load_index];
124  bool valid_store_SSID = validSSIT[store_index];
125 
126  if (!valid_load_SSID && !valid_store_SSID) {
127  // Calculate a new SSID here.
128  SSID new_set = calcSSID(load_PC);
129 
130  validSSIT[load_index] = true;
131 
132  SSIT[load_index] = new_set;
133 
134  validSSIT[store_index] = true;
135 
136  SSIT[store_index] = new_set;
137 
138  assert(new_set < LFSTSize);
139 
140  DPRINTF(StoreSet, "StoreSet: Neither load nor store had a valid "
141  "storeset, creating a new one: %i for load %#x, store %#x\n",
142  new_set, load_PC, store_PC);
143  } else if (valid_load_SSID && !valid_store_SSID) {
144  SSID load_SSID = SSIT[load_index];
145 
146  validSSIT[store_index] = true;
147 
148  SSIT[store_index] = load_SSID;
149 
150  assert(load_SSID < LFSTSize);
151 
152  DPRINTF(StoreSet, "StoreSet: Load had a valid store set. Adding "
153  "store to that set: %i for load %#x, store %#x\n",
154  load_SSID, load_PC, store_PC);
155  } else if (!valid_load_SSID && valid_store_SSID) {
156  SSID store_SSID = SSIT[store_index];
157 
158  validSSIT[load_index] = true;
159 
160  SSIT[load_index] = store_SSID;
161 
162  DPRINTF(StoreSet, "StoreSet: Store had a valid store set: %i for "
163  "load %#x, store %#x\n",
164  store_SSID, load_PC, store_PC);
165  } else {
166  SSID load_SSID = SSIT[load_index];
167  SSID store_SSID = SSIT[store_index];
168 
169  assert(load_SSID < LFSTSize && store_SSID < LFSTSize);
170 
171  // The store set with the lower number wins
172  if (store_SSID > load_SSID) {
173  SSIT[store_index] = load_SSID;
174 
175  DPRINTF(StoreSet, "StoreSet: Load had smaller store set: %i; "
176  "for load %#x, store %#x\n",
177  load_SSID, load_PC, store_PC);
178  } else {
179  SSIT[load_index] = store_SSID;
180 
181  DPRINTF(StoreSet, "StoreSet: Store had smaller store set: %i; "
182  "for load %#x, store %#x\n",
183  store_SSID, load_PC, store_PC);
184  }
185  }
186 }
187 
188 void
190 {
191  memOpsPred++;
192  if (memOpsPred > clearPeriod) {
193  DPRINTF(StoreSet, "Wiping predictor state beacuse %d ld/st executed\n",
194  clearPeriod);
195  memOpsPred = 0;
196  clear();
197  }
198 }
199 
200 void
201 StoreSet::insertLoad(Addr load_PC, InstSeqNum load_seq_num)
202 {
203  checkClear();
204  // Does nothing.
205  return;
206 }
207 
208 void
209 StoreSet::insertStore(Addr store_PC, InstSeqNum store_seq_num, ThreadID tid)
210 {
211  int index = calcIndex(store_PC);
212 
213  int store_SSID;
214 
215  checkClear();
216  assert(index < SSITSize);
217 
218  if (!validSSIT[index]) {
219  // Do nothing if there's no valid entry.
220  return;
221  } else {
222  store_SSID = SSIT[index];
223 
224  assert(store_SSID < LFSTSize);
225 
226  // Update the last store that was fetched with the current one.
227  LFST[store_SSID] = store_seq_num;
228 
229  validLFST[store_SSID] = 1;
230 
231  storeList[store_seq_num] = store_SSID;
232 
233  DPRINTF(StoreSet, "Store %#x updated the LFST, SSID: %i\n",
234  store_PC, store_SSID);
235  }
236 }
237 
240 {
241  int index = calcIndex(PC);
242 
243  int inst_SSID;
244 
245  assert(index < SSITSize);
246 
247  if (!validSSIT[index]) {
248  DPRINTF(StoreSet, "Inst %#x with index %i had no SSID\n",
249  PC, index);
250 
251  // Return 0 if there's no valid entry.
252  return 0;
253  } else {
254  inst_SSID = SSIT[index];
255 
256  assert(inst_SSID < LFSTSize);
257 
258  if (!validLFST[inst_SSID]) {
259 
260  DPRINTF(StoreSet, "Inst %#x with index %i and SSID %i had no "
261  "dependency\n", PC, index, inst_SSID);
262 
263  return 0;
264  } else {
265  DPRINTF(StoreSet, "Inst %#x with index %i and SSID %i had LFST "
266  "inum of %i\n", PC, index, inst_SSID, LFST[inst_SSID]);
267 
268  return LFST[inst_SSID];
269  }
270  }
271 }
272 
273 void
274 StoreSet::issued(Addr issued_PC, InstSeqNum issued_seq_num, bool is_store)
275 {
276  // This only is updated upon a store being issued.
277  if (!is_store) {
278  return;
279  }
280 
281  int index = calcIndex(issued_PC);
282 
283  int store_SSID;
284 
285  assert(index < SSITSize);
286 
287  SeqNumMapIt store_list_it = storeList.find(issued_seq_num);
288 
289  if (store_list_it != storeList.end()) {
290  storeList.erase(store_list_it);
291  }
292 
293  // Make sure the SSIT still has a valid entry for the issued store.
294  if (!validSSIT[index]) {
295  return;
296  }
297 
298  store_SSID = SSIT[index];
299 
300  assert(store_SSID < LFSTSize);
301 
302  // If the last fetched store in the store set refers to the store that
303  // was just issued, then invalidate the entry.
304  if (validLFST[store_SSID] && LFST[store_SSID] == issued_seq_num) {
305  DPRINTF(StoreSet, "StoreSet: store invalidated itself in LFST.\n");
306  validLFST[store_SSID] = false;
307  }
308 }
309 
310 void
312 {
313  DPRINTF(StoreSet, "StoreSet: Squashing until inum %i\n",
314  squashed_num);
315 
316  int idx;
317  SeqNumMapIt store_list_it = storeList.begin();
318 
319  //@todo:Fix to only delete from correct thread
320  while (!storeList.empty()) {
321  idx = (*store_list_it).second;
322 
323  if ((*store_list_it).first <= squashed_num) {
324  break;
325  }
326 
327  bool younger = LFST[idx] > squashed_num;
328 
329  if (validLFST[idx] && younger) {
330  DPRINTF(StoreSet, "Squashed [sn:%lli]\n", LFST[idx]);
331  validLFST[idx] = false;
332 
333  storeList.erase(store_list_it++);
334  } else if (!validLFST[idx] && younger) {
335  storeList.erase(store_list_it++);
336  }
337  }
338 }
339 
340 void
342 {
343  for (int i = 0; i < SSITSize; ++i) {
344  validSSIT[i] = false;
345  }
346 
347  for (int i = 0; i < LFSTSize; ++i) {
348  validLFST[i] = false;
349  }
350 
351  storeList.clear();
352 }
353 
354 void
356 {
357  cprintf("storeList.size(): %i\n", storeList.size());
358  SeqNumMapIt store_list_it = storeList.begin();
359 
360  int num = 0;
361 
362  while (store_list_it != storeList.end()) {
363  cprintf("%i: [sn:%lli] SSID:%i\n",
364  num, (*store_list_it).first, (*store_list_it).second);
365  num++;
366  store_list_it++;
367  }
368 }
#define DPRINTF(x,...)
Definition: trace.hh:212
Implements a store set predictor for determining if memory instructions are dependent upon each other...
Definition: store_set.hh:56
Bitfield< 30, 0 > index
SSID calcSSID(Addr PC)
Calculates a Store Set ID based on the PC.
Definition: store_set.hh:117
void insertLoad(Addr load_PC, InstSeqNum load_seq_num)
Inserts a load into the store set predictor.
Definition: store_set.cc:201
Bitfield< 7 > i
Definition: miscregs.hh:1378
~StoreSet()
Default destructor.
Definition: store_set.cc:76
std::vector< bool > validSSIT
Bit vector to tell if the SSIT has a valid entry.
Definition: store_set.hh:124
int calcIndex(Addr PC)
Calculates the index into the SSIT based on the PC.
Definition: store_set.hh:113
std::map< InstSeqNum, int, ltseqnum >::iterator SeqNumMapIt
Definition: store_set.hh:137
int indexMask
Mask to obtain the index.
Definition: store_set.hh:151
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:81
std::vector< InstSeqNum > LFST
Last Fetched Store Table.
Definition: store_set.hh:127
InstSeqNum checkInst(Addr PC)
Checks if the instruction with the given PC is dependent upon any store.
Definition: store_set.cc:239
StoreSet()
Default constructor.
Definition: store_set.hh:63
void squash(InstSeqNum squashed_num, ThreadID tid)
Squashes for a specific thread until the given sequence number.
Definition: store_set.cc:311
uint64_t clearPeriod
Number of loads/stores to process before wiping predictor so all entries don't get saturated...
Definition: store_set.hh:142
void clear()
Resets all tables.
Definition: store_set.cc:341
#define fatal(...)
Definition: misc.hh:163
bool isPowerOf2(const T &n)
Definition: intmath.hh:73
uint64_t InstSeqNum
Definition: inst_seq.hh:40
int LFSTSize
Last Fetched Store Table size, in entries.
Definition: store_set.hh:148
unsigned SSID
Definition: store_set.hh:59
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:135
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
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:116
int memOpsPred
Number of memory operations predicted since last clear of predictor.
Definition: store_set.hh:157
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:189
int SSITSize
Store Set ID Table size, in entries.
Definition: store_set.hh:145
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:171
void issued(Addr issued_PC, InstSeqNum issued_seq_num, bool is_store)
Records this PC/sequence number as issued.
Definition: store_set.cc:274
std::vector< SSID > SSIT
The Store Set ID Table.
Definition: store_set.hh:121
std::vector< bool > validLFST
Bit vector to tell if the LFST has a valid entry.
Definition: store_set.hh:130
int offsetBits
Definition: store_set.hh:154
void insertStore(Addr store_PC, InstSeqNum store_seq_num, ThreadID tid)
Inserts a store into the store set predictor.
Definition: store_set.cc:209
void dump()
Debug function to dump the contents of the store list.
Definition: store_set.cc:355
void cprintf(const char *format, const Args &...args)
Definition: cprintf.hh:155

Generated on Fri Jun 9 2017 13:03:44 for gem5 by doxygen 1.8.6