LLVM  8.0.1
RegisterFile.h
Go to the documentation of this file.
1 //===--------------------- RegisterFile.h -----------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 ///
11 /// This file defines a register mapping file class. This class is responsible
12 /// for managing hardware register files and the tracking of data dependencies
13 /// between registers.
14 ///
15 //===----------------------------------------------------------------------===//
16 
17 #ifndef LLVM_MCA_REGISTER_FILE_H
18 #define LLVM_MCA_REGISTER_FILE_H
19 
20 #include "llvm/ADT/APInt.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/MC/MCRegisterInfo.h"
23 #include "llvm/MC/MCSchedule.h"
25 #include "llvm/Support/Error.h"
26 
27 namespace llvm {
28 namespace mca {
29 
30 class ReadState;
31 class WriteState;
32 class WriteRef;
33 
34 /// Manages hardware register files, and tracks register definitions for
35 /// register renaming purposes.
36 class RegisterFile : public HardwareUnit {
37  const MCRegisterInfo &MRI;
38 
39  // class RegisterMappingTracker is a physical register file (PRF) descriptor.
40  // There is one RegisterMappingTracker for every PRF definition in the
41  // scheduling model.
42  //
43  // An instance of RegisterMappingTracker tracks the number of physical
44  // registers available for renaming. It also tracks the number of register
45  // moves eliminated per cycle.
46  struct RegisterMappingTracker {
47  // The total number of physical registers that are available in this
48  // register file for register renaming purpouses. A value of zero for this
49  // field means: this register file has an unbounded number of physical
50  // registers.
51  const unsigned NumPhysRegs;
52  // Number of physical registers that are currently in use.
53  unsigned NumUsedPhysRegs;
54 
55  // Maximum number of register moves that can be eliminated by this PRF every
56  // cycle. A value of zero means that there is no limit in the number of
57  // moves which can be eliminated every cycle.
58  const unsigned MaxMoveEliminatedPerCycle;
59 
60  // Number of register moves eliminated during this cycle.
61  //
62  // This value is increased by one every time a register move is eliminated.
63  // Every new cycle, this value is reset to zero.
64  // A move can be eliminated only if MaxMoveEliminatedPerCycle is zero, or if
65  // NumMoveEliminated is less than MaxMoveEliminatedPerCycle.
66  unsigned NumMoveEliminated;
67 
68  // If set, move elimination is restricted to zero-register moves only.
69  bool AllowZeroMoveEliminationOnly;
70 
71  RegisterMappingTracker(unsigned NumPhysRegisters,
72  unsigned MaxMoveEliminated = 0U,
73  bool AllowZeroMoveElimOnly = false)
74  : NumPhysRegs(NumPhysRegisters), NumUsedPhysRegs(0),
75  MaxMoveEliminatedPerCycle(MaxMoveEliminated), NumMoveEliminated(0U),
76  AllowZeroMoveEliminationOnly(AllowZeroMoveElimOnly) {}
77  };
78 
79  // A vector of register file descriptors. This set always contains at least
80  // one entry. Entry at index #0 is reserved. That entry describes a register
81  // file with an unbounded number of physical registers that "sees" all the
82  // hardware registers declared by the target (i.e. all the register
83  // definitions in the target specific `XYZRegisterInfo.td` - where `XYZ` is
84  // the target name).
85  //
86  // Users can limit the number of physical registers that are available in
87  // regsiter file #0 specifying command line flag `-register-file-size=<uint>`.
89 
90  // This type is used to propagate information about the owner of a register,
91  // and the cost of allocating it in the PRF. Register cost is defined as the
92  // number of physical registers consumed by the PRF to allocate a user
93  // register.
94  //
95  // For example: on X86 BtVer2, a YMM register consumes 2 128-bit physical
96  // registers. So, the cost of allocating a YMM register in BtVer2 is 2.
97  using IndexPlusCostPairTy = std::pair<unsigned, unsigned>;
98 
99  // Struct RegisterRenamingInfo is used to map logical registers to register
100  // files.
101  //
102  // There is a RegisterRenamingInfo object for every logical register defined
103  // by the target. RegisteRenamingInfo objects are stored into vector
104  // `RegisterMappings`, and MCPhysReg IDs can be used to reference
105  // elements in that vector.
106  //
107  // Each RegisterRenamingInfo is owned by a PRF, and field `IndexPlusCost`
108  // specifies both the owning PRF, as well as the number of physical registers
109  // consumed at register renaming stage.
110  //
111  // Field `AllowMoveElimination` is set for registers that are used as
112  // destination by optimizable register moves.
113  //
114  // Field `AliasRegID` is set by writes from register moves that have been
115  // eliminated at register renaming stage. A move eliminated at register
116  // renaming stage is effectively bypassed, and its write aliases the source
117  // register definition.
118  struct RegisterRenamingInfo {
119  IndexPlusCostPairTy IndexPlusCost;
120  MCPhysReg RenameAs;
121  MCPhysReg AliasRegID;
122  bool AllowMoveElimination;
123  RegisterRenamingInfo()
124  : IndexPlusCost(std::make_pair(0U, 1U)), RenameAs(0U), AliasRegID(0U),
125  AllowMoveElimination(false) {}
126  };
127 
128  // RegisterMapping objects are mainly used to track physical register
129  // definitions and resolve data dependencies.
130  //
131  // Every register declared by the Target is associated with an instance of
132  // RegisterMapping. RegisterMapping objects keep track of writes to a logical
133  // register. That information is used by class RegisterFile to resolve data
134  // dependencies, and correctly set latencies for register uses.
135  //
136  // This implementation does not allow overlapping register files. The only
137  // register file that is allowed to overlap with other register files is
138  // register file #0. If we exclude register #0, every register is "owned" by
139  // at most one register file.
140  using RegisterMapping = std::pair<WriteRef, RegisterRenamingInfo>;
141 
142  // There is one entry per each register defined by the target.
143  std::vector<RegisterMapping> RegisterMappings;
144 
145  // Used to track zero registers. There is one bit for each register defined by
146  // the target. Bits are set for registers that are known to be zero.
147  APInt ZeroRegisters;
148 
149  // This method creates a new register file descriptor.
150  // The new register file owns all of the registers declared by register
151  // classes in the 'RegisterClasses' set.
152  //
153  // Processor models allow the definition of RegisterFile(s) via tablegen. For
154  // example, this is a tablegen definition for a x86 register file for
155  // XMM[0-15] and YMM[0-15], that allows up to 60 renames (each rename costs 1
156  // physical register).
157  //
158  // def FPRegisterFile : RegisterFile<60, [VR128RegClass, VR256RegClass]>
159  //
160  // Here FPRegisterFile contains all the registers defined by register class
161  // VR128RegClass and VR256RegClass. FPRegisterFile implements 60
162  // registers which can be used for register renaming purpose.
163  void addRegisterFile(const MCRegisterFileDesc &RF,
165 
166  // Consumes physical registers in each register file specified by the
167  // `IndexPlusCostPairTy`. This method is called from `addRegisterMapping()`.
168  void allocatePhysRegs(const RegisterRenamingInfo &Entry,
169  MutableArrayRef<unsigned> UsedPhysRegs);
170 
171  // Releases previously allocated physical registers from the register file(s).
172  // This method is called from `invalidateRegisterMapping()`.
173  void freePhysRegs(const RegisterRenamingInfo &Entry,
174  MutableArrayRef<unsigned> FreedPhysRegs);
175 
176  // Collects writes that are in a RAW dependency with RS.
177  // This method is called from `addRegisterRead()`.
178  void collectWrites(const ReadState &RS,
179  SmallVectorImpl<WriteRef> &Writes) const;
180 
181  // Create an instance of RegisterMappingTracker for every register file
182  // specified by the processor model.
183  // If no register file is specified, then this method creates a default
184  // register file with an unbounded number of physical registers.
185  void initialize(const MCSchedModel &SM, unsigned NumRegs);
186 
187 public:
188  RegisterFile(const MCSchedModel &SM, const MCRegisterInfo &mri,
189  unsigned NumRegs = 0);
190 
191  // This method updates the register mappings inserting a new register
192  // definition. This method is also responsible for updating the number of
193  // allocated physical registers in each register file modified by the write.
194  // No physical regiser is allocated if this write is from a zero-idiom.
195  void addRegisterWrite(WriteRef Write, MutableArrayRef<unsigned> UsedPhysRegs);
196 
197  // Collect writes that are in a data dependency with RS, and update RS
198  // internal state.
199  void addRegisterRead(ReadState &RS, SmallVectorImpl<WriteRef> &Writes) const;
200 
201  // Removes write \param WS from the register mappings.
202  // Physical registers may be released to reflect this update.
203  // No registers are released if this write is from a zero-idiom.
204  void removeRegisterWrite(const WriteState &WS,
205  MutableArrayRef<unsigned> FreedPhysRegs);
206 
207  // Returns true if a move from RS to WS can be eliminated.
208  // On success, it updates WriteState by setting flag `WS.isEliminated`.
209  // If RS is a read from a zero register, and WS is eliminated, then
210  // `WS.WritesZero` is also set, so that method addRegisterWrite() would not
211  // reserve a physical register for it.
212  bool tryEliminateMove(WriteState &WS, ReadState &RS);
213 
214  // Checks if there are enough physical registers in the register files.
215  // Returns a "response mask" where each bit represents the response from a
216  // different register file. A mask of all zeroes means that all register
217  // files are available. Otherwise, the mask can be used to identify which
218  // register file was busy. This sematic allows us to classify dispatch
219  // stalls caused by the lack of register file resources.
220  //
221  // Current implementation can simulate up to 32 register files (including the
222  // special register file at index #0).
223  unsigned isAvailable(ArrayRef<unsigned> Regs) const;
224 
225  // Returns the number of PRFs implemented by this processor.
226  unsigned getNumRegisterFiles() const { return RegisterFiles.size(); }
227 
228  // Notify each PRF that a new cycle just started.
229  void cycleStart();
230 
231 #ifndef NDEBUG
232  void dump() const;
233 #endif
234 };
235 
236 } // namespace mca
237 } // namespace llvm
238 
239 #endif // LLVM_MCA_REGISTER_FILE_H
This class represents lattice values for constants.
Definition: AllocatorList.h:24
void addRegisterWrite(WriteRef Write, MutableArrayRef< unsigned > UsedPhysRegs)
unsigned getNumRegisterFiles() const
Definition: RegisterFile.h:226
Tracks register operand latency in cycles.
Definition: Instruction.h:205
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
A register file descriptor.
Definition: MCSchedule.h:157
This file implements a class to represent arbitrary precision integral constant values and operations...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:291
unsigned isAvailable(ArrayRef< unsigned > Regs) const
Manages hardware register files, and tracks register definitions for register renaming purposes...
Definition: RegisterFile.h:36
RegisterFile(const MCSchedModel &SM, const MCRegisterInfo &mri, unsigned NumRegs=0)
This file defines a base class for describing a simulated hardware unit.
size_t size() const
Definition: SmallVector.h:53
void removeRegisterWrite(const WriteState &WS, MutableArrayRef< unsigned > FreedPhysRegs)
Tracks uses of a register definition (e.g.
Definition: Instruction.h:90
A reference to a register write.
Definition: Instruction.h:514
Class for arbitrary precision integers.
Definition: APInt.h:70
bool tryEliminateMove(WriteState &WS, ReadState &RS)
void addRegisterRead(ReadState &RS, SmallVectorImpl< WriteRef > &Writes) const
Machine model for scheduling, bundling, and heuristics.
Definition: MCSchedule.h:244