20#define DEBUG_TYPE "llvm-mca"
25const unsigned WriteRef::INVALID_IID = std::numeric_limits<unsigned>::max();
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);
72void 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;
198void 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;
213void 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;
275 assert(!IsEliminated &&
"Unexpected partial update!");
284 ZeroRegisters.
setBitVal(ZeroRegisterID, IsWriteZero);
293 const WriteRef &OtherWrite = RegisterMappings[RegID].first;
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);
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)
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;
525 if (ReadAdvance < 0) {
527 if (Elapsed <
static_cast<unsigned>(-ReadAdvance))
534 const WriteRef &WR = RegisterMappings[
I].first;
540 if (ReadAdvance < 0) {
542 if (Elapsed <
static_cast<unsigned>(-ReadAdvance))
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';
unsigned const MachineRegisterInfo * MRI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
SmallVector< uint32_t, 0 > Writes
This file defines abstractions used by the Pipeline to model register reads, register writes and inst...
This file defines a register mapping file class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void setBitVal(unsigned BitPosition, bool BitValue)
Set a given bit to a given value.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
A possibly irreducible generalization of a Loop.
MCRegisterClass - Base class of TargetRegisterClass.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
iterator_range< MCSuperRegIterator > superregs(MCRegister Reg) const
Return an iterator range over all super-registers of Reg, excluding Reg.
const char * getName(MCRegister RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register.
iterator_range< MCSubRegIterator > subregs(MCRegister Reg) const
Return an iterator range over all sub-registers of Reg, excluding Reg.
bool isSuperRegister(MCRegister RegA, MCRegister RegB) const
Returns true if RegB is a super-register of RegA.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
Generic base class for all target subtargets.
int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx, unsigned WriteResID) const
const MCSchedModel & getSchedModel() const
Get the machine model for this subtarget's CPU.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
SmallVectorImpl< WriteState > & getDefs()
An instruction propagated through the simulated instruction pipeline.
Tracks register operand latency in cycles.
void writeStartEvent(unsigned IID, MCPhysReg RegID, unsigned Cycles)
bool isIndependentFromDef() const
const ReadDescriptor & getDescriptor() const
void setDependentWrites(unsigned Writes)
MCPhysReg getRegisterID() const
void collectWrites(const MCSubtargetInfo &STI, const ReadState &RS, SmallVectorImpl< WriteRef > &Writes, SmallVectorImpl< WriteRef > &CommittedWrites) const
unsigned getElapsedCyclesFromWriteBack(const WriteRef &WR) const
void addRegisterWrite(WriteRef Write, MutableArrayRef< unsigned > UsedPhysRegs)
unsigned isAvailable(ArrayRef< MCPhysReg > Regs) const
unsigned getNumRegisterFiles() const
RAWHazard checkRAWHazards(const MCSubtargetInfo &STI, const ReadState &RS) const
void removeRegisterWrite(const WriteState &WS, MutableArrayRef< unsigned > FreedPhysRegs)
bool tryEliminateMoveOrSwap(MutableArrayRef< WriteState > Writes, MutableArrayRef< ReadState > Reads)
RegisterFile(const MCSchedModel &SM, const MCRegisterInfo &mri, unsigned NumRegs=0)
void addRegisterRead(ReadState &RS, const MCSubtargetInfo &STI) const
bool canEliminateMove(const WriteState &WS, const ReadState &RS, unsigned PRFIndex) const
void onInstructionExecuted(Instruction *IS)
A reference to a register write.
unsigned getSourceIndex() const
unsigned getWriteResourceID() const
void notifyExecuted(unsigned Cycle)
const WriteState * getWriteState() const
MCPhysReg getRegisterID() const
unsigned getWriteBackCycle() const
bool hasKnownWriteBackCycle() const
Tracks uses of a register definition (e.g.
bool isEliminated() const
unsigned getLatency() const
void setPRF(unsigned PRF)
int getCyclesLeft() const
bool clearsSuperRegisters() const
MCPhysReg getRegisterID() const
unsigned getWriteResourceID() const
void addUser(unsigned IID, ReadState *Use, int ReadAdvance)
constexpr int UNKNOWN_CYCLES
This is an optimization pass for GlobalISel generic memory operations.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
auto unique(Range &&R, Predicate P)
void sort(IteratorTy Start, IteratorTy End)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Specify the cost of a register definition in terms of number of physical register allocated at regist...
A register file descriptor.
uint16_t NumRegisterCostEntries
bool AllowZeroMoveEliminationOnly
uint16_t RegisterCostEntryIdx
uint16_t MaxMovesEliminatedPerCycle
Summarize the scheduling resources required for an instruction of a particular scheduling class.
Machine model for scheduling, bundling, and heuristics.
bool hasExtraProcessorInfo() const
const MCSchedClassDesc * getSchedClassDesc(unsigned SchedClassIdx) const
const MCExtraProcessorInfo & getExtraProcessorInfo() const
A register read descriptor.