1 //===--------------------- RegisterFile.h -----------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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.
15 //===----------------------------------------------------------------------===//
17 #ifndef LLVM_TOOLS_LLVM_MCA_REGISTER_FILE_H
18 #define LLVM_TOOLS_LLVM_MCA_REGISTER_FILE_H
20 #include "HardwareUnit.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/MC/MCRegisterInfo.h"
23 #include "llvm/MC/MCSchedule.h"
31 /// Manages hardware register files, and tracks register definitions for
32 /// register renaming purposes.
33 class RegisterFile : public HardwareUnit {
34 const llvm::MCRegisterInfo &MRI;
36 // Each register file is associated with an instance of
37 // RegisterMappingTracker.
38 // A RegisterMappingTracker keeps track of the number of physical registers
39 // which have been dynamically allocated by the simulator.
40 struct RegisterMappingTracker {
41 // The total number of physical registers that are available in this
42 // register file for register renaming purpouses. A value of zero for this
43 // field means: this register file has an unbounded number of physical
45 const unsigned NumPhysRegs;
46 // Number of physical registers that are currently in use.
47 unsigned NumUsedPhysRegs;
49 RegisterMappingTracker(unsigned NumPhysRegisters)
50 : NumPhysRegs(NumPhysRegisters), NumUsedPhysRegs(0) {}
53 // A vector of register file descriptors. This set always contains at least
54 // one entry. Entry at index #0 is reserved. That entry describes a register
55 // file with an unbounded number of physical registers that "sees" all the
56 // hardware registers declared by the target (i.e. all the register
57 // definitions in the target specific `XYZRegisterInfo.td` - where `XYZ` is
60 // Users can limit the number of physical registers that are available in
61 // regsiter file #0 specifying command line flag `-register-file-size=<uint>`.
62 llvm::SmallVector<RegisterMappingTracker, 4> RegisterFiles;
64 // This type is used to propagate information about the owner of a register,
65 // and the cost of allocating it in the PRF. Register cost is defined as the
66 // number of physical registers consumed by the PRF to allocate a user
69 // For example: on X86 BtVer2, a YMM register consumes 2 128-bit physical
70 // registers. So, the cost of allocating a YMM register in BtVer2 is 2.
71 using IndexPlusCostPairTy = std::pair<unsigned, unsigned>;
73 // Struct RegisterRenamingInfo maps registers to register files.
74 // There is a RegisterRenamingInfo object for every register defined by
75 // the target. RegisteRenamingInfo objects are stored into vector
76 // RegisterMappings, and register IDs can be used to reference them.
77 struct RegisterRenamingInfo {
78 IndexPlusCostPairTy IndexPlusCost;
79 llvm::MCPhysReg RenameAs;
82 // RegisterMapping objects are mainly used to track physical register
83 // definitions. There is a RegisterMapping for every register defined by the
84 // Target. For each register, a RegisterMapping pair contains a descriptor of
85 // the last register write (in the form of a WriteRef object), as well as a
86 // RegisterRenamingInfo to quickly identify owning register files.
88 // This implementation does not allow overlapping register files. The only
89 // register file that is allowed to overlap with other register files is
90 // register file #0. If we exclude register #0, every register is "owned" by
91 // at most one register file.
92 using RegisterMapping = std::pair<WriteRef, RegisterRenamingInfo>;
94 // This map contains one entry for each register defined by the target.
95 std::vector<RegisterMapping> RegisterMappings;
97 // This method creates a new register file descriptor.
98 // The new register file owns all of the registers declared by register
99 // classes in the 'RegisterClasses' set.
101 // Processor models allow the definition of RegisterFile(s) via tablegen. For
102 // example, this is a tablegen definition for a x86 register file for
103 // XMM[0-15] and YMM[0-15], that allows up to 60 renames (each rename costs 1
104 // physical register).
106 // def FPRegisterFile : RegisterFile<60, [VR128RegClass, VR256RegClass]>
108 // Here FPRegisterFile contains all the registers defined by register class
109 // VR128RegClass and VR256RegClass. FPRegisterFile implements 60
110 // registers which can be used for register renaming purpose.
112 addRegisterFile(llvm::ArrayRef<llvm::MCRegisterCostEntry> RegisterClasses,
113 unsigned NumPhysRegs);
115 // Consumes physical registers in each register file specified by the
116 // `IndexPlusCostPairTy`. This method is called from `addRegisterMapping()`.
117 void allocatePhysRegs(const RegisterRenamingInfo &Entry,
118 llvm::MutableArrayRef<unsigned> UsedPhysRegs);
120 // Releases previously allocated physical registers from the register file(s).
121 // This method is called from `invalidateRegisterMapping()`.
122 void freePhysRegs(const RegisterRenamingInfo &Entry,
123 llvm::MutableArrayRef<unsigned> FreedPhysRegs);
125 // Create an instance of RegisterMappingTracker for every register file
126 // specified by the processor model.
127 // If no register file is specified, then this method creates a default
128 // register file with an unbounded number of physical registers.
129 void initialize(const llvm::MCSchedModel &SM, unsigned NumRegs);
132 RegisterFile(const llvm::MCSchedModel &SM, const llvm::MCRegisterInfo &mri,
133 unsigned NumRegs = 0);
135 // This method updates the register mappings inserting a new register
136 // definition. This method is also responsible for updating the number of
137 // allocated physical registers in each register file modified by the write.
138 // No physical regiser is allocated when flag ShouldAllocatePhysRegs is set.
139 void addRegisterWrite(WriteRef Write,
140 llvm::MutableArrayRef<unsigned> UsedPhysRegs,
141 bool ShouldAllocatePhysRegs = true);
143 // Removes write \param WS from the register mappings.
144 // Physical registers may be released to reflect this update.
145 void removeRegisterWrite(const WriteState &WS,
146 llvm::MutableArrayRef<unsigned> FreedPhysRegs,
147 bool ShouldFreePhysRegs = true);
149 // Checks if there are enough physical registers in the register files.
150 // Returns a "response mask" where each bit represents the response from a
151 // different register file. A mask of all zeroes means that all register
152 // files are available. Otherwise, the mask can be used to identify which
153 // register file was busy. This sematic allows us to classify dispatch
154 // stalls caused by the lack of register file resources.
156 // Current implementation can simulate up to 32 register files (including the
157 // special register file at index #0).
158 unsigned isAvailable(llvm::ArrayRef<unsigned> Regs) const;
159 void collectWrites(llvm::SmallVectorImpl<WriteRef> &Writes,
160 unsigned RegID) const;
161 void updateOnRead(ReadState &RS, unsigned RegID);
163 unsigned getNumRegisterFiles() const { return RegisterFiles.size(); }
172 #endif // LLVM_TOOLS_LLVM_MCA_REGISTER_FILE_H