8
8
// ===----------------------------------------------------------------------===//
9
9
// / \file
10
10
// /
11
- // / This file implements methods declared by class RegisterFile and
12
- // / DispatchUnit.
11
+ // / This file implements methods declared by the DispatchUnit class.
13
12
// /
14
13
// ===----------------------------------------------------------------------===//
15
14
@@ -25,240 +24,6 @@ using namespace llvm;
25
24
26
25
namespace mca {
27
26
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
-
262
27
void DispatchUnit::notifyInstructionDispatched (const InstRef &IR,
263
28
ArrayRef<unsigned > UsedRegs) {
264
29
LLVM_DEBUG (dbgs () << " [E] Instruction Dispatched: " << IR << ' \n ' );
0 commit comments