20 #define DEBUG_TYPE "llvm-mca"
28 : IID(SourceIndex), WriteBackCycle(), WriteResID(), RegisterID(),
40 WriteBackCycle =
Cycle;
67 RegisterMappings(mri.getNumRegs(), {
WriteRef(), RegisterRenamingInfo()}),
68 ZeroRegisters(mri.getNumRegs(),
false), CurrentCycle() {
69 initialize(SM, NumRegs);
72 void RegisterFile::initialize(
const MCSchedModel &SM,
unsigned NumRegs) {
87 for (
unsigned I = 1,
E =
Info.NumRegisterFiles;
I <
E; ++
I) {
101 for (RegisterMappingTracker &RMT : RegisterFiles)
102 RMT.NumMoveEliminated = 0;
108 if (WS.isEliminated())
119 "The number of cycles should be known at this point!");
120 assert(WS.getCyclesLeft() <= 0 &&
"Invalid cycles left for this write!");
122 MCPhysReg RenameAs = RegisterMappings[RegID].second.RenameAs;
123 if (RenameAs && RenameAs != RegID)
126 WriteRef &WR = RegisterMappings[RegID].first;
131 WriteRef &OtherWR = RegisterMappings[*
I].first;
136 if (!WS.clearsSuperRegisters())
140 WriteRef &OtherWR = RegisterMappings[*
I].first;
154 unsigned RegisterFileIndex = RegisterFiles.size();
171 RegisterRenamingInfo &Entry = RegisterMappings[
Reg].second;
172 IndexPlusCostPairTy &IPC = Entry.IndexPlusCost;
173 if (IPC.first && IPC.first != RegisterFileIndex) {
178 <<
" defined in multiple register files.";
180 IPC = std::make_pair(RegisterFileIndex, RCE.Cost);
181 Entry.RenameAs =
Reg;
182 Entry.AllowMoveElimination = RCE.AllowMoveElimination;
186 RegisterRenamingInfo &OtherEntry = RegisterMappings[*
I].second;
187 if (!OtherEntry.IndexPlusCost.first &&
188 (!OtherEntry.RenameAs ||
190 OtherEntry.IndexPlusCost = IPC;
191 OtherEntry.RenameAs =
Reg;
198 void RegisterFile::allocatePhysRegs(
const RegisterRenamingInfo &Entry,
199 MutableArrayRef<unsigned> UsedPhysRegs) {
200 unsigned RegisterFileIndex = Entry.IndexPlusCost.first;
201 unsigned Cost = Entry.IndexPlusCost.second;
202 if (RegisterFileIndex) {
203 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
204 RMT.NumUsedPhysRegs +=
Cost;
205 UsedPhysRegs[RegisterFileIndex] +=
Cost;
209 RegisterFiles[0].NumUsedPhysRegs +=
Cost;
210 UsedPhysRegs[0] +=
Cost;
213 void RegisterFile::freePhysRegs(
const RegisterRenamingInfo &Entry,
214 MutableArrayRef<unsigned> FreedPhysRegs) {
215 unsigned RegisterFileIndex = Entry.IndexPlusCost.first;
216 unsigned Cost = Entry.IndexPlusCost.second;
217 if (RegisterFileIndex) {
218 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
219 RMT.NumUsedPhysRegs -=
Cost;
220 FreedPhysRegs[RegisterFileIndex] +=
Cost;
224 RegisterFiles[0].NumUsedPhysRegs -=
Cost;
225 FreedPhysRegs[0] +=
Cost;
239 dbgs() <<
"[PRF] addRegisterWrite [ " << Write.getSourceIndex() <<
", "
240 << MRI.
getName(RegID) <<
"]\n";
258 bool ShouldAllocatePhysRegs = !IsWriteZero && !IsEliminated;
259 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
260 WS.
setPRF(RRI.IndexPlusCost.first);
262 if (RRI.RenameAs && RRI.RenameAs != RegID) {
263 RegID = RRI.RenameAs;
264 WriteRef &OtherWrite = RegisterMappings[RegID].first;
270 ShouldAllocatePhysRegs =
false;
273 if (OtherWS && (OtherWrite.
getSourceIndex() != Write.getSourceIndex())) {
275 assert(!IsEliminated &&
"Unexpected partial update!");
284 ZeroRegisters.
setBitVal(ZeroRegisterID, IsWriteZero);
293 const WriteRef &OtherWrite = RegisterMappings[RegID].first;
295 if (OtherWS && OtherWrite.
getSourceIndex() == Write.getSourceIndex()) {
298 if (ShouldAllocatePhysRegs)
299 allocatePhysRegs(RegisterMappings[RegID].second, UsedPhysRegs);
305 RegisterMappings[RegID].first = Write;
306 RegisterMappings[RegID].second.AliasRegID = 0U;
308 RegisterMappings[*
I].first = Write;
309 RegisterMappings[*
I].second.AliasRegID = 0U;
315 if (ShouldAllocatePhysRegs)
316 allocatePhysRegs(RegisterMappings[RegID].second, UsedPhysRegs);
324 RegisterMappings[*
I].first = Write;
325 RegisterMappings[*
I].second.AliasRegID = 0U;
347 "Invalidating a write of unknown cycles!");
351 MCPhysReg RenameAs = RegisterMappings[RegID].second.RenameAs;
352 if (RenameAs && RenameAs != RegID) {
357 ShouldFreePhysRegs =
false;
361 if (ShouldFreePhysRegs)
362 freePhysRegs(RegisterMappings[RegID].second, FreedPhysRegs);
364 WriteRef &WR = RegisterMappings[RegID].first;
369 WriteRef &OtherWR = RegisterMappings[*
I].first;
378 WriteRef &OtherWR = RegisterMappings[*
I].first;
385 unsigned RegisterFileIndex)
const {
386 const RegisterMapping &RMFrom = RegisterMappings[RS.
getRegisterID()];
387 const RegisterMapping &RMTo = RegisterMappings[WS.
getRegisterID()];
388 const RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
391 const RegisterRenamingInfo &RRIFrom = RMFrom.second;
392 if (RRIFrom.IndexPlusCost.first != RegisterFileIndex)
395 const RegisterRenamingInfo &RRITo = RMTo.second;
396 if (RRITo.IndexPlusCost.first != RegisterFileIndex)
401 if (!RegisterMappings[RRITo.RenameAs].second.AllowMoveElimination)
423 return (!RMT.AllowZeroMoveEliminationOnly || IsZeroMove);
428 if (Writes.size() != Reads.size())
435 if (Writes.empty() || Writes.size() > 2)
439 const RegisterRenamingInfo &RRInfo =
440 RegisterMappings[Writes[0].getRegisterID()].second;
441 unsigned RegisterFileIndex = RRInfo.IndexPlusCost.first;
442 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
445 if (RMT.MaxMoveEliminatedPerCycle &&
446 (RMT.NumMoveEliminated + Writes.size()) > RMT.MaxMoveEliminatedPerCycle)
449 for (
size_t I = 0,
E = Writes.size();
I <
E; ++
I) {
456 for (
size_t I = 0,
E = Writes.size();
I <
E; ++
I) {
460 const RegisterMapping &RMFrom = RegisterMappings[RS.
getRegisterID()];
461 const RegisterMapping &RMTo = RegisterMappings[WS.
getRegisterID()];
462 const RegisterRenamingInfo &RRIFrom = RMFrom.second;
463 const RegisterRenamingInfo &RRITo = RMTo.second;
470 const RegisterRenamingInfo &RMAlias = RegisterMappings[AliasedReg].second;
471 if (RMAlias.AliasRegID)
472 AliasedReg = RMAlias.AliasRegID;
474 RegisterMappings[AliasReg].second.AliasRegID = AliasedReg;
476 RegisterMappings[*
I].second.AliasRegID = AliasedReg;
484 RMT.NumMoveEliminated++;
493 "Inconsistent state found!");
494 return WriteBackCycle;
510 assert(RegID && RegID < RegisterMappings.size());
512 << MRI.
getName(RegID) <<
'\n');
515 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
517 RegID = RRI.AliasRegID;
519 const WriteRef &WR = RegisterMappings[RegID].first;
521 Writes.push_back(WR);
525 if (ReadAdvance < 0) {
527 if (Elapsed <
static_cast<unsigned>(-ReadAdvance))
528 CommittedWrites.push_back(WR);
534 const WriteRef &WR = RegisterMappings[*
I].first;
536 Writes.push_back(WR);
540 if (ReadAdvance < 0) {
542 if (Elapsed <
static_cast<unsigned>(-ReadAdvance))
543 CommittedWrites.push_back(WR);
549 if (Writes.size() > 1) {
553 auto It =
std::unique(Writes.begin(), Writes.end());
554 Writes.
resize(std::distance(Writes.begin(), It));
560 dbgs() <<
"[PRF] Found a dependent use of Register "
594 if (CyclesLeft > 0) {
603 for (
const WriteRef &WR : CommittedWrites) {
604 unsigned WriteResID = WR.getWriteResourceID();
607 int CyclesLeft = NegReadAdvance - Elapsed;
608 assert(CyclesLeft > 0 &&
"Write should not be in the CommottedWrites set!");
621 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
622 RS.
setPRF(RRI.IndexPlusCost.first);
640 for (
WriteRef &WR : DependentWrites) {
641 unsigned WriteResID = WR.getWriteResourceID();
644 WS.
addUser(WR.getSourceIndex(), &RS, ReadAdvance);
647 for (
WriteRef &WR : CompletedWrites) {
648 unsigned WriteResID = WR.getWriteResourceID();
649 assert(WR.hasKnownWriteBackCycle() &&
"Invalid write!");
651 unsigned ReadAdvance =
static_cast<unsigned>(
654 assert(Elapsed < ReadAdvance &&
"Should not have been added to the set!");
656 ReadAdvance - Elapsed);
665 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
666 const IndexPlusCostPairTy &Entry = RRI.IndexPlusCost;
668 NumPhysRegs[Entry.first] += Entry.second;
669 NumPhysRegs[0] += Entry.second;
672 unsigned Response = 0;
674 unsigned NumRegs = NumPhysRegs[
I];
678 const RegisterMappingTracker &RMT = RegisterFiles[
I];
679 if (!RMT.NumPhysRegs) {
685 if (RMT.NumPhysRegs < NumRegs) {
691 dbgs() <<
"[PRF] Not enough registers in the register file.\n");
698 NumRegs = RMT.NumPhysRegs;
701 if (RMT.NumPhysRegs < (RMT.NumUsedPhysRegs + NumRegs))
702 Response |= (1U <<
I);
719 const RegisterMapping &
RM = RegisterMappings[
I];
720 const RegisterRenamingInfo &RRI =
RM.second;
721 if (ZeroRegisters[
I]) {
723 <<
", PRF=" << RRI.IndexPlusCost.first
724 <<
", Cost=" << RRI.IndexPlusCost.second
725 <<
", RenameAs=" << RRI.RenameAs <<
", IsZero=" << ZeroRegisters[
I]
733 dbgs() <<
"Register File #" <<
I;
734 const RegisterMappingTracker &RMT = RegisterFiles[
I];
735 dbgs() <<
"\n TotalMappings: " << RMT.NumPhysRegs
736 <<
"\n NumUsedMappings: " << RMT.NumUsedPhysRegs <<
'\n';