20#define DEBUG_TYPE "llvm-mca"
25const unsigned WriteRef::INVALID_IID = std::numeric_limits<unsigned>::max();
33 : IID(SourceIndex), WriteBackCycle(), WriteResID(), RegisterID(),
45 WriteBackCycle =
Cycle;
72 RegisterMappings(mri.getNumRegs(), {
WriteRef(), RegisterRenamingInfo()}),
73 ZeroRegisters(mri.getNumRegs(),
false), CurrentCycle() {
74 initialize(SM, NumRegs);
77void RegisterFile::initialize(
const MCSchedModel &SM,
unsigned NumRegs) {
92 for (
unsigned I = 1,
E =
Info.NumRegisterFiles;
I <
E; ++
I) {
106 for (RegisterMappingTracker &RMT : RegisterFiles)
107 RMT.NumMoveEliminated = 0;
113 if (WS.isEliminated())
124 "The number of cycles should be known at this point!");
125 assert(WS.getCyclesLeft() <= 0 &&
"Invalid cycles left for this write!");
127 MCPhysReg RenameAs = RegisterMappings[RegID].second.RenameAs;
128 if (RenameAs && RenameAs != RegID)
131 WriteRef &WR = RegisterMappings[RegID].first;
136 WriteRef &OtherWR = RegisterMappings[
I].first;
141 if (!WS.clearsSuperRegisters())
145 WriteRef &OtherWR = RegisterMappings[
I].first;
159 unsigned RegisterFileIndex = RegisterFiles.
size();
176 RegisterRenamingInfo &Entry = RegisterMappings[
Reg].second;
177 IndexPlusCostPairTy &IPC = Entry.IndexPlusCost;
178 if (IPC.first && IPC.first != RegisterFileIndex) {
183 <<
" defined in multiple register files.";
185 IPC = std::make_pair(RegisterFileIndex, RCE.Cost);
186 Entry.RenameAs =
Reg;
187 Entry.AllowMoveElimination = RCE.AllowMoveElimination;
191 RegisterRenamingInfo &OtherEntry = RegisterMappings[
I].second;
192 if (!OtherEntry.IndexPlusCost.first &&
193 (!OtherEntry.RenameAs ||
195 OtherEntry.IndexPlusCost = IPC;
196 OtherEntry.RenameAs =
Reg;
203void RegisterFile::allocatePhysRegs(
const RegisterRenamingInfo &Entry,
204 MutableArrayRef<unsigned> UsedPhysRegs) {
205 unsigned RegisterFileIndex =
Entry.IndexPlusCost.first;
206 unsigned Cost =
Entry.IndexPlusCost.second;
207 if (RegisterFileIndex) {
208 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
209 RMT.NumUsedPhysRegs +=
Cost;
210 UsedPhysRegs[RegisterFileIndex] +=
Cost;
214 RegisterFiles[0].NumUsedPhysRegs +=
Cost;
215 UsedPhysRegs[0] +=
Cost;
218void RegisterFile::freePhysRegs(
const RegisterRenamingInfo &Entry,
219 MutableArrayRef<unsigned> FreedPhysRegs) {
220 unsigned RegisterFileIndex =
Entry.IndexPlusCost.first;
221 unsigned Cost =
Entry.IndexPlusCost.second;
222 if (RegisterFileIndex) {
223 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
224 RMT.NumUsedPhysRegs -=
Cost;
225 FreedPhysRegs[RegisterFileIndex] +=
Cost;
229 RegisterFiles[0].NumUsedPhysRegs -=
Cost;
230 FreedPhysRegs[0] +=
Cost;
244 dbgs() <<
"[PRF] addRegisterWrite [ " <<
Write.getSourceIndex() <<
", "
245 << MRI.
getName(RegID) <<
"]\n";
263 bool ShouldAllocatePhysRegs = !IsWriteZero && !IsEliminated;
264 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
265 WS.
setPRF(RRI.IndexPlusCost.first);
267 if (RRI.RenameAs && RRI.RenameAs != RegID) {
268 RegID = RRI.RenameAs;
269 WriteRef &OtherWrite = RegisterMappings[RegID].first;
275 ShouldAllocatePhysRegs =
false;
280 assert(!IsEliminated &&
"Unexpected partial update!");
289 ZeroRegisters.
setBitVal(ZeroRegisterID, IsWriteZero);
299 const WriteRef &OtherWrite = RegisterMappings[RegID].first;
304 if (ShouldAllocatePhysRegs)
305 allocatePhysRegs(RegisterMappings[RegID].second, UsedPhysRegs);
311 RegisterMappings[RegID].first =
Write;
312 RegisterMappings[RegID].second.AliasRegID = 0U;
315 RegisterMappings[
I].first =
Write;
316 RegisterMappings[
I].second.AliasRegID = 0U;
322 if (ShouldAllocatePhysRegs)
323 allocatePhysRegs(RegisterMappings[RegID].second, UsedPhysRegs);
331 RegisterMappings[
I].first =
Write;
332 RegisterMappings[
I].second.AliasRegID = 0U;
354 "Invalidating a write of unknown cycles!");
358 MCPhysReg RenameAs = RegisterMappings[RegID].second.RenameAs;
359 if (RenameAs && RenameAs != RegID) {
364 ShouldFreePhysRegs =
false;
368 if (ShouldFreePhysRegs)
369 freePhysRegs(RegisterMappings[RegID].second, FreedPhysRegs);
371 WriteRef &WR = RegisterMappings[RegID].first;
376 WriteRef &OtherWR = RegisterMappings[
I].first;
385 WriteRef &OtherWR = RegisterMappings[
I].first;
392 unsigned RegisterFileIndex)
const {
393 const RegisterMapping &RMFrom = RegisterMappings[RS.
getRegisterID()];
394 const RegisterMapping &RMTo = RegisterMappings[WS.
getRegisterID()];
395 const RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
398 const RegisterRenamingInfo &RRIFrom = RMFrom.second;
399 if (RRIFrom.IndexPlusCost.first != RegisterFileIndex)
402 const RegisterRenamingInfo &RRITo = RMTo.second;
403 if (RRITo.IndexPlusCost.first != RegisterFileIndex)
408 if (!RegisterMappings[RRITo.RenameAs].second.AllowMoveElimination)
430 return (!RMT.AllowZeroMoveEliminationOnly || IsZeroMove);
446 const RegisterRenamingInfo &RRInfo =
447 RegisterMappings[
Writes[0].getRegisterID()].second;
448 unsigned RegisterFileIndex = RRInfo.IndexPlusCost.first;
449 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
452 if (RMT.MaxMoveEliminatedPerCycle &&
453 (RMT.NumMoveEliminated +
Writes.
size()) > RMT.MaxMoveEliminatedPerCycle)
467 const RegisterMapping &RMFrom = RegisterMappings[RS.
getRegisterID()];
468 const RegisterMapping &RMTo = RegisterMappings[WS.
getRegisterID()];
469 const RegisterRenamingInfo &RRIFrom = RMFrom.second;
470 const RegisterRenamingInfo &RRITo = RMTo.second;
477 const RegisterRenamingInfo &RMAlias = RegisterMappings[AliasedReg].second;
478 if (RMAlias.AliasRegID)
479 AliasedReg = RMAlias.AliasRegID;
481 RegisterMappings[AliasReg].second.AliasRegID = AliasedReg;
484 RegisterMappings[
I].second.AliasRegID = AliasedReg;
492 RMT.NumMoveEliminated++;
501 "Inconsistent state found!");
502 return WriteBackCycle;
518 assert(RegID && RegID < RegisterMappings.size());
520 << MRI.
getName(RegID) <<
'\n');
523 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
525 RegID = RRI.AliasRegID;
527 const WriteRef &WR = RegisterMappings[RegID].first;
533 if (ReadAdvance < 0) {
535 if (Elapsed <
static_cast<unsigned>(-ReadAdvance))
542 const WriteRef &WR = RegisterMappings[
I].first;
548 if (ReadAdvance < 0) {
550 if (Elapsed <
static_cast<unsigned>(-ReadAdvance))
568 dbgs() <<
"[PRF] Found a dependent use of Register "
602 if (CyclesLeft > 0) {
611 for (
const WriteRef &WR : CommittedWrites) {
612 unsigned WriteResID = WR.getWriteResourceID();
615 int CyclesLeft = NegReadAdvance - Elapsed;
616 assert(CyclesLeft > 0 &&
"Write should not be in the CommottedWrites set!");
629 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
630 RS.
setPRF(RRI.IndexPlusCost.first);
648 for (
WriteRef &WR : DependentWrites) {
649 unsigned WriteResID = WR.getWriteResourceID();
652 WS.
addUser(WR.getSourceIndex(), &RS, ReadAdvance);
655 for (
WriteRef &WR : CompletedWrites) {
656 unsigned WriteResID = WR.getWriteResourceID();
657 assert(WR.hasKnownWriteBackCycle() &&
"Invalid write!");
659 unsigned ReadAdvance =
static_cast<unsigned>(
662 assert(Elapsed < ReadAdvance &&
"Should not have been added to the set!");
664 ReadAdvance - Elapsed);
673 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
674 const IndexPlusCostPairTy &Entry = RRI.IndexPlusCost;
676 NumPhysRegs[Entry.first] += Entry.second;
677 NumPhysRegs[0] += Entry.second;
680 unsigned Response = 0;
682 unsigned NumRegs = NumPhysRegs[
I];
686 const RegisterMappingTracker &RMT = RegisterFiles[
I];
687 if (!RMT.NumPhysRegs) {
693 if (RMT.NumPhysRegs < NumRegs) {
699 dbgs() <<
"[PRF] Not enough registers in the register file.\n");
706 NumRegs = RMT.NumPhysRegs;
709 if (RMT.NumPhysRegs < (RMT.NumUsedPhysRegs + NumRegs))
710 Response |= (1U <<
I);
727 const RegisterMapping &RM = RegisterMappings[
I];
728 const RegisterRenamingInfo &RRI = RM.second;
729 if (ZeroRegisters[
I]) {
731 <<
", PRF=" << RRI.IndexPlusCost.first
732 <<
", Cost=" << RRI.IndexPlusCost.second
733 <<
", RenameAs=" << RRI.RenameAs <<
", IsZero=" << ZeroRegisters[
I]
741 dbgs() <<
"Register File #" <<
I;
742 const RegisterMappingTracker &RMT = RegisterFiles[
I];
743 dbgs() <<
"\n TotalMappings: " << RMT.NumPhysRegs
744 <<
"\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)
static std::function< bool(MCPhysReg)> isNonArtificial(const MCRegisterInfo &MRI)
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.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
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.