1 //===--------------------- RegisterFile.cpp ---------------------*- 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 #include "RegisterFile.h"
18 #include "Instruction.h"
19 #include "llvm/Support/Debug.h"
23 #define DEBUG_TYPE "llvm-mca"
27 RegisterFile::RegisterFile(const llvm::MCSchedModel &SM,
28 const llvm::MCRegisterInfo &mri, unsigned NumRegs)
29 : MRI(mri), RegisterMappings(mri.getNumRegs(),
30 {WriteRef(), {IndexPlusCostPairTy(0, 1), 0}}) {
31 initialize(SM, NumRegs);
34 void RegisterFile::initialize(const MCSchedModel &SM, unsigned NumRegs) {
35 // Create a default register file that "sees" all the machine registers
36 // declared by the target. The number of physical registers in the default
37 // register file is set equal to `NumRegs`. A value of zero for `NumRegs`
38 // means: this register file has an unbounded number of physical registers.
39 addRegisterFile({} /* all registers */, NumRegs);
40 if (!SM.hasExtraProcessorInfo())
43 // For each user defined register file, allocate a RegisterMappingTracker
44 // object. The size of every register file, as well as the mapping between
45 // register files and register classes is specified via tablegen.
46 const MCExtraProcessorInfo &Info = SM.getExtraProcessorInfo();
47 for (unsigned I = 0, E = Info.NumRegisterFiles; I < E; ++I) {
48 const MCRegisterFileDesc &RF = Info.RegisterFiles[I];
49 // Skip invalid register files with zero physical registers.
50 unsigned Length = RF.NumRegisterCostEntries;
53 // The cost of a register definition is equivalent to the number of
54 // physical registers that are allocated at register renaming stage.
55 const MCRegisterCostEntry *FirstElt =
56 &Info.RegisterCostTable[RF.RegisterCostEntryIdx];
57 addRegisterFile(ArrayRef<MCRegisterCostEntry>(FirstElt, Length),
62 void RegisterFile::addRegisterFile(ArrayRef<MCRegisterCostEntry> Entries,
63 unsigned NumPhysRegs) {
64 // A default register file is always allocated at index #0. That register file
65 // is mainly used to count the total number of mappings created by all
66 // register files at runtime. Users can limit the number of available physical
67 // registers in register file #0 through the command line flag
68 // `-register-file-size`.
69 unsigned RegisterFileIndex = RegisterFiles.size();
70 RegisterFiles.emplace_back(NumPhysRegs);
72 // Special case where there is no register class identifier in the set.
73 // An empty set of register classes means: this register file contains all
74 // the physical registers specified by the target.
75 // We optimistically assume that a register can be renamed at the cost of a
76 // single physical register. The constructor of RegisterFile ensures that
77 // a RegisterMapping exists for each logical register defined by the Target.
81 // Now update the cost of individual registers.
82 for (const MCRegisterCostEntry &RCE : Entries) {
83 const MCRegisterClass &RC = MRI.getRegClass(RCE.RegisterClassID);
84 for (const MCPhysReg Reg : RC) {
85 RegisterRenamingInfo &Entry = RegisterMappings[Reg].second;
86 IndexPlusCostPairTy &IPC = Entry.IndexPlusCost;
87 if (IPC.first && IPC.first != RegisterFileIndex) {
88 // The only register file that is allowed to overlap is the default
89 // register file at index #0. The analysis is inaccurate if register
91 errs() << "warning: register " << MRI.getName(Reg)
92 << " defined in multiple register files.";
94 IPC = std::make_pair(RegisterFileIndex, RCE.Cost);
97 // Assume the same cost for each sub-register.
98 for (MCSubRegIterator I(Reg, &MRI); I.isValid(); ++I) {
99 RegisterRenamingInfo &OtherEntry = RegisterMappings[*I].second;
100 if (!OtherEntry.IndexPlusCost.first &&
101 (!OtherEntry.RenameAs ||
102 MRI.isSuperRegister(*I, OtherEntry.RenameAs))) {
103 OtherEntry.IndexPlusCost = IPC;
104 OtherEntry.RenameAs = Reg;
111 void RegisterFile::allocatePhysRegs(const RegisterRenamingInfo &Entry,
112 MutableArrayRef<unsigned> UsedPhysRegs) {
113 unsigned RegisterFileIndex = Entry.IndexPlusCost.first;
114 unsigned Cost = Entry.IndexPlusCost.second;
115 if (RegisterFileIndex) {
116 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
117 RMT.NumUsedPhysRegs += Cost;
118 UsedPhysRegs[RegisterFileIndex] += Cost;
121 // Now update the default register mapping tracker.
122 RegisterFiles[0].NumUsedPhysRegs += Cost;
123 UsedPhysRegs[0] += Cost;
126 void RegisterFile::freePhysRegs(const RegisterRenamingInfo &Entry,
127 MutableArrayRef<unsigned> FreedPhysRegs) {
128 unsigned RegisterFileIndex = Entry.IndexPlusCost.first;
129 unsigned Cost = Entry.IndexPlusCost.second;
130 if (RegisterFileIndex) {
131 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
132 RMT.NumUsedPhysRegs -= Cost;
133 FreedPhysRegs[RegisterFileIndex] += Cost;
136 // Now update the default register mapping tracker.
137 RegisterFiles[0].NumUsedPhysRegs -= Cost;
138 FreedPhysRegs[0] += Cost;
141 void RegisterFile::addRegisterWrite(WriteRef Write,
142 MutableArrayRef<unsigned> UsedPhysRegs,
143 bool ShouldAllocatePhysRegs) {
144 WriteState &WS = *Write.getWriteState();
145 unsigned RegID = WS.getRegisterID();
146 assert(RegID && "Adding an invalid register definition?");
149 dbgs() << "RegisterFile: addRegisterWrite [ " << Write.getSourceIndex()
150 << ", " << MRI.getName(RegID) << "]\n";
153 // If RenameAs is equal to RegID, then RegID is subject to register renaming
154 // and false dependencies on RegID are all eliminated.
156 // If RenameAs references the invalid register, then we optimistically assume
157 // that it can be renamed. In the absence of tablegen descriptors for register
158 // files, RenameAs is always set to the invalid register ID. In all other
159 // cases, RenameAs must be either equal to RegID, or it must reference a
160 // super-register of RegID.
162 // If RenameAs is a super-register of RegID, then a write to RegID has always
163 // a false dependency on RenameAs. The only exception is for when the write
164 // implicitly clears the upper portion of the underlying register.
165 // If a write clears its super-registers, then it is renamed as `RenameAs`.
166 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
167 if (RRI.RenameAs && RRI.RenameAs != RegID) {
168 RegID = RRI.RenameAs;
169 const WriteRef &OtherWrite = RegisterMappings[RegID].first;
171 if (!WS.clearsSuperRegisters()) {
172 // The processor keeps the definition of `RegID` together with register
173 // `RenameAs`. Since this partial write is not renamed, no physical
174 // register is allocated.
175 ShouldAllocatePhysRegs = false;
177 if (OtherWrite.getSourceIndex() != Write.getSourceIndex()) {
178 // This partial write has a false dependency on RenameAs.
179 WS.setDependentWrite(OtherWrite.getWriteState());
184 // Update the mapping for register RegID including its sub-registers.
185 RegisterMappings[RegID].first = Write;
186 for (MCSubRegIterator I(RegID, &MRI); I.isValid(); ++I)
187 RegisterMappings[*I].first = Write;
189 // No physical registers are allocated for instructions that are optimized in
190 // hardware. For example, zero-latency data-dependency breaking instructions
191 // don't consume physical registers.
192 if (ShouldAllocatePhysRegs)
193 allocatePhysRegs(RegisterMappings[RegID].second, UsedPhysRegs);
195 if (!WS.clearsSuperRegisters())
198 for (MCSuperRegIterator I(RegID, &MRI); I.isValid(); ++I)
199 RegisterMappings[*I].first = Write;
202 void RegisterFile::removeRegisterWrite(const WriteState &WS,
203 MutableArrayRef<unsigned> FreedPhysRegs,
204 bool ShouldFreePhysRegs) {
205 unsigned RegID = WS.getRegisterID();
207 assert(RegID != 0 && "Invalidating an already invalid register?");
208 assert(WS.getCyclesLeft() != UNKNOWN_CYCLES &&
209 "Invalidating a write of unknown cycles!");
210 assert(WS.getCyclesLeft() <= 0 && "Invalid cycles left for this write!");
212 unsigned RenameAs = RegisterMappings[RegID].second.RenameAs;
213 if (RenameAs && RenameAs != RegID) {
216 if (!WS.clearsSuperRegisters()) {
217 // Keep the definition of `RegID` together with register `RenameAs`.
218 ShouldFreePhysRegs = false;
222 if (ShouldFreePhysRegs)
223 freePhysRegs(RegisterMappings[RegID].second, FreedPhysRegs);
225 WriteRef &WR = RegisterMappings[RegID].first;
226 if (WR.getWriteState() == &WS)
229 for (MCSubRegIterator I(RegID, &MRI); I.isValid(); ++I) {
230 WriteRef &OtherWR = RegisterMappings[*I].first;
231 if (OtherWR.getWriteState() == &WS)
232 OtherWR.invalidate();
235 if (!WS.clearsSuperRegisters())
238 for (MCSuperRegIterator I(RegID, &MRI); I.isValid(); ++I) {
239 WriteRef &OtherWR = RegisterMappings[*I].first;
240 if (OtherWR.getWriteState() == &WS)
241 OtherWR.invalidate();
245 void RegisterFile::collectWrites(SmallVectorImpl<WriteRef> &Writes,
246 unsigned RegID) const {
247 assert(RegID && RegID < RegisterMappings.size());
248 LLVM_DEBUG(dbgs() << "RegisterFile: collecting writes for register "
249 << MRI.getName(RegID) << '\n');
250 const WriteRef &WR = RegisterMappings[RegID].first;
252 Writes.push_back(WR);
254 // Handle potential partial register updates.
255 for (MCSubRegIterator I(RegID, &MRI); I.isValid(); ++I) {
256 const WriteRef &WR = RegisterMappings[*I].first;
258 Writes.push_back(WR);
261 // Remove duplicate entries and resize the input vector.
262 llvm::sort(Writes.begin(), Writes.end(),
263 [](const WriteRef &Lhs, const WriteRef &Rhs) {
264 return Lhs.getWriteState() < Rhs.getWriteState();
266 auto It = std::unique(Writes.begin(), Writes.end());
267 Writes.resize(std::distance(Writes.begin(), It));
270 for (const WriteRef &WR : Writes) {
271 const WriteState &WS = *WR.getWriteState();
272 dbgs() << "[PRF] Found a dependent use of Register "
273 << MRI.getName(WS.getRegisterID()) << " (defined by intruction #"
274 << WR.getSourceIndex() << ")\n";
279 unsigned RegisterFile::isAvailable(ArrayRef<unsigned> Regs) const {
280 SmallVector<unsigned, 4> NumPhysRegs(getNumRegisterFiles());
282 // Find how many new mappings must be created for each register file.
283 for (const unsigned RegID : Regs) {
284 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
285 const IndexPlusCostPairTy &Entry = RRI.IndexPlusCost;
287 NumPhysRegs[Entry.first] += Entry.second;
288 NumPhysRegs[0] += Entry.second;
291 unsigned Response = 0;
292 for (unsigned I = 0, E = getNumRegisterFiles(); I < E; ++I) {
293 unsigned NumRegs = NumPhysRegs[I];
297 const RegisterMappingTracker &RMT = RegisterFiles[I];
298 if (!RMT.NumPhysRegs) {
299 // The register file has an unbounded number of microarchitectural
304 if (RMT.NumPhysRegs < NumRegs) {
305 // The current register file is too small. This may occur if the number of
306 // microarchitectural registers in register file #0 was changed by the
307 // users via flag -reg-file-size. Alternatively, the scheduling model
308 // specified a too small number of registers for this register file.
310 "Not enough microarchitectural registers in the register file");
313 if (RMT.NumPhysRegs < (RMT.NumUsedPhysRegs + NumRegs))
314 Response |= (1U << I);
321 void RegisterFile::dump() const {
322 for (unsigned I = 0, E = MRI.getNumRegs(); I < E; ++I) {
323 const RegisterMapping &RM = RegisterMappings[I];
324 if (!RM.first.getWriteState())
326 const RegisterRenamingInfo &RRI = RM.second;
327 dbgs() << MRI.getName(I) << ", " << I << ", PRF=" << RRI.IndexPlusCost.first
328 << ", Cost=" << RRI.IndexPlusCost.second
329 << ", RenameAs=" << RRI.RenameAs << ", ";
334 for (unsigned I = 0, E = getNumRegisterFiles(); I < E; ++I) {
335 dbgs() << "Register File #" << I;
336 const RegisterMappingTracker &RMT = RegisterFiles[I];
337 dbgs() << "\n TotalMappings: " << RMT.NumPhysRegs
338 << "\n NumUsedMappings: " << RMT.NumUsedPhysRegs << '\n';