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