LLVM: include/llvm/MCA/HardwareUnits/LSUnit.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#ifndef LLVM_MCA_HARDWAREUNITS_LSUNIT_H
16#define LLVM_MCA_HARDWAREUNITS_LSUNIT_H
17
24
25namespace llvm {
26namespace mca {
27
28
30
31
32
33
34
35
36 unsigned LQSize;
37
38
39
40
41
42
43
44 unsigned SQSize;
45
46 unsigned UsedLQEntries;
47 unsigned UsedSQEntries;
48
49
50
51
52
53
54 const bool NoAlias;
55
56public:
58 unsigned StoreQueueSize, bool AssumeNoAlias);
59
61
62
64
65
67
74
76
82
83
84
85
86
87
89
90
91
92
93
94
95
97
98 bool isSQEmpty() const { return !UsedSQEntries; }
99 bool isLQEmpty() const { return !UsedLQEntries; }
100 bool isSQFull() const { return SQSize && SQSize == UsedSQEntries; }
101 bool isLQFull() const { return LQSize && LQSize == UsedLQEntries; }
102
103
105
106
107
109
110
111
113
115
117
119
120
121
122
123
125
127
129
130#ifndef NDEBUG
131 virtual void dump() const = 0;
132#endif
133};
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237protected:
238
239
240
241
242
243
244
245
246 class MemoryGroup {
247 unsigned NumPredecessors = 0;
248 unsigned NumExecutingPredecessors = 0;
249 unsigned NumExecutedPredecessors = 0;
250
251 unsigned NumInstructions = 0;
252 unsigned NumExecuting = 0;
253 unsigned NumExecuted = 0;
254
256
258
260 InstRef CriticalMemoryInstruction;
261
262 MemoryGroup(const MemoryGroup &) = delete;
263 MemoryGroup &operator=(const MemoryGroup &) = delete;
264
265 public:
268
270 return OrderSucc.size() + DataSucc.size();
271 }
274 return NumExecutingPredecessors;
275 }
277 return NumExecutedPredecessors;
278 }
282
284 return CriticalMemoryInstruction;
285 }
287 return CriticalPredecessor;
288 }
289
290 void addSuccessor(MemoryGroup *Group, bool IsDataDependent) {
291
292
293
295 return;
296
297 Group->NumPredecessors++;
300 Group->onGroupIssued(CriticalMemoryInstruction, IsDataDependent);
301
302 if (IsDataDependent)
303 DataSucc.emplace_back(Group);
304 else
305 OrderSucc.emplace_back(Group);
306 }
307
309 return NumPredecessors >
310 (NumExecutingPredecessors + NumExecutedPredecessors);
311 }
313 return NumExecutingPredecessors &&
314 ((NumExecutedPredecessors + NumExecutingPredecessors) ==
315 NumPredecessors);
316 }
317 bool isReady() const { return NumExecutedPredecessors == NumPredecessors; }
319 return NumExecuting && (NumExecuting == (NumInstructions - NumExecuted));
320 }
321 bool isExecuted() const { return NumInstructions == NumExecuted; }
322
324 assert(() && "Unexpected group-start event!");
325 NumExecutingPredecessors++;
326
327 if (!ShouldUpdateCriticalDep)
328 return;
329
330 unsigned Cycles = IR.getInstruction()->getCyclesLeft();
331 if (CriticalPredecessor.Cycles < Cycles) {
332 CriticalPredecessor.IID = IR.getSourceIndex();
333 CriticalPredecessor.Cycles = Cycles;
334 }
335 }
336
338 assert(() && "Inconsistent state found!");
339 NumExecutingPredecessors--;
340 NumExecutedPredecessors++;
341 }
342
345 ++NumExecuting;
346
347
349 if ((bool)CriticalMemoryInstruction) {
351 *CriticalMemoryInstruction.getInstruction();
353 CriticalMemoryInstruction = IR;
354 } else {
355 CriticalMemoryInstruction = IR;
356 }
357
359 return;
360
361
362 for (MemoryGroup *MG : OrderSucc) {
363 MG->onGroupIssued(CriticalMemoryInstruction, false);
364
365 MG->onGroupExecuted();
366 }
367
368 for (MemoryGroup *MG : DataSucc)
369 MG->onGroupIssued(CriticalMemoryInstruction, true);
370 }
371
374 --NumExecuting;
375 ++NumExecuted;
376
377 if (CriticalMemoryInstruction &&
378 CriticalMemoryInstruction.getSourceIndex() == IR.getSourceIndex()) {
379 CriticalMemoryInstruction.invalidate();
380 }
381
383 return;
384
385
386
387 for (MemoryGroup *MG : DataSucc)
388 MG->onGroupExecuted();
389 }
390
393 ++NumInstructions;
394 }
395
397 if (isWaiting() && CriticalPredecessor.Cycles)
398 CriticalPredecessor.Cycles--;
399 }
400 };
401
404
409
410public:
419
420
421
423
425 unsigned GroupID = IR.getInstruction()->getLSUTokenID();
426 const MemoryGroup &Group = getGroup(GroupID);
428 }
429
431 unsigned GroupID = IR.getInstruction()->getLSUTokenID();
432 const MemoryGroup &Group = getGroup(GroupID);
434 }
435
437 unsigned GroupID = IR.getInstruction()->getLSUTokenID();
438 const MemoryGroup &Group = getGroup(GroupID);
440 }
441
443 unsigned GroupID = IR.getInstruction()->getLSUTokenID();
444 const MemoryGroup &Group = getGroup(GroupID);
446 }
447
449 const MemoryGroup &Group = getGroup(GroupId);
451 }
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466 unsigned dispatch(const InstRef &IR) override;
467
469 unsigned GroupID = IR.getInstruction()->getLSUTokenID();
470 Groups[GroupID]->onInstructionIssued(IR);
471 }
472
473 void onInstructionRetired(const InstRef &IR) override;
474
475 void onInstructionExecuted(const InstRef &IR) override;
476
477 void cycleEvent() override;
478
479#ifndef NDEBUG
480 void dump() const override;
481#endif
482
483private:
484 bool isValidGroupID(unsigned Index) const {
485 return Index && Groups.contains(Index);
486 }
487
488 const MemoryGroup &getGroup(unsigned Index) const {
489 assert(isValidGroupID(Index) && "Group doesn't exist!");
490 return *Groups.find(Index)->second;
491 }
492
493 MemoryGroup &getGroup(unsigned Index) {
494 assert(isValidGroupID(Index) && "Group doesn't exist!");
495 return *Groups.find(Index)->second;
496 }
497
498 unsigned createMemoryGroup() {
499 Groups.insert(std::make_pair(NextGroupID, std::make_unique()));
500 return NextGroupID++;
501 }
502};
503
504}
505}
506
507#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the DenseMap class.
This file defines a base class for describing a simulated hardware unit.
Legalize the Machine IR a function s Machine IR
This file defines abstractions used by the Pipeline to model register reads, register writes and inst...
This file defines the SmallVector class.
static const X86InstrFMA3Group Groups[]
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An InstRef contains both a SourceMgr index and Instruction pair.
An instruction propagated through the simulated instruction pipeline.
int getCyclesLeft() const
virtual void dump() const =0
virtual unsigned dispatch(const InstRef &IR)=0
Allocates LS resources for instruction IR.
bool isLQFull() const
Definition LSUnit.h:101
unsigned getUsedSQEntries() const
Definition LSUnit.h:69
void acquireSQSlot()
Definition LSUnit.h:71
virtual bool isReady(const InstRef &IR) const =0
Check if a peviously dispatched instruction IR is now ready for execution.
void releaseLQSlot()
Definition LSUnit.h:72
virtual Status isAvailable(const InstRef &IR) const =0
This method checks the availability of the load/store buffers.
virtual void onInstructionRetired(const InstRef &IR)=0
virtual void onInstructionExecuted(const InstRef &IR)=0
virtual void cycleEvent()=0
unsigned getUsedLQEntries() const
Definition LSUnit.h:68
bool isSQEmpty() const
Definition LSUnit.h:98
bool assumeNoAlias() const
Definition LSUnit.h:75
unsigned getLoadQueueSize() const
Returns the total number of entries in the load queue.
Definition LSUnit.h:63
Status
Definition LSUnit.h:77
@ LSU_LQUEUE_FULL
Definition LSUnit.h:79
@ LSU_AVAILABLE
Definition LSUnit.h:78
@ LSU_SQUEUE_FULL
Definition LSUnit.h:80
virtual bool isWaiting(const InstRef &IR) const =0
Check if instruction IR is still waiting on memory operations, and the wait time is still unknown.
bool isSQFull() const
Definition LSUnit.h:100
virtual const CriticalDependency getCriticalPredecessor(unsigned GroupId)=0
virtual bool isPending(const InstRef &IR) const =0
Check if instruction IR only depends on memory instructions that are currently executing.
virtual bool hasDependentUsers(const InstRef &IR) const =0
bool isLQEmpty() const
Definition LSUnit.h:99
LSUnitBase(const MCSchedModel &SM, unsigned LoadQueueSize, unsigned StoreQueueSize, bool AssumeNoAlias)
unsigned getStoreQueueSize() const
Returns the total number of entries in the store queue.
Definition LSUnit.h:66
void acquireLQSlot()
Definition LSUnit.h:70
virtual void onInstructionIssued(const InstRef &IR)=0
void releaseSQSlot()
Definition LSUnit.h:73
A node of a memory dependency graph.
Definition LSUnit.h:246
unsigned getNumInstructions() const
Definition LSUnit.h:279
unsigned getNumExecutingPredecessors() const
Definition LSUnit.h:273
void addInstruction()
Definition LSUnit.h:391
unsigned getNumExecuting() const
Definition LSUnit.h:280
void onGroupIssued(const InstRef &IR, bool ShouldUpdateCriticalDep)
Definition LSUnit.h:323
unsigned getNumPredecessors() const
Definition LSUnit.h:272
bool isExecuted() const
Definition LSUnit.h:321
void onInstructionExecuted(const InstRef &IR)
Definition LSUnit.h:372
bool isExecuting() const
Definition LSUnit.h:318
const CriticalDependency & getCriticalPredecessor() const
Definition LSUnit.h:286
bool isPending() const
Definition LSUnit.h:312
void addSuccessor(MemoryGroup *Group, bool IsDataDependent)
Definition LSUnit.h:290
unsigned getNumExecuted() const
Definition LSUnit.h:281
bool isWaiting() const
Definition LSUnit.h:308
unsigned getNumExecutedPredecessors() const
Definition LSUnit.h:276
void onGroupExecuted()
Definition LSUnit.h:337
bool isReady() const
Definition LSUnit.h:317
MemoryGroup(MemoryGroup &&)=default
size_t getNumSuccessors() const
Definition LSUnit.h:269
void onInstructionIssued(const InstRef &IR)
Definition LSUnit.h:343
void cycleEvent()
Definition LSUnit.h:396
const InstRef & getCriticalMemoryInstruction() const
Definition LSUnit.h:283
unsigned CurrentLoadGroupID
Definition LSUnit.h:405
bool isPending(const InstRef &IR) const override
Check if instruction IR only depends on memory instructions that are currently executing.
Definition LSUnit.h:430
void onInstructionIssued(const InstRef &IR) override
Definition LSUnit.h:468
bool isReady(const InstRef &IR) const override
Check if a peviously dispatched instruction IR is now ready for execution.
Definition LSUnit.h:424
DenseMap< unsigned, std::unique_ptr< MemoryGroup > > Groups
Used to map group identifiers to MemoryGroups.
Definition LSUnit.h:402
unsigned CurrentStoreGroupID
Definition LSUnit.h:407
LSUnit(const MCSchedModel &SM, unsigned LQ, unsigned SQ, bool AssumeNoAlias)
Definition LSUnit.h:415
unsigned CurrentLoadBarrierGroupID
Definition LSUnit.h:406
unsigned NextGroupID
Definition LSUnit.h:403
bool isWaiting(const InstRef &IR) const override
Check if instruction IR is still waiting on memory operations, and the wait time is still unknown.
Definition LSUnit.h:436
unsigned CurrentStoreBarrierGroupID
Definition LSUnit.h:408
LSUnit(const MCSchedModel &SM, unsigned LQ, unsigned SQ)
Definition LSUnit.h:413
const CriticalDependency getCriticalPredecessor(unsigned GroupId) override
Definition LSUnit.h:448
bool hasDependentUsers(const InstRef &IR) const override
Definition LSUnit.h:442
LSUnit(const MCSchedModel &SM)
Definition LSUnit.h:411
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Machine model for scheduling, bundling, and heuristics.
A critical data dependency descriptor.