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(); }
448 void setReserved() { CS.setReserved(); }
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
Legalize the Machine IR a function s Machine IR
Definition Legalizer.cpp:80
#define I(x, y, z)
Definition MD5.cpp:58
Register Reg
This file contains some templates that are useful if you are working with the STL at all.
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 consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
A sequence of cycles.
CycleSegment(unsigned StartCycle, unsigned EndCycle, bool IsReserved=false)
bool operator<(const CycleSegment &Other) const
bool startsAfter(const CycleSegment &CS) const
bool contains(unsigned Cycle) const
void setEnd(unsigned NewEnd)
void subtract(unsigned Cycles)
CycleSegment & operator--()
unsigned end() const
unsigned size() const
bool endsBefore(const CycleSegment &CS) const
unsigned begin() const
bool overlaps(const CycleSegment &CS) const
An InstRef contains both a SourceMgr index and Instruction pair.
void invalidate()
Invalidate this reference.
bool operator<(const InstRef &Other) const
const Instruction * getInstruction() const
InstRef(unsigned Index, Instruction *I)
Instruction * getInstruction()
unsigned getSourceIndex() const
bool operator!=(const InstRef &Other) const
bool operator==(const InstRef &Other) const
void print(raw_ostream &OS) const
void setEndGroup(bool newVal)
unsigned getOpcode() const
void setRetireOOO(bool newVal)
ArrayRef< WriteState > getDefs() const
void addOperand(const MCAOperand Op)
unsigned getNumMicroOps() const
const InstrDesc & getDesc() const
const MCAOperand * getOperand(const unsigned Idx) const
Return the MCAOperand which corresponds to index Idx within the original MCInst.
SmallVectorImpl< WriteState > & getDefs()
unsigned getLatency() const
void setBeginGroup(bool newVal)
SmallVectorImpl< ReadState > & getUses()
void setLoadBarrier(bool IsBarrier)
unsigned getNumOperands() const
void setStoreBarrier(bool IsBarrier)
void setHasSideEffects(bool newVal)
void setMayStore(bool newVal)
ArrayRef< ReadState > getUses() const
InstructionBase(const InstrDesc &D, const unsigned Opcode)
unsigned getNumUsers() const
void setMayLoad(bool newVal)
An instruction propagated through the simulated instruction pipeline.
LLVM_ABI void cycleEvent()
bool isDispatched() const
bool isEliminated() const
Instruction(const InstrDesc &D, const unsigned Opcode)
bool isExecuted() const
uint64_t getCriticalResourceMask() const
unsigned getRCUTokenID() const
LLVM_ABI bool updateDispatched()
const CriticalDependency & getCriticalMemDep() const
const CriticalDependency & getCriticalRegDep() const
bool isExecuting() const
LLVM_ABI void forceExecuted()
int getCyclesLeft() const
void setCriticalResourceMask(uint64_t ResourceMask)
LLVM_ABI const CriticalDependency & computeCriticalRegDep()
LLVM_ABI void execute(unsigned IID)
LLVM_ABI bool updatePending()
void setLSUTokenID(unsigned LSUTok)
void setUsedBuffers(uint64_t Mask)
void setCriticalMemDep(const CriticalDependency &MemDep)
LLVM_ABI void dispatch(unsigned RCUTokenID)
LLVM_ABI void update()
uint64_t getUsedBuffers() const
LLVM_ABI void reset()
unsigned getLSUTokenID() const
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)
uint32_t getSFPImm() const
Definition Instruction.h:85
static MCAOperand createInvalid()
static MCAOperand createDFPImm(uint64_t Val)
static MCAOperand createImm(int64_t Val)
static MCAOperand createReg(unsigned Reg)
Definition Instruction.h:99
unsigned getIndex() const
Definition Instruction.h:97
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 isValid() const
Definition Instruction.h:68
Tracks register operand latency in cycles.
unsigned getRegisterFileID() const
unsigned getSchedClass() const
LLVM_ABI void writeStartEvent(unsigned IID, MCPhysReg RegID, unsigned Cycles)
bool isIndependentFromDef() const
const ReadDescriptor & getDescriptor() const
void setPRF(unsigned ID)
const CriticalDependency & getCriticalRegDep() const
LLVM_ABI void cycleEvent()
void setDependentWrites(unsigned Writes)
bool isReady() const
MCPhysReg getRegisterID() const
bool isImplicitRead() const
ReadState(const ReadDescriptor &Desc, MCPhysReg RegID)
bool isPending() const
bool isReadZero() const
Tracks uses of a register definition (e.g.
unsigned getRegisterFileID() const
bool isEliminated() const
const WriteState * getDependentWrite() const
LLVM_ABI void writeStartEvent(unsigned IID, MCPhysReg RegID, unsigned Cycles)
unsigned getDependentWriteCyclesLeft() const
void setRegisterID(const MCPhysReg RegID)
unsigned getLatency() const
WriteState & operator=(const WriteState &Other)=default
void setPRF(unsigned PRF)
void setDependentWrite(const WriteState *Other)
int getCyclesLeft() const
LLVM_ABI void cycleEvent()
WriteState(const WriteDescriptor &Desc, MCPhysReg RegID, bool clearsSuperRegs=false, bool writesZero=false)
const CriticalDependency & getCriticalRegDep() const
LLVM_ABI void onInstructionIssued(unsigned IID)
WriteState(const WriteState &Other)=default
bool clearsSuperRegisters() const
unsigned getNumUsers() const
MCPhysReg getRegisterID() const
bool isWriteZero() const
bool isExecuted() const
unsigned getWriteResourceID() const
LLVM_ABI void addUser(unsigned IID, ReadState *Use, int ReadAdvance)
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
char InstructionError< T >::ID
Definition Support.h:44
raw_ostream & operator<<(raw_ostream &OS, const InstRef &IR)
constexpr int UNKNOWN_CYCLES
Definition Instruction.h:35
This is an optimization pass for GlobalISel generic memory operations.
Op::Description Desc
CycleInfo::CycleT Cycle
Definition CycleInfo.h:24
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:1734
@ Other
Any other memory.
Definition ModRef.h:68
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
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:1760
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:851
A critical data dependency descriptor.
An instruction descriptor.
SmallVector< WriteDescriptor, 2 > Writes
InstrDesc(const InstrDesc &Other)=delete
SmallVector< std::pair< uint64_t, ResourceUsage >, 4 > Resources
unsigned HasPartiallyOverlappingGroups
SmallVector< ReadDescriptor, 4 > Reads
bool isZeroLatency() const
InstrDesc & operator=(const InstrDesc &Other)=delete
unsigned MustIssueImmediately
A register read descriptor.
ResourceUsage(CycleSegment Cycles, unsigned Units=1)
unsigned size() const
A register write descriptor.