Skip to content

Commit b7972f8

Browse files
Matt DavisMatt Davis
authored andcommitted
[llvm-mca] Move the RegisterFile class into its own translation unit. NFC
Summary: This change will help us turn the DispatchUnit into its own stage. Reviewers: andreadb, RKSimon, courbet Reviewed By: andreadb, courbet Subscribers: mgorny, tschuett, gbedwell, llvm-commits Differential Revision: https://reviews.llvm.org/D46916 llvm-svn: 332493
1 parent a3c0c9a commit b7972f8

File tree

5 files changed

+428
-371
lines changed

5 files changed

+428
-371
lines changed

llvm/tools/llvm-mca/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ add_llvm_tool(llvm-mca
2323
InstructionTables.cpp
2424
LSUnit.cpp
2525
llvm-mca.cpp
26+
RegisterFile.cpp
2627
RegisterFileStatistics.cpp
2728
ResourcePressureView.cpp
2829
RetireControlUnit.cpp

llvm/tools/llvm-mca/Dispatch.cpp

Lines changed: 1 addition & 236 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
//===----------------------------------------------------------------------===//
99
/// \file
1010
///
11-
/// This file implements methods declared by class RegisterFile and
12-
/// DispatchUnit.
11+
/// This file implements methods declared by the DispatchUnit class.
1312
///
1413
//===----------------------------------------------------------------------===//
1514

@@ -25,240 +24,6 @@ using namespace llvm;
2524

2625
namespace mca {
2726

28-
void RegisterFile::initialize(const MCSchedModel &SM, unsigned NumRegs) {
29-
// Create a default register file that "sees" all the machine registers
30-
// declared by the target. The number of physical registers in the default
31-
// register file is set equal to `NumRegs`. A value of zero for `NumRegs`
32-
// means: this register file has an unbounded number of physical registers.
33-
addRegisterFile({} /* all registers */, NumRegs);
34-
if (!SM.hasExtraProcessorInfo())
35-
return;
36-
37-
// For each user defined register file, allocate a RegisterMappingTracker
38-
// object. The size of every register file, as well as the mapping between
39-
// register files and register classes is specified via tablegen.
40-
const MCExtraProcessorInfo &Info = SM.getExtraProcessorInfo();
41-
for (unsigned I = 0, E = Info.NumRegisterFiles; I < E; ++I) {
42-
const MCRegisterFileDesc &RF = Info.RegisterFiles[I];
43-
// Skip invalid register files with zero physical registers.
44-
unsigned Length = RF.NumRegisterCostEntries;
45-
if (!RF.NumPhysRegs)
46-
continue;
47-
// The cost of a register definition is equivalent to the number of
48-
// physical registers that are allocated at register renaming stage.
49-
const MCRegisterCostEntry *FirstElt =
50-
&Info.RegisterCostTable[RF.RegisterCostEntryIdx];
51-
addRegisterFile(ArrayRef<MCRegisterCostEntry>(FirstElt, Length),
52-
RF.NumPhysRegs);
53-
}
54-
}
55-
56-
void RegisterFile::addRegisterFile(ArrayRef<MCRegisterCostEntry> Entries,
57-
unsigned NumPhysRegs) {
58-
// A default register file is always allocated at index #0. That register file
59-
// is mainly used to count the total number of mappings created by all
60-
// register files at runtime. Users can limit the number of available physical
61-
// registers in register file #0 through the command line flag
62-
// `-register-file-size`.
63-
unsigned RegisterFileIndex = RegisterFiles.size();
64-
RegisterFiles.emplace_back(NumPhysRegs);
65-
66-
// Special case where there is no register class identifier in the set.
67-
// An empty set of register classes means: this register file contains all
68-
// the physical registers specified by the target.
69-
if (Entries.empty()) {
70-
for (std::pair<WriteState *, IndexPlusCostPairTy> &Mapping :
71-
RegisterMappings)
72-
Mapping.second = std::make_pair(RegisterFileIndex, 1U);
73-
return;
74-
}
75-
76-
// Now update the cost of individual registers.
77-
for (const MCRegisterCostEntry &RCE : Entries) {
78-
const MCRegisterClass &RC = MRI.getRegClass(RCE.RegisterClassID);
79-
for (const MCPhysReg Reg : RC) {
80-
IndexPlusCostPairTy &Entry = RegisterMappings[Reg].second;
81-
if (Entry.first) {
82-
// The only register file that is allowed to overlap is the default
83-
// register file at index #0. The analysis is inaccurate if register
84-
// files overlap.
85-
errs() << "warning: register " << MRI.getName(Reg)
86-
<< " defined in multiple register files.";
87-
}
88-
Entry.first = RegisterFileIndex;
89-
Entry.second = RCE.Cost;
90-
}
91-
}
92-
}
93-
94-
void RegisterFile::allocatePhysRegs(IndexPlusCostPairTy Entry,
95-
MutableArrayRef<unsigned> UsedPhysRegs) {
96-
unsigned RegisterFileIndex = Entry.first;
97-
unsigned Cost = Entry.second;
98-
if (RegisterFileIndex) {
99-
RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
100-
RMT.NumUsedMappings += Cost;
101-
UsedPhysRegs[RegisterFileIndex] += Cost;
102-
}
103-
104-
// Now update the default register mapping tracker.
105-
RegisterFiles[0].NumUsedMappings += Cost;
106-
UsedPhysRegs[0] += Cost;
107-
}
108-
109-
void RegisterFile::freePhysRegs(IndexPlusCostPairTy Entry,
110-
MutableArrayRef<unsigned> FreedPhysRegs) {
111-
unsigned RegisterFileIndex = Entry.first;
112-
unsigned Cost = Entry.second;
113-
if (RegisterFileIndex) {
114-
RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
115-
RMT.NumUsedMappings -= Cost;
116-
FreedPhysRegs[RegisterFileIndex] += Cost;
117-
}
118-
119-
// Now update the default register mapping tracker.
120-
RegisterFiles[0].NumUsedMappings -= Cost;
121-
FreedPhysRegs[0] += Cost;
122-
}
123-
124-
void RegisterFile::addRegisterWrite(WriteState &WS,
125-
MutableArrayRef<unsigned> UsedPhysRegs,
126-
bool ShouldAllocatePhysRegs) {
127-
unsigned RegID = WS.getRegisterID();
128-
assert(RegID && "Adding an invalid register definition?");
129-
130-
RegisterMapping &Mapping = RegisterMappings[RegID];
131-
Mapping.first = &WS;
132-
for (MCSubRegIterator I(RegID, &MRI); I.isValid(); ++I)
133-
RegisterMappings[*I].first = &WS;
134-
135-
// No physical registers are allocated for instructions that are optimized in
136-
// hardware. For example, zero-latency data-dependency breaking instructions
137-
// don't consume physical registers.
138-
if (ShouldAllocatePhysRegs)
139-
allocatePhysRegs(Mapping.second, UsedPhysRegs);
140-
141-
// If this is a partial update, then we are done.
142-
if (!WS.fullyUpdatesSuperRegs())
143-
return;
144-
145-
for (MCSuperRegIterator I(RegID, &MRI); I.isValid(); ++I)
146-
RegisterMappings[*I].first = &WS;
147-
}
148-
149-
void RegisterFile::removeRegisterWrite(const WriteState &WS,
150-
MutableArrayRef<unsigned> FreedPhysRegs,
151-
bool ShouldFreePhysRegs) {
152-
unsigned RegID = WS.getRegisterID();
153-
bool ShouldInvalidateSuperRegs = WS.fullyUpdatesSuperRegs();
154-
155-
assert(RegID != 0 && "Invalidating an already invalid register?");
156-
assert(WS.getCyclesLeft() != -512 &&
157-
"Invalidating a write of unknown cycles!");
158-
assert(WS.getCyclesLeft() <= 0 && "Invalid cycles left for this write!");
159-
RegisterMapping &Mapping = RegisterMappings[RegID];
160-
if (!Mapping.first)
161-
return;
162-
163-
if (ShouldFreePhysRegs)
164-
freePhysRegs(Mapping.second, FreedPhysRegs);
165-
166-
if (Mapping.first == &WS)
167-
Mapping.first = nullptr;
168-
169-
for (MCSubRegIterator I(RegID, &MRI); I.isValid(); ++I)
170-
if (RegisterMappings[*I].first == &WS)
171-
RegisterMappings[*I].first = nullptr;
172-
173-
if (!ShouldInvalidateSuperRegs)
174-
return;
175-
176-
for (MCSuperRegIterator I(RegID, &MRI); I.isValid(); ++I)
177-
if (RegisterMappings[*I].first == &WS)
178-
RegisterMappings[*I].first = nullptr;
179-
}
180-
181-
void RegisterFile::collectWrites(SmallVectorImpl<WriteState *> &Writes,
182-
unsigned RegID) const {
183-
assert(RegID && RegID < RegisterMappings.size());
184-
WriteState *WS = RegisterMappings[RegID].first;
185-
if (WS) {
186-
LLVM_DEBUG(dbgs() << "Found a dependent use of RegID=" << RegID << '\n');
187-
Writes.push_back(WS);
188-
}
189-
190-
// Handle potential partial register updates.
191-
for (MCSubRegIterator I(RegID, &MRI); I.isValid(); ++I) {
192-
WS = RegisterMappings[*I].first;
193-
if (WS && std::find(Writes.begin(), Writes.end(), WS) == Writes.end()) {
194-
LLVM_DEBUG(dbgs() << "Found a dependent use of subReg " << *I
195-
<< " (part of " << RegID << ")\n");
196-
Writes.push_back(WS);
197-
}
198-
}
199-
}
200-
201-
unsigned RegisterFile::isAvailable(ArrayRef<unsigned> Regs) const {
202-
SmallVector<unsigned, 4> NumPhysRegs(getNumRegisterFiles());
203-
204-
// Find how many new mappings must be created for each register file.
205-
for (const unsigned RegID : Regs) {
206-
const IndexPlusCostPairTy &Entry = RegisterMappings[RegID].second;
207-
if (Entry.first)
208-
NumPhysRegs[Entry.first] += Entry.second;
209-
NumPhysRegs[0] += Entry.second;
210-
}
211-
212-
unsigned Response = 0;
213-
for (unsigned I = 0, E = getNumRegisterFiles(); I < E; ++I) {
214-
unsigned NumRegs = NumPhysRegs[I];
215-
if (!NumRegs)
216-
continue;
217-
218-
const RegisterMappingTracker &RMT = RegisterFiles[I];
219-
if (!RMT.TotalMappings) {
220-
// The register file has an unbounded number of microarchitectural
221-
// registers.
222-
continue;
223-
}
224-
225-
if (RMT.TotalMappings < NumRegs) {
226-
// The current register file is too small. This may occur if the number of
227-
// microarchitectural registers in register file #0 was changed by the
228-
// users via flag -reg-file-size. Alternatively, the scheduling model
229-
// specified a too small number of registers for this register file.
230-
report_fatal_error(
231-
"Not enough microarchitectural registers in the register file");
232-
}
233-
234-
if (RMT.TotalMappings < (RMT.NumUsedMappings + NumRegs))
235-
Response |= (1U << I);
236-
}
237-
238-
return Response;
239-
}
240-
241-
#ifndef NDEBUG
242-
void RegisterFile::dump() const {
243-
for (unsigned I = 0, E = MRI.getNumRegs(); I < E; ++I) {
244-
const RegisterMapping &RM = RegisterMappings[I];
245-
dbgs() << MRI.getName(I) << ", " << I << ", Map=" << RM.second.first
246-
<< ", ";
247-
if (RM.first)
248-
RM.first->dump();
249-
else
250-
dbgs() << "(null)\n";
251-
}
252-
253-
for (unsigned I = 0, E = getNumRegisterFiles(); I < E; ++I) {
254-
dbgs() << "Register File #" << I;
255-
const RegisterMappingTracker &RMT = RegisterFiles[I];
256-
dbgs() << "\n TotalMappings: " << RMT.TotalMappings
257-
<< "\n NumUsedMappings: " << RMT.NumUsedMappings << '\n';
258-
}
259-
}
260-
#endif
261-
26227
void DispatchUnit::notifyInstructionDispatched(const InstRef &IR,
26328
ArrayRef<unsigned> UsedRegs) {
26429
LLVM_DEBUG(dbgs() << "[E] Instruction Dispatched: " << IR << '\n');

0 commit comments

Comments
 (0)