LLVM 22.0.0git
Instruction.h
Go to the documentation of this file.
1//===--------------------- Instruction.h ------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9///
10/// This file defines abstractions used by the Pipeline to model register reads,
11/// register writes and instructions.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_MCA_INSTRUCTION_H
16#define LLVM_MCA_INSTRUCTION_H
17
18#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/STLExtras.h"
21#include "llvm/MC/MCRegister.h" // definition of MCPhysReg.
24
25#ifndef NDEBUG
27#endif
28
29#include <memory>
30
31namespace llvm {
32
33namespace mca {
34
35constexpr int UNKNOWN_CYCLES = -512;
36
37/// A representation of an mca::Instruction operand
38/// for use in mca::CustomBehaviour.
40 // This class is mostly copied from MCOperand within
41 // MCInst.h except that we don't keep track of
42 // expressions or sub-instructions.
43 enum MCAOperandType : unsigned char {
44 kInvalid, ///< Uninitialized, Relocatable immediate, or Sub-instruction.
45 kRegister, ///< Register operand.
46 kImmediate, ///< Immediate operand.
47 kSFPImmediate, ///< Single-floating-point immediate operand.
48 kDFPImmediate, ///< Double-Floating-point immediate operand.
49 };
50 MCAOperandType Kind;
51
52 union {
53 unsigned RegVal;
54 int64_t ImmVal;
57 };
58
59 // We only store specific operands for specific instructions
60 // so an instruction's operand 3 may be stored within the list
61 // of MCAOperand as element 0. This Index attribute keeps track
62 // of the original index (3 for this example).
63 unsigned Index;
64
65public:
66 MCAOperand() : Kind(kInvalid), FPImmVal(), Index() {}
67
68 bool isValid() const { return Kind != kInvalid; }
69 bool isReg() const { return Kind == kRegister; }
70 bool isImm() const { return Kind == kImmediate; }
71 bool isSFPImm() const { return Kind == kSFPImmediate; }
72 bool isDFPImm() const { return Kind == kDFPImmediate; }
73
74 /// Returns the register number.
75 unsigned getReg() const {
76 assert(isReg() && "This is not a register operand!");
77 return RegVal;
78 }
79
80 int64_t getImm() const {
81 assert(isImm() && "This is not an immediate");
82 return ImmVal;
83 }
84
86 assert(isSFPImm() && "This is not an SFP immediate");
87 return SFPImmVal;
88 }
89
91 assert(isDFPImm() && "This is not an FP immediate");
92 return FPImmVal;
93 }
94
95 void setIndex(const unsigned Idx) { Index = Idx; }
96
97 unsigned getIndex() const { return Index; }
98
99 static MCAOperand createReg(unsigned Reg) {
101 Op.Kind = kRegister;
102 Op.RegVal = Reg;
103 return Op;
104 }
105
106 static MCAOperand createImm(int64_t Val) {
108 Op.Kind = kImmediate;
109 Op.ImmVal = Val;
110 return Op;
111 }
112
115 Op.Kind = kSFPImmediate;
116 Op.SFPImmVal = Val;
117 return Op;
118 }
119
122 Op.Kind = kDFPImmediate;
123 Op.FPImmVal = Val;
124 return Op;
125 }
126
129 Op.Kind = kInvalid;
130 Op.FPImmVal = 0;
131 return Op;
132 }
133};
134
135/// A register write descriptor.
137 // Operand index. The index is negative for implicit writes only.
138 // For implicit writes, the actual operand index is computed performing
139 // a bitwise not of the OpIndex.
141 // Write latency. Number of cycles before write-back stage.
142 unsigned Latency;
143 // This field is set to a value different than zero only if this
144 // is an implicit definition.
146 // Instruction itineraries would set this field to the SchedClass ID.
147 // Otherwise, it defaults to the WriteResourceID from the MCWriteLatencyEntry
148 // element associated to this write.
149 // When computing read latencies, this value is matched against the
150 // "ReadAdvance" information. The hardware backend may implement
151 // dedicated forwarding paths to quickly propagate write results to dependent
152 // instructions waiting in the reservation station (effectively bypassing the
153 // write-back stage).
155 // True only if this is a write obtained from an optional definition.
156 // Optional definitions are allowed to reference regID zero (i.e. "no
157 // register").
159
160 bool isImplicitWrite() const { return OpIndex < 0; };
161};
162
163/// A register read descriptor.
165 // A MCOperand index. This is used by the Dispatch logic to identify register
166 // reads. Implicit reads have negative indices. The actual operand index of an
167 // implicit read is the bitwise not of field OpIndex.
169 // The actual "UseIdx". This is used to query the ReadAdvance table. Explicit
170 // uses always come first in the sequence of uses.
171 unsigned UseIndex;
172 // This field is only set if this is an implicit read.
174 // Scheduling Class Index. It is used to query the scheduling model for the
175 // MCSchedClassDesc object.
176 unsigned SchedClassID;
177
178 bool isImplicitRead() const { return OpIndex < 0; };
179};
180
181class ReadState;
182
183/// A critical data dependency descriptor.
184///
185/// Field RegID is set to the invalid register for memory dependencies.
187 unsigned IID;
189 unsigned Cycles;
190};
191
192/// Tracks uses of a register definition (e.g. register write).
193///
194/// Each implicit/explicit register write is associated with an instance of
195/// this class. A WriteState object tracks the dependent users of a
196/// register write. It also tracks how many cycles are left before the write
197/// back stage.
199 const WriteDescriptor *WD;
200 // On instruction issue, this field is set equal to the write latency.
201 // Before instruction issue, this field defaults to -512, a special
202 // value that represents an "unknown" number of cycles.
203 int CyclesLeft;
204
205 // Actual register defined by this write. This field is only used
206 // to speedup queries on the register file.
207 // For implicit writes, this field always matches the value of
208 // field RegisterID from WD.
209 MCPhysReg RegisterID;
210
211 // Physical register file that serves register RegisterID.
212 unsigned PRFID;
213
214 // True if this write implicitly clears the upper portion of RegisterID's
215 // super-registers.
216 bool ClearsSuperRegs;
217
218 // True if this write is from a dependency breaking zero-idiom instruction.
219 bool WritesZero;
220
221 // True if this write has been eliminated at register renaming stage.
222 // Example: a register move doesn't consume scheduler/pipleline resources if
223 // it is eliminated at register renaming stage. It still consumes
224 // decode bandwidth, and ROB entries.
225 bool IsEliminated;
226
227 // This field is set if this is a partial register write, and it has a false
228 // dependency on any previous write of the same register (or a portion of it).
229 // DependentWrite must be able to complete before this write completes, so
230 // that we don't break the WAW, and the two writes can be merged together.
231 const WriteState *DependentWrite;
232
233 // A partial write that is in a false dependency with this write.
234 WriteState *PartialWrite;
235 unsigned DependentWriteCyclesLeft;
236
237 // Critical register dependency for this write.
239
240 // A list of dependent reads. Users is a set of dependent
241 // reads. A dependent read is added to the set only if CyclesLeft
242 // is "unknown". As soon as CyclesLeft is 'known', each user in the set
243 // gets notified with the actual CyclesLeft.
244
245 // The 'second' element of a pair is a "ReadAdvance" number of cycles.
247
248public:
250 bool clearsSuperRegs = false, bool writesZero = false)
251 : WD(&Desc), CyclesLeft(UNKNOWN_CYCLES), RegisterID(RegID), PRFID(0),
252 ClearsSuperRegs(clearsSuperRegs), WritesZero(writesZero),
253 IsEliminated(false), DependentWrite(nullptr), PartialWrite(nullptr),
254 DependentWriteCyclesLeft(0), CRD() {}
255
256 WriteState(const WriteState &Other) = default;
258
259 int getCyclesLeft() const { return CyclesLeft; }
260 unsigned getWriteResourceID() const { return WD->SClassOrWriteResourceID; }
261 MCPhysReg getRegisterID() const { return RegisterID; }
262 void setRegisterID(const MCPhysReg RegID) { RegisterID = RegID; }
263 unsigned getRegisterFileID() const { return PRFID; }
264 unsigned getLatency() const { return WD->Latency; }
266 return DependentWriteCyclesLeft;
267 }
268 const WriteState *getDependentWrite() const { return DependentWrite; }
269 const CriticalDependency &getCriticalRegDep() const { return CRD; }
270
271 // This method adds Use to the set of data dependent reads. IID is the
272 // instruction identifier associated with this write. ReadAdvance is the
273 // number of cycles to subtract from the latency of this data dependency.
274 // Use is in a RAW dependency with this write.
275 LLVM_ABI void addUser(unsigned IID, ReadState *Use, int ReadAdvance);
276
277 // Use is a younger register write that is in a false dependency with this
278 // write. IID is the instruction identifier associated with this write.
279 LLVM_ABI void addUser(unsigned IID, WriteState *Use);
280
281 unsigned getNumUsers() const {
282 unsigned NumUsers = Users.size();
283 if (PartialWrite)
284 ++NumUsers;
285 return NumUsers;
286 }
287
288 bool clearsSuperRegisters() const { return ClearsSuperRegs; }
289 bool isWriteZero() const { return WritesZero; }
290 bool isEliminated() const { return IsEliminated; }
291
292 bool isReady() const {
293 if (DependentWrite)
294 return false;
295 unsigned CyclesLeft = getDependentWriteCyclesLeft();
296 return !CyclesLeft || CyclesLeft < getLatency();
297 }
298
299 bool isExecuted() const {
300 return CyclesLeft != UNKNOWN_CYCLES && CyclesLeft <= 0;
301 }
302
303 void setDependentWrite(const WriteState *Other) { DependentWrite = Other; }
304 LLVM_ABI void writeStartEvent(unsigned IID, MCPhysReg RegID, unsigned Cycles);
305 void setWriteZero() { WritesZero = true; }
307 assert(Users.empty() && "Write is in an inconsistent state.");
308 CyclesLeft = 0;
309 IsEliminated = true;
310 }
311
312 void setPRF(unsigned PRF) { PRFID = PRF; }
313
314 // On every cycle, update CyclesLeft and notify dependent users.
315 LLVM_ABI void cycleEvent();
316 LLVM_ABI void onInstructionIssued(unsigned IID);
317
318#ifndef NDEBUG
319 void dump() const;
320#endif
321};
322
323/// Tracks register operand latency in cycles.
324///
325/// A read may be dependent on more than one write. This occurs when some
326/// writes only partially update the register associated to this read.
328 const ReadDescriptor *RD;
329 // Physical register identified associated to this read.
330 MCPhysReg RegisterID;
331 // Physical register file that serves register RegisterID.
332 unsigned PRFID;
333 // Number of writes that contribute to the definition of RegisterID.
334 // In the absence of partial register updates, the number of DependentWrites
335 // cannot be more than one.
336 unsigned DependentWrites;
337 // Number of cycles left before RegisterID can be read. This value depends on
338 // the latency of all the dependent writes. It defaults to UNKNOWN_CYCLES.
339 // It gets set to the value of field TotalCycles only when the 'CyclesLeft' of
340 // every dependent write is known.
341 int CyclesLeft;
342 // This field is updated on every writeStartEvent(). When the number of
343 // dependent writes (i.e. field DependentWrite) is zero, this value is
344 // propagated to field CyclesLeft.
345 unsigned TotalCycles;
346 // Longest register dependency.
348 // This field is set to true only if there are no dependent writes, and
349 // there are no `CyclesLeft' to wait.
350 bool IsReady;
351 // True if this is a read from a known zero register.
352 bool IsZero;
353 // True if this register read is from a dependency-breaking instruction.
354 bool IndependentFromDef;
355
356public:
358 : RD(&Desc), RegisterID(RegID), PRFID(0), DependentWrites(0),
359 CyclesLeft(UNKNOWN_CYCLES), TotalCycles(0), CRD(), IsReady(true),
360 IsZero(false), IndependentFromDef(false) {}
361
362 const ReadDescriptor &getDescriptor() const { return *RD; }
363 unsigned getSchedClass() const { return RD->SchedClassID; }
364 MCPhysReg getRegisterID() const { return RegisterID; }
365 unsigned getRegisterFileID() const { return PRFID; }
366 const CriticalDependency &getCriticalRegDep() const { return CRD; }
367
368 bool isPending() const { return !IndependentFromDef && CyclesLeft > 0; }
369 bool isReady() const { return IsReady; }
370 bool isImplicitRead() const { return RD->isImplicitRead(); }
371
372 bool isIndependentFromDef() const { return IndependentFromDef; }
373 void setIndependentFromDef() { IndependentFromDef = true; }
374
375 LLVM_ABI void cycleEvent();
376 LLVM_ABI void writeStartEvent(unsigned IID, MCPhysReg RegID, unsigned Cycles);
377 void setDependentWrites(unsigned Writes) {
378 DependentWrites = Writes;
379 IsReady = !Writes;
380 }
381
382 bool isReadZero() const { return IsZero; }
383 void setReadZero() { IsZero = true; }
384 void setPRF(unsigned ID) { PRFID = ID; }
385
386#ifndef NDEBUG
387 void dump() const;
388#endif
389};
390
391/// A sequence of cycles.
392///
393/// This class can be used as a building block to construct ranges of cycles.
395 unsigned Begin; // Inclusive.
396 unsigned End; // Exclusive.
397 bool Reserved; // Resources associated to this segment must be reserved.
398
399public:
400 CycleSegment(unsigned StartCycle, unsigned EndCycle, bool IsReserved = false)
401 : Begin(StartCycle), End(EndCycle), Reserved(IsReserved) {}
402
403 bool contains(unsigned Cycle) const { return Cycle >= Begin && Cycle < End; }
404 bool startsAfter(const CycleSegment &CS) const { return End <= CS.Begin; }
405 bool endsBefore(const CycleSegment &CS) const { return Begin >= CS.End; }
406 bool overlaps(const CycleSegment &CS) const {
407 return !startsAfter(CS) && !endsBefore(CS);
408 }
409 bool isExecuting() const { return Begin == 0 && End != 0; }
410 bool isExecuted() const { return End == 0; }
411 bool operator<(const CycleSegment &Other) const {
412 return Begin < Other.Begin;
413 }
415 if (Begin)
416 Begin--;
417 if (End)
418 End--;
419 return *this;
420 }
421
422 bool isValid() const { return Begin <= End; }
423 unsigned size() const { return End - Begin; };
424 void subtract(unsigned Cycles) {
425 assert(End >= Cycles);
426 End -= Cycles;
427 }
428
429 unsigned begin() const { return Begin; }
430 unsigned end() const { return End; }
431 void setEnd(unsigned NewEnd) { End = NewEnd; }
432 bool isReserved() const { return Reserved; }
433 void setReserved() { Reserved = true; }
434};
435
436/// Helper used by class InstrDesc to describe how hardware resources
437/// are used.
438///
439/// This class describes how many resource units of a specific resource kind
440/// (and how many cycles) are "used" by an instruction.
443 unsigned NumUnits;
444 ResourceUsage(CycleSegment Cycles, unsigned Units = 1)
445 : CS(Cycles), NumUnits(Units) {}
446 unsigned size() const { return CS.size(); }
447 bool isReserved() const { return CS.isReserved(); }
449};
450
451/// An instruction descriptor
452struct InstrDesc {
453 SmallVector<WriteDescriptor, 2> Writes; // Implicit writes are at the end.
454 SmallVector<ReadDescriptor, 4> Reads; // Implicit reads are at the end.
455
456 // For every resource used by an instruction of this kind, this vector
457 // reports the number of "consumed cycles".
459
460 // A bitmask of used hardware buffers.
462
463 // A bitmask of used processor resource units.
465
466 // A bitmask of used processor resource groups.
468
469 unsigned MaxLatency;
470 // Number of MicroOps for this instruction.
471 unsigned NumMicroOps;
472 // SchedClassID used to construct this InstrDesc.
473 // This information is currently used by views to do fast queries on the
474 // subtarget when computing the reciprocal throughput.
475 unsigned SchedClassID;
476
477 // True if all buffered resources are in-order, and there is at least one
478 // buffer which is a dispatch hazard (BufferSize = 0).
480
481 // True if the corresponding mca::Instruction can be recycled. Currently only
482 // instructions that are neither variadic nor have any variant can be
483 // recycled.
484 unsigned IsRecyclable : 1;
485
486 // True if some of the consumed group resources are partially overlapping.
488
489 // A zero latency instruction doesn't consume any scheduler resources.
490 bool isZeroLatency() const { return !MaxLatency && Resources.empty(); }
491
492 InstrDesc() = default;
493 InstrDesc(const InstrDesc &Other) = delete;
495};
496
497/// Base class for instructions consumed by the simulation pipeline.
498///
499/// This class tracks data dependencies as well as generic properties
500/// of the instruction.
502 const InstrDesc &Desc;
503
504 // This field is set for instructions that are candidates for move
505 // elimination. For more information about move elimination, see the
506 // definition of RegisterMappingTracker in RegisterFile.h
507 bool IsOptimizableMove;
508
509 // Output dependencies.
510 // One entry per each implicit and explicit register definition.
512
513 // Input dependencies.
514 // One entry per each implicit and explicit register use.
516
517 // List of operands which can be used by mca::CustomBehaviour
518 std::vector<MCAOperand> Operands;
519
520 // Instruction opcode which can be used by mca::CustomBehaviour
521 unsigned Opcode;
522
523 // Flags used by the LSUnit.
524 bool IsALoadBarrier : 1;
525 bool IsAStoreBarrier : 1;
526 // Flags copied from the InstrDesc and potentially modified by
527 // CustomBehaviour or (more likely) InstrPostProcess.
528 bool MayLoad : 1;
529 bool MayStore : 1;
530 bool HasSideEffects : 1;
531 bool BeginGroup : 1;
532 bool EndGroup : 1;
533 bool RetireOOO : 1;
534
535public:
536 InstructionBase(const InstrDesc &D, const unsigned Opcode)
537 : Desc(D), IsOptimizableMove(false), Operands(0), Opcode(Opcode),
538 IsALoadBarrier(false), IsAStoreBarrier(false) {}
539
541 ArrayRef<WriteState> getDefs() const { return Defs; }
543 ArrayRef<ReadState> getUses() const { return Uses; }
544 const InstrDesc &getDesc() const { return Desc; }
545
546 unsigned getLatency() const { return Desc.MaxLatency; }
547 unsigned getNumMicroOps() const { return Desc.NumMicroOps; }
548 unsigned getOpcode() const { return Opcode; }
549 bool isALoadBarrier() const { return IsALoadBarrier; }
550 bool isAStoreBarrier() const { return IsAStoreBarrier; }
551 void setLoadBarrier(bool IsBarrier) { IsALoadBarrier = IsBarrier; }
552 void setStoreBarrier(bool IsBarrier) { IsAStoreBarrier = IsBarrier; }
553
554 /// Return the MCAOperand which corresponds to index Idx within the original
555 /// MCInst.
556 const MCAOperand *getOperand(const unsigned Idx) const {
557 auto It = llvm::find_if(Operands, [&Idx](const MCAOperand &Op) {
558 return Op.getIndex() == Idx;
559 });
560 if (It == Operands.end())
561 return nullptr;
562 return &(*It);
563 }
564 unsigned getNumOperands() const { return Operands.size(); }
565 void addOperand(const MCAOperand Op) { Operands.push_back(Op); }
566
567 bool hasDependentUsers() const {
568 return any_of(Defs,
569 [](const WriteState &Def) { return Def.getNumUsers() > 0; });
570 }
571
572 unsigned getNumUsers() const {
573 unsigned NumUsers = 0;
574 for (const WriteState &Def : Defs)
575 NumUsers += Def.getNumUsers();
576 return NumUsers;
577 }
578
579 // Returns true if this instruction is a candidate for move elimination.
580 bool isOptimizableMove() const { return IsOptimizableMove; }
581 void setOptimizableMove() { IsOptimizableMove = true; }
582 void clearOptimizableMove() { IsOptimizableMove = false; }
583 bool isMemOp() const { return MayLoad || MayStore; }
584
585 // Getters and setters for general instruction flags.
586 void setMayLoad(bool newVal) { MayLoad = newVal; }
587 void setMayStore(bool newVal) { MayStore = newVal; }
588 void setHasSideEffects(bool newVal) { HasSideEffects = newVal; }
589 void setBeginGroup(bool newVal) { BeginGroup = newVal; }
590 void setEndGroup(bool newVal) { EndGroup = newVal; }
591 void setRetireOOO(bool newVal) { RetireOOO = newVal; }
592
593 bool getMayLoad() const { return MayLoad; }
594 bool getMayStore() const { return MayStore; }
595 bool getHasSideEffects() const { return HasSideEffects; }
596 bool getBeginGroup() const { return BeginGroup; }
597 bool getEndGroup() const { return EndGroup; }
598 bool getRetireOOO() const { return RetireOOO; }
599};
600
601/// An instruction propagated through the simulated instruction pipeline.
602///
603/// This class is used to monitor changes to the internal state of instructions
604/// that are sent to the various components of the simulated hardware pipeline.
606 enum InstrStage {
607 IS_INVALID, // Instruction in an invalid state.
608 IS_DISPATCHED, // Instruction dispatched but operands are not ready.
609 IS_PENDING, // Instruction is not ready, but operand latency is known.
610 IS_READY, // Instruction dispatched and operands ready.
611 IS_EXECUTING, // Instruction issued.
612 IS_EXECUTED, // Instruction executed. Values are written back.
613 IS_RETIRED // Instruction retired.
614 };
615
616 // The current instruction stage.
617 enum InstrStage Stage;
618
619 // This value defaults to the instruction latency. This instruction is
620 // considered executed when field CyclesLeft goes to zero.
621 int CyclesLeft;
622
623 // Retire Unit token ID for this instruction.
624 unsigned RCUTokenID;
625
626 // LS token ID for this instruction.
627 // This field is set to the invalid null token if this is not a memory
628 // operation.
629 unsigned LSUTokenID;
630
631 // A resource mask which identifies buffered resources consumed by this
632 // instruction at dispatch stage. In the absence of macro-fusion, this value
633 // should always match the value of field `UsedBuffers` from the instruction
634 // descriptor (see field InstrBase::Desc).
635 uint64_t UsedBuffers;
636
637 // Critical register dependency.
638 CriticalDependency CriticalRegDep;
639
640 // Critical memory dependency.
641 CriticalDependency CriticalMemDep;
642
643 // A bitmask of busy processor resource units.
644 // This field is set to zero only if execution is not delayed during this
645 // cycle because of unavailable pipeline resources.
646 uint64_t CriticalResourceMask;
647
648 // True if this instruction has been optimized at register renaming stage.
649 bool IsEliminated;
650
651public:
652 Instruction(const InstrDesc &D, const unsigned Opcode)
653 : InstructionBase(D, Opcode), Stage(IS_INVALID),
654 CyclesLeft(UNKNOWN_CYCLES), RCUTokenID(0), LSUTokenID(0),
655 UsedBuffers(D.UsedBuffers), CriticalRegDep(), CriticalMemDep(),
656 CriticalResourceMask(0), IsEliminated(false) {}
657
658 LLVM_ABI void reset();
659
660 unsigned getRCUTokenID() const { return RCUTokenID; }
661 unsigned getLSUTokenID() const { return LSUTokenID; }
662 void setLSUTokenID(unsigned LSUTok) { LSUTokenID = LSUTok; }
663
664 uint64_t getUsedBuffers() const { return UsedBuffers; }
665 void setUsedBuffers(uint64_t Mask) { UsedBuffers = Mask; }
666 void clearUsedBuffers() { UsedBuffers = 0ULL; }
667
668 int getCyclesLeft() const { return CyclesLeft; }
669
670 // Transition to the dispatch stage, and assign a RCUToken to this
671 // instruction. The RCUToken is used to track the completion of every
672 // register write performed by this instruction.
673 LLVM_ABI void dispatch(unsigned RCUTokenID);
674
675 // Instruction issued. Transition to the IS_EXECUTING state, and update
676 // all the register definitions.
677 LLVM_ABI void execute(unsigned IID);
678
679 // Force a transition from the IS_DISPATCHED state to the IS_READY or
680 // IS_PENDING state. State transitions normally occur either at the beginning
681 // of a new cycle (see method cycleEvent()), or as a result of another issue
682 // event. This method is called every time the instruction might have changed
683 // in state. It internally delegates to method updateDispatched() and
684 // updateWaiting().
685 LLVM_ABI void update();
687 LLVM_ABI bool updatePending();
688
689 bool isInvalid() const { return Stage == IS_INVALID; }
690 bool isDispatched() const { return Stage == IS_DISPATCHED; }
691 bool isPending() const { return Stage == IS_PENDING; }
692 bool isReady() const { return Stage == IS_READY; }
693 bool isExecuting() const { return Stage == IS_EXECUTING; }
694 bool isExecuted() const { return Stage == IS_EXECUTED; }
695 bool isRetired() const { return Stage == IS_RETIRED; }
696 bool isEliminated() const { return IsEliminated; }
697
698 // Forces a transition from state IS_DISPATCHED to state IS_EXECUTED.
699 LLVM_ABI void forceExecuted();
700 void setEliminated() { IsEliminated = true; }
701
702 void retire() {
703 assert(isExecuted() && "Instruction is in an invalid state!");
704 Stage = IS_RETIRED;
705 }
706
707 const CriticalDependency &getCriticalRegDep() const { return CriticalRegDep; }
708 const CriticalDependency &getCriticalMemDep() const { return CriticalMemDep; }
711 CriticalMemDep = MemDep;
712 }
713
714 uint64_t getCriticalResourceMask() const { return CriticalResourceMask; }
716 CriticalResourceMask = ResourceMask;
717 }
718
719 LLVM_ABI void cycleEvent();
720};
721
722/// An InstRef contains both a SourceMgr index and Instruction pair. The index
723/// is used as a unique identifier for the instruction. MCA will make use of
724/// this index as a key throughout MCA.
725class InstRef {
726 std::pair<unsigned, Instruction *> Data;
727
728public:
729 InstRef() : Data(std::make_pair(0, nullptr)) {}
730 InstRef(unsigned Index, Instruction *I) : Data(std::make_pair(Index, I)) {}
731
732 bool operator==(const InstRef &Other) const { return Data == Other.Data; }
733 bool operator!=(const InstRef &Other) const { return Data != Other.Data; }
734 bool operator<(const InstRef &Other) const {
735 return Data.first < Other.Data.first;
736 }
737
738 unsigned getSourceIndex() const { return Data.first; }
739 Instruction *getInstruction() { return Data.second; }
740 const Instruction *getInstruction() const { return Data.second; }
741
742 /// Returns true if this references a valid instruction.
743 explicit operator bool() const { return Data.second != nullptr; }
744
745 /// Invalidate this reference.
746 void invalidate() { Data.second = nullptr; }
747
748#ifndef NDEBUG
749 void print(raw_ostream &OS) const { OS << getSourceIndex(); }
750#endif
751};
752
753#ifndef NDEBUG
755 IR.print(OS);
756 return OS;
757}
758#endif
759
760} // namespace mca
761} // namespace llvm
762
763#endif // LLVM_MCA_INSTRUCTION_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define LLVM_ABI
Definition: Compiler.h:213
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint32_t Index
bool End
Definition: ELF_riscv.cpp:480
SmallVector< uint32_t, 0 > Writes
Definition: ELF_riscv.cpp:497
iv Induction Variable Users
Definition: IVUsers.cpp:48
Legalize the Machine IR a function s Machine IR
Definition: Legalizer.cpp:80
#define I(x, y, z)
Definition: MD5.cpp:58
mir Rename Register Operands
Register Reg
Remove Loads Into Fake Uses
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
This class represents an Operation in the Expression.
A possibly irreducible generalization of a Loop.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
A Use represents the edge between a Value definition and its users.
Definition: Use.h:35
A sequence of cycles.
Definition: Instruction.h:394
CycleSegment(unsigned StartCycle, unsigned EndCycle, bool IsReserved=false)
Definition: Instruction.h:400
bool isExecuting() const
Definition: Instruction.h:409
bool operator<(const CycleSegment &Other) const
Definition: Instruction.h:411
bool startsAfter(const CycleSegment &CS) const
Definition: Instruction.h:404
bool contains(unsigned Cycle) const
Definition: Instruction.h:403
void setEnd(unsigned NewEnd)
Definition: Instruction.h:431
void subtract(unsigned Cycles)
Definition: Instruction.h:424
CycleSegment & operator--()
Definition: Instruction.h:414
unsigned end() const
Definition: Instruction.h:430
bool isReserved() const
Definition: Instruction.h:432
unsigned size() const
Definition: Instruction.h:423
bool endsBefore(const CycleSegment &CS) const
Definition: Instruction.h:405
bool isExecuted() const
Definition: Instruction.h:410
unsigned begin() const
Definition: Instruction.h:429
bool overlaps(const CycleSegment &CS) const
Definition: Instruction.h:406
An InstRef contains both a SourceMgr index and Instruction pair.
Definition: Instruction.h:725
void invalidate()
Invalidate this reference.
Definition: Instruction.h:746
bool operator<(const InstRef &Other) const
Definition: Instruction.h:734
const Instruction * getInstruction() const
Definition: Instruction.h:740
InstRef(unsigned Index, Instruction *I)
Definition: Instruction.h:730
Instruction * getInstruction()
Definition: Instruction.h:739
unsigned getSourceIndex() const
Definition: Instruction.h:738
bool operator!=(const InstRef &Other) const
Definition: Instruction.h:733
bool operator==(const InstRef &Other) const
Definition: Instruction.h:732
void print(raw_ostream &OS) const
Definition: Instruction.h:749
Base class for instructions consumed by the simulation pipeline.
Definition: Instruction.h:501
void setEndGroup(bool newVal)
Definition: Instruction.h:590
unsigned getOpcode() const
Definition: Instruction.h:548
bool isAStoreBarrier() const
Definition: Instruction.h:550
bool isOptimizableMove() const
Definition: Instruction.h:580
void setRetireOOO(bool newVal)
Definition: Instruction.h:591
ArrayRef< WriteState > getDefs() const
Definition: Instruction.h:541
void addOperand(const MCAOperand Op)
Definition: Instruction.h:565
unsigned getNumMicroOps() const
Definition: Instruction.h:547
const InstrDesc & getDesc() const
Definition: Instruction.h:544
const MCAOperand * getOperand(const unsigned Idx) const
Return the MCAOperand which corresponds to index Idx within the original MCInst.
Definition: Instruction.h:556
SmallVectorImpl< WriteState > & getDefs()
Definition: Instruction.h:540
bool hasDependentUsers() const
Definition: Instruction.h:567
unsigned getLatency() const
Definition: Instruction.h:546
void setBeginGroup(bool newVal)
Definition: Instruction.h:589
bool getHasSideEffects() const
Definition: Instruction.h:595
SmallVectorImpl< ReadState > & getUses()
Definition: Instruction.h:542
void setLoadBarrier(bool IsBarrier)
Definition: Instruction.h:551
unsigned getNumOperands() const
Definition: Instruction.h:564
void setStoreBarrier(bool IsBarrier)
Definition: Instruction.h:552
void setHasSideEffects(bool newVal)
Definition: Instruction.h:588
void setMayStore(bool newVal)
Definition: Instruction.h:587
ArrayRef< ReadState > getUses() const
Definition: Instruction.h:543
InstructionBase(const InstrDesc &D, const unsigned Opcode)
Definition: Instruction.h:536
unsigned getNumUsers() const
Definition: Instruction.h:572
void setMayLoad(bool newVal)
Definition: Instruction.h:586
An instruction propagated through the simulated instruction pipeline.
Definition: Instruction.h:605
LLVM_ABI void cycleEvent()
bool isDispatched() const
Definition: Instruction.h:690
bool isEliminated() const
Definition: Instruction.h:696
Instruction(const InstrDesc &D, const unsigned Opcode)
Definition: Instruction.h:652
bool isExecuted() const
Definition: Instruction.h:694
uint64_t getCriticalResourceMask() const
Definition: Instruction.h:714
unsigned getRCUTokenID() const
Definition: Instruction.h:660
LLVM_ABI bool updateDispatched()
const CriticalDependency & getCriticalMemDep() const
Definition: Instruction.h:708
const CriticalDependency & getCriticalRegDep() const
Definition: Instruction.h:707
bool isExecuting() const
Definition: Instruction.h:693
LLVM_ABI void forceExecuted()
int getCyclesLeft() const
Definition: Instruction.h:668
bool isRetired() const
Definition: Instruction.h:695
void setCriticalResourceMask(uint64_t ResourceMask)
Definition: Instruction.h:715
bool isReady() const
Definition: Instruction.h:692
LLVM_ABI const CriticalDependency & computeCriticalRegDep()
LLVM_ABI void execute(unsigned IID)
bool isInvalid() const
Definition: Instruction.h:689
LLVM_ABI bool updatePending()
void setLSUTokenID(unsigned LSUTok)
Definition: Instruction.h:662
void setUsedBuffers(uint64_t Mask)
Definition: Instruction.h:665
void setCriticalMemDep(const CriticalDependency &MemDep)
Definition: Instruction.h:710
LLVM_ABI void dispatch(unsigned RCUTokenID)
LLVM_ABI void update()
uint64_t getUsedBuffers() const
Definition: Instruction.h:664
LLVM_ABI void reset()
bool isPending() const
Definition: Instruction.h:691
unsigned getLSUTokenID() const
Definition: Instruction.h:661
A representation of an mca::Instruction operand for use in mca::CustomBehaviour.
Definition: Instruction.h:39
unsigned getReg() const
Returns the register number.
Definition: Instruction.h:75
static MCAOperand createSFPImm(uint32_t Val)
Definition: Instruction.h:113
uint32_t getSFPImm() const
Definition: Instruction.h:85
static MCAOperand createInvalid()
Definition: Instruction.h:127
static MCAOperand createDFPImm(uint64_t Val)
Definition: Instruction.h:120
static MCAOperand createImm(int64_t Val)
Definition: Instruction.h:106
static MCAOperand createReg(unsigned Reg)
Definition: Instruction.h:99
unsigned getIndex() const
Definition: Instruction.h:97
bool isImm() const
Definition: Instruction.h:70
bool isDFPImm() const
Definition: Instruction.h:72
bool isSFPImm() const
Definition: Instruction.h:71
int64_t getImm() const
Definition: Instruction.h:80
uint64_t getDFPImm() const
Definition: Instruction.h:90
void setIndex(const unsigned Idx)
Definition: Instruction.h:95
bool isReg() const
Definition: Instruction.h:69
bool isValid() const
Definition: Instruction.h:68
Tracks register operand latency in cycles.
Definition: Instruction.h:327
unsigned getRegisterFileID() const
Definition: Instruction.h:365
unsigned getSchedClass() const
Definition: Instruction.h:363
LLVM_ABI void writeStartEvent(unsigned IID, MCPhysReg RegID, unsigned Cycles)
Definition: Instruction.cpp:30
bool isIndependentFromDef() const
Definition: Instruction.h:372
const ReadDescriptor & getDescriptor() const
Definition: Instruction.h:362
void setPRF(unsigned ID)
Definition: Instruction.h:384
const CriticalDependency & getCriticalRegDep() const
Definition: Instruction.h:366
LLVM_ABI void cycleEvent()
void setDependentWrites(unsigned Writes)
Definition: Instruction.h:377
bool isReady() const
Definition: Instruction.h:369
MCPhysReg getRegisterID() const
Definition: Instruction.h:364
bool isImplicitRead() const
Definition: Instruction.h:370
ReadState(const ReadDescriptor &Desc, MCPhysReg RegID)
Definition: Instruction.h:357
void setIndependentFromDef()
Definition: Instruction.h:373
bool isPending() const
Definition: Instruction.h:368
bool isReadZero() const
Definition: Instruction.h:382
Tracks uses of a register definition (e.g.
Definition: Instruction.h:198
unsigned getRegisterFileID() const
Definition: Instruction.h:263
bool isEliminated() const
Definition: Instruction.h:290
const WriteState * getDependentWrite() const
Definition: Instruction.h:268
LLVM_ABI void writeStartEvent(unsigned IID, MCPhysReg RegID, unsigned Cycles)
Definition: Instruction.cpp:21
unsigned getDependentWriteCyclesLeft() const
Definition: Instruction.h:265
void setRegisterID(const MCPhysReg RegID)
Definition: Instruction.h:262
unsigned getLatency() const
Definition: Instruction.h:264
WriteState & operator=(const WriteState &Other)=default
void setPRF(unsigned PRF)
Definition: Instruction.h:312
void setDependentWrite(const WriteState *Other)
Definition: Instruction.h:303
int getCyclesLeft() const
Definition: Instruction.h:259
LLVM_ABI void cycleEvent()
Definition: Instruction.cpp:96
WriteState(const WriteDescriptor &Desc, MCPhysReg RegID, bool clearsSuperRegs=false, bool writesZero=false)
Definition: Instruction.h:249
const CriticalDependency & getCriticalRegDep() const
Definition: Instruction.h:269
LLVM_ABI void onInstructionIssued(unsigned IID)
Definition: Instruction.cpp:54
WriteState(const WriteState &Other)=default
bool clearsSuperRegisters() const
Definition: Instruction.h:288
unsigned getNumUsers() const
Definition: Instruction.h:281
MCPhysReg getRegisterID() const
Definition: Instruction.h:261
bool isWriteZero() const
Definition: Instruction.h:289
bool isExecuted() const
Definition: Instruction.h:299
unsigned getWriteResourceID() const
Definition: Instruction.h:260
LLVM_ABI void addUser(unsigned IID, ReadState *Use, int ReadAdvance)
Definition: Instruction.cpp:72
bool isReady() const
Definition: Instruction.h:292
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
raw_ostream & operator<<(raw_ostream &OS, const InstRef &IR)
Definition: Instruction.h:754
constexpr int UNKNOWN_CYCLES
Definition: Instruction.h:35
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition: MCRegister.h:21
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1751
@ Other
Any other memory.
DWARFExpression::Operation Op
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1777
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
Description of the encoding of one expression Op.
A critical data dependency descriptor.
Definition: Instruction.h:186
An instruction descriptor.
Definition: Instruction.h:452
uint64_t UsedProcResGroups
Definition: Instruction.h:467
uint64_t UsedProcResUnits
Definition: Instruction.h:464
SmallVector< WriteDescriptor, 2 > Writes
Definition: Instruction.h:453
InstrDesc(const InstrDesc &Other)=delete
SmallVector< std::pair< uint64_t, ResourceUsage >, 4 > Resources
Definition: Instruction.h:458
unsigned HasPartiallyOverlappingGroups
Definition: Instruction.h:487
SmallVector< ReadDescriptor, 4 > Reads
Definition: Instruction.h:454
bool isZeroLatency() const
Definition: Instruction.h:490
InstrDesc & operator=(const InstrDesc &Other)=delete
unsigned MustIssueImmediately
Definition: Instruction.h:479
A register read descriptor.
Definition: Instruction.h:164
bool isImplicitRead() const
Definition: Instruction.h:178
Helper used by class InstrDesc to describe how hardware resources are used.
Definition: Instruction.h:441
ResourceUsage(CycleSegment Cycles, unsigned Units=1)
Definition: Instruction.h:444
unsigned size() const
Definition: Instruction.h:446
A register write descriptor.
Definition: Instruction.h:136
bool isImplicitWrite() const
Definition: Instruction.h:160