LLVM  14.0.0git
RegisterFile.h
Go to the documentation of this file.
1 //===--------------------- RegisterFile.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 a register mapping file class. This class is responsible
11 /// for managing hardware register files and the tracking of data dependencies
12 /// between registers.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_MCA_HARDWAREUNITS_REGISTERFILE_H
17 #define LLVM_MCA_HARDWAREUNITS_REGISTERFILE_H
18 
19 #include "llvm/ADT/APInt.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/MC/MCSchedule.h"
25 
26 namespace llvm {
27 namespace mca {
28 
29 class ReadState;
30 class WriteState;
31 class Instruction;
32 
33 /// A reference to a register write.
34 ///
35 /// This class is mainly used by the register file to describe register
36 /// mappings. It correlates a register write to the source index of the
37 /// defining instruction.
38 class WriteRef {
39  unsigned IID;
40  unsigned WriteBackCycle;
41  unsigned WriteResID;
42  MCPhysReg RegisterID;
43  WriteState *Write;
44 
45  static const unsigned INVALID_IID;
46 
47 public:
49  : IID(INVALID_IID), WriteBackCycle(), WriteResID(), RegisterID(),
50  Write() {}
51  WriteRef(unsigned SourceIndex, WriteState *WS);
52 
53  unsigned getSourceIndex() const { return IID; }
54  unsigned getWriteBackCycle() const;
55 
56  const WriteState *getWriteState() const { return Write; }
57  WriteState *getWriteState() { return Write; }
58  unsigned getWriteResourceID() const;
59  MCPhysReg getRegisterID() const;
60 
61  void commit();
62  void notifyExecuted(unsigned Cycle);
63 
64  bool hasKnownWriteBackCycle() const;
65  bool isWriteZero() const;
66  bool isValid() const { return getSourceIndex() != INVALID_IID; }
67 
68  /// Returns true if this register write has been executed, and the new
69  /// register value is therefore available to users.
70  bool isAvailable() const { return hasKnownWriteBackCycle(); }
71 
72  bool operator==(const WriteRef &Other) const {
73  return Write && Other.Write && Write == Other.Write;
74  }
75 
76 #ifndef NDEBUG
77  void dump() const;
78 #endif
79 };
80 
81 /// Manages hardware register files, and tracks register definitions for
82 /// register renaming purposes.
83 class RegisterFile : public HardwareUnit {
84  const MCRegisterInfo &MRI;
85 
86  // class RegisterMappingTracker is a physical register file (PRF) descriptor.
87  // There is one RegisterMappingTracker for every PRF definition in the
88  // scheduling model.
89  //
90  // An instance of RegisterMappingTracker tracks the number of physical
91  // registers available for renaming. It also tracks the number of register
92  // moves eliminated per cycle.
93  struct RegisterMappingTracker {
94  // The total number of physical registers that are available in this
95  // register file for register renaming purpouses. A value of zero for this
96  // field means: this register file has an unbounded number of physical
97  // registers.
98  const unsigned NumPhysRegs;
99  // Number of physical registers that are currently in use.
100  unsigned NumUsedPhysRegs;
101 
102  // Maximum number of register moves that can be eliminated by this PRF every
103  // cycle. A value of zero means that there is no limit in the number of
104  // moves which can be eliminated every cycle.
105  const unsigned MaxMoveEliminatedPerCycle;
106 
107  // Number of register moves eliminated during this cycle.
108  //
109  // This value is increased by one every time a register move is eliminated.
110  // Every new cycle, this value is reset to zero.
111  // A move can be eliminated only if MaxMoveEliminatedPerCycle is zero, or if
112  // NumMoveEliminated is less than MaxMoveEliminatedPerCycle.
113  unsigned NumMoveEliminated;
114 
115  // If set, move elimination is restricted to zero-register moves only.
116  bool AllowZeroMoveEliminationOnly;
117 
118  RegisterMappingTracker(unsigned NumPhysRegisters,
119  unsigned MaxMoveEliminated = 0U,
120  bool AllowZeroMoveElimOnly = false)
121  : NumPhysRegs(NumPhysRegisters), NumUsedPhysRegs(0),
122  MaxMoveEliminatedPerCycle(MaxMoveEliminated), NumMoveEliminated(0U),
123  AllowZeroMoveEliminationOnly(AllowZeroMoveElimOnly) {}
124  };
125 
126  // A vector of register file descriptors. This set always contains at least
127  // one entry. Entry at index #0 is reserved. That entry describes a register
128  // file with an unbounded number of physical registers that "sees" all the
129  // hardware registers declared by the target (i.e. all the register
130  // definitions in the target specific `XYZRegisterInfo.td` - where `XYZ` is
131  // the target name).
132  //
133  // Users can limit the number of physical registers that are available in
134  // register file #0 specifying command line flag `-register-file-size=<uint>`.
136 
137  // This type is used to propagate information about the owner of a register,
138  // and the cost of allocating it in the PRF. Register cost is defined as the
139  // number of physical registers consumed by the PRF to allocate a user
140  // register.
141  //
142  // For example: on X86 BtVer2, a YMM register consumes 2 128-bit physical
143  // registers. So, the cost of allocating a YMM register in BtVer2 is 2.
144  using IndexPlusCostPairTy = std::pair<unsigned, unsigned>;
145 
146  // Struct RegisterRenamingInfo is used to map logical registers to register
147  // files.
148  //
149  // There is a RegisterRenamingInfo object for every logical register defined
150  // by the target. RegisteRenamingInfo objects are stored into vector
151  // `RegisterMappings`, and MCPhysReg IDs can be used to reference
152  // elements in that vector.
153  //
154  // Each RegisterRenamingInfo is owned by a PRF, and field `IndexPlusCost`
155  // specifies both the owning PRF, as well as the number of physical registers
156  // consumed at register renaming stage.
157  //
158  // Field `AllowMoveElimination` is set for registers that are used as
159  // destination by optimizable register moves.
160  //
161  // Field `AliasRegID` is set by writes from register moves that have been
162  // eliminated at register renaming stage. A move eliminated at register
163  // renaming stage is effectively bypassed, and its write aliases the source
164  // register definition.
165  struct RegisterRenamingInfo {
166  IndexPlusCostPairTy IndexPlusCost;
167  MCPhysReg RenameAs;
168  MCPhysReg AliasRegID;
169  bool AllowMoveElimination;
170  RegisterRenamingInfo()
171  : IndexPlusCost(std::make_pair(0U, 1U)), RenameAs(0U), AliasRegID(0U),
172  AllowMoveElimination(false) {}
173  };
174 
175  // RegisterMapping objects are mainly used to track physical register
176  // definitions and resolve data dependencies.
177  //
178  // Every register declared by the Target is associated with an instance of
179  // RegisterMapping. RegisterMapping objects keep track of writes to a logical
180  // register. That information is used by class RegisterFile to resolve data
181  // dependencies, and correctly set latencies for register uses.
182  //
183  // This implementation does not allow overlapping register files. The only
184  // register file that is allowed to overlap with other register files is
185  // register file #0. If we exclude register #0, every register is "owned" by
186  // at most one register file.
187  using RegisterMapping = std::pair<WriteRef, RegisterRenamingInfo>;
188 
189  // There is one entry per each register defined by the target.
190  std::vector<RegisterMapping> RegisterMappings;
191 
192  // Used to track zero registers. There is one bit for each register defined by
193  // the target. Bits are set for registers that are known to be zero.
194  APInt ZeroRegisters;
195 
196  unsigned CurrentCycle;
197 
198  // This method creates a new register file descriptor.
199  // The new register file owns all of the registers declared by register
200  // classes in the 'RegisterClasses' set.
201  //
202  // Processor models allow the definition of RegisterFile(s) via tablegen. For
203  // example, this is a tablegen definition for a x86 register file for
204  // XMM[0-15] and YMM[0-15], that allows up to 60 renames (each rename costs 1
205  // physical register).
206  //
207  // def FPRegisterFile : RegisterFile<60, [VR128RegClass, VR256RegClass]>
208  //
209  // Here FPRegisterFile contains all the registers defined by register class
210  // VR128RegClass and VR256RegClass. FPRegisterFile implements 60
211  // registers which can be used for register renaming purpose.
212  void addRegisterFile(const MCRegisterFileDesc &RF,
214 
215  // Consumes physical registers in each register file specified by the
216  // `IndexPlusCostPairTy`. This method is called from `addRegisterMapping()`.
217  void allocatePhysRegs(const RegisterRenamingInfo &Entry,
218  MutableArrayRef<unsigned> UsedPhysRegs);
219 
220  // Releases previously allocated physical registers from the register file(s).
221  // This method is called from `invalidateRegisterMapping()`.
222  void freePhysRegs(const RegisterRenamingInfo &Entry,
223  MutableArrayRef<unsigned> FreedPhysRegs);
224 
225  // Create an instance of RegisterMappingTracker for every register file
226  // specified by the processor model.
227  // If no register file is specified, then this method creates a default
228  // register file with an unbounded number of physical registers.
229  void initialize(const MCSchedModel &SM, unsigned NumRegs);
230 
231 public:
232  RegisterFile(const MCSchedModel &SM, const MCRegisterInfo &mri,
233  unsigned NumRegs = 0);
234 
235  // Collects writes that are in a RAW dependency with RS.
236  void collectWrites(const MCSubtargetInfo &STI, const ReadState &RS,
238  SmallVectorImpl<WriteRef> &CommittedWrites) const;
239  struct RAWHazard {
242 
244  bool isValid() const { return RegisterID; }
245  bool hasUnknownCycles() const { return CyclesLeft < 0; }
246  };
247 
248  RAWHazard checkRAWHazards(const MCSubtargetInfo &STI,
249  const ReadState &RS) const;
250 
251  // This method updates the register mappings inserting a new register
252  // definition. This method is also responsible for updating the number of
253  // allocated physical registers in each register file modified by the write.
254  // No physical regiser is allocated if this write is from a zero-idiom.
255  void addRegisterWrite(WriteRef Write, MutableArrayRef<unsigned> UsedPhysRegs);
256 
257  // Collect writes that are in a data dependency with RS, and update RS
258  // internal state.
259  void addRegisterRead(ReadState &RS, const MCSubtargetInfo &STI) const;
260 
261  // Removes write \param WS from the register mappings.
262  // Physical registers may be released to reflect this update.
263  // No registers are released if this write is from a zero-idiom.
264  void removeRegisterWrite(const WriteState &WS,
265  MutableArrayRef<unsigned> FreedPhysRegs);
266 
267  // Returns true if the PRF at index `PRFIndex` can eliminate a move from RS to
268  // WS.
269  bool canEliminateMove(const WriteState &WS, const ReadState &RS,
270  unsigned PRFIndex) const;
271 
272  // Returns true if this instruction can be fully eliminated at register
273  // renaming stage. On success, this method updates the internal state of each
274  // WriteState by setting flag `WS.isEliminated`, and by propagating the zero
275  // flag for known zero registers. It internally uses `canEliminateMove` to
276  // determine if a read/write pair can be eliminated. By default, it assumes a
277  // register swap if there is more than one register definition.
280 
281  // Checks if there are enough physical registers in the register files.
282  // Returns a "response mask" where each bit represents the response from a
283  // different register file. A mask of all zeroes means that all register
284  // files are available. Otherwise, the mask can be used to identify which
285  // register file was busy. This sematic allows us to classify dispatch
286  // stalls caused by the lack of register file resources.
287  //
288  // Current implementation can simulate up to 32 register files (including the
289  // special register file at index #0).
290  unsigned isAvailable(ArrayRef<MCPhysReg> Regs) const;
291 
292  // Returns the number of PRFs implemented by this processor.
293  unsigned getNumRegisterFiles() const { return RegisterFiles.size(); }
294 
295  unsigned getElapsedCyclesFromWriteBack(const WriteRef &WR) const;
296 
298 
299  // Notify each PRF that a new cycle just started.
300  void cycleStart();
301 
302  void cycleEnd() { ++CurrentCycle; }
303 
304 #ifndef NDEBUG
305  void dump() const;
306 #endif
307 };
308 
309 } // namespace mca
310 } // namespace llvm
311 
312 #endif // LLVM_MCA_HARDWAREUNITS_REGISTERFILE_H
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::mca::RegisterFile::getElapsedCyclesFromWriteBack
unsigned getElapsedCyclesFromWriteBack(const WriteRef &WR) const
Definition: RegisterFile.cpp:497
llvm::mca::RegisterFile::tryEliminateMoveOrSwap
bool tryEliminateMoveOrSwap(MutableArrayRef< WriteState > Writes, MutableArrayRef< ReadState > Reads)
Definition: RegisterFile.cpp:426
llvm::mca::RegisterFile::removeRegisterWrite
void removeRegisterWrite(const WriteState &WS, MutableArrayRef< unsigned > FreedPhysRegs)
Definition: RegisterFile.cpp:332
llvm::SmallVector< RegisterMappingTracker, 4 >
llvm::mca::RegisterFile::checkRAWHazards
RAWHazard checkRAWHazards(const MCSubtargetInfo &STI, const ReadState &RS) const
Definition: RegisterFile.cpp:568
llvm::mca::WriteRef::getWriteState
const WriteState * getWriteState() const
Definition: RegisterFile.h:56
llvm::mca::RegisterFile::RAWHazard::CyclesLeft
int CyclesLeft
Definition: RegisterFile.h:241
APInt.h
llvm::mca::WriteRef::getRegisterID
MCPhysReg getRegisterID() const
Definition: RegisterFile.cpp:58
llvm::mca::WriteRef::getWriteState
WriteState * getWriteState()
Definition: RegisterFile.h:57
llvm::mca::Instruction
An instruction propagated through the simulated instruction pipeline.
Definition: Instruction.h:569
llvm::MCRegisterFileDesc
A register file descriptor.
Definition: MCSchedule.h:158
llvm::mca::RegisterFile::RAWHazard
Definition: RegisterFile.h:239
llvm::mca::WriteRef::getSourceIndex
unsigned getSourceIndex() const
Definition: RegisterFile.h:53
llvm::mca::RegisterFile::cycleStart
void cycleStart()
Definition: RegisterFile.cpp:100
llvm::mca::RegisterFile::getNumRegisterFiles
unsigned getNumRegisterFiles() const
Definition: RegisterFile.h:293
llvm::mca::RegisterFile::RAWHazard::hasUnknownCycles
bool hasUnknownCycles() const
Definition: RegisterFile.h:245
llvm::mca::RegisterFile::RAWHazard::RAWHazard
RAWHazard()
Definition: RegisterFile.h:243
llvm::mca::WriteRef::operator==
bool operator==(const WriteRef &Other) const
Definition: RegisterFile.h:72
llvm::mca::RegisterFile::isAvailable
unsigned isAvailable(ArrayRef< MCPhysReg > Regs) const
Definition: RegisterFile.cpp:660
llvm::MutableArrayRef
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:307
llvm::mca::RegisterFile::cycleEnd
void cycleEnd()
Definition: RegisterFile.h:302
MCSubtargetInfo.h
llvm::mca::ReadState
Tracks register operand latency in cycles.
Definition: Instruction.h:326
HardwareUnit.h
llvm::mca::RegisterFile::RegisterFile
RegisterFile(const MCSchedModel &SM, const MCRegisterInfo &mri, unsigned NumRegs=0)
Definition: RegisterFile.cpp:64
llvm::mca::WriteRef
A reference to a register write.
Definition: RegisterFile.h:38
llvm::mca::WriteRef::getWriteBackCycle
unsigned getWriteBackCycle() const
Definition: RegisterFile.cpp:490
llvm::mca::RegisterFile::RAWHazard::isValid
bool isValid() const
Definition: RegisterFile.h:244
llvm::mca::RegisterFile::canEliminateMove
bool canEliminateMove(const WriteState &WS, const ReadState &RS, unsigned PRFIndex) const
Definition: RegisterFile.cpp:384
llvm::mca::WriteRef::isWriteZero
bool isWriteZero() const
Definition: RegisterFile.cpp:47
MCSchedule.h
llvm::mca::WriteRef::hasKnownWriteBackCycle
bool hasKnownWriteBackCycle() const
Definition: RegisterFile.cpp:43
llvm::MCPhysReg
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition: MCRegister.h:20
MCRegisterInfo.h
llvm::mca::WriteRef::isAvailable
bool isAvailable() const
Returns true if this register write has been executed, and the new register value is therefore availa...
Definition: RegisterFile.h:70
llvm::mca::WriteRef::WriteRef
WriteRef()
Definition: RegisterFile.h:48
llvm::APInt
Class for arbitrary precision integers.
Definition: APInt.h:75
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::mca::RegisterFile::RAWHazard::RegisterID
MCPhysReg RegisterID
Definition: RegisterFile.h:240
llvm::mca::WriteRef::getWriteResourceID
unsigned getWriteResourceID() const
Definition: RegisterFile.cpp:52
llvm::mca::RegisterFile::onInstructionExecuted
void onInstructionExecuted(Instruction *IS)
Definition: RegisterFile.cpp:105
llvm::MCRegisterInfo
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Definition: MCRegisterInfo.h:135
llvm::mca::RegisterFile::addRegisterRead
void addRegisterRead(ReadState &RS, const MCSubtargetInfo &STI) const
Definition: RegisterFile.cpp:618
llvm::mca::RegisterFile
Manages hardware register files, and tracks register definitions for register renaming purposes.
Definition: RegisterFile.h:83
uint16_t
llvm::mca::HardwareUnit
Definition: HardwareUnit.h:21
llvm::mca::RegisterFile::collectWrites
void collectWrites(const MCSubtargetInfo &STI, const ReadState &RS, SmallVectorImpl< WriteRef > &Writes, SmallVectorImpl< WriteRef > &CommittedWrites) const
Definition: RegisterFile.cpp:502
llvm::mca::WriteRef::dump
void dump() const
Definition: RegisterFile.cpp:709
llvm::mca::RegisterFile::addRegisterWrite
void addRegisterWrite(WriteRef Write, MutableArrayRef< unsigned > UsedPhysRegs)
Definition: RegisterFile.cpp:228
llvm::mca::WriteRef::isValid
bool isValid() const
Definition: RegisterFile.h:66
llvm::MCSchedModel
Machine model for scheduling, bundling, and heuristics.
Definition: MCSchedule.h:245
SmallVector.h
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75
llvm::mca::WriteState
Tracks uses of a register definition (e.g.
Definition: Instruction.h:197
llvm::mca::WriteRef::notifyExecuted
void notifyExecuted(unsigned Cycle)
Definition: RegisterFile.cpp:38
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1172
llvm::mca::RegisterFile::dump
void dump() const
Definition: RegisterFile.cpp:717
llvm::mca::WriteRef::commit
void commit()
Definition: RegisterFile.cpp:31