]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/MCA/HardwareUnits/RegisterFile.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / MCA / HardwareUnits / RegisterFile.h
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"
24 #include "llvm/MCA/HardwareUnits/HardwareUnit.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>`.
88   SmallVector<RegisterMappingTracker, 4> RegisterFiles;
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,
164                        ArrayRef<MCRegisterCostEntry> Entries);
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