21 #define DEBUG_TYPE "llvm-mca" 29 RegisterMappings(mri.getNumRegs(), {
WriteRef(), RegisterRenamingInfo()}),
30 ZeroRegisters(mri.getNumRegs(),
false) {
31 initialize(SM, NumRegs);
34 void RegisterFile::initialize(
const MCSchedModel &SM,
unsigned NumRegs) {
63 for (RegisterMappingTracker &RMT : RegisterFiles)
64 RMT.NumMoveEliminated = 0;
74 unsigned RegisterFileIndex = RegisterFiles.
size();
91 RegisterRenamingInfo &Entry = RegisterMappings[
Reg].second;
92 IndexPlusCostPairTy &IPC = Entry.IndexPlusCost;
93 if (IPC.first && IPC.first != RegisterFileIndex) {
98 <<
" defined in multiple register files.";
100 IPC = std::make_pair(RegisterFileIndex, RCE.Cost);
101 Entry.RenameAs =
Reg;
102 Entry.AllowMoveElimination = RCE.AllowMoveElimination;
106 RegisterRenamingInfo &OtherEntry = RegisterMappings[*
I].second;
107 if (!OtherEntry.IndexPlusCost.first &&
108 (!OtherEntry.RenameAs ||
110 OtherEntry.IndexPlusCost = IPC;
111 OtherEntry.RenameAs =
Reg;
118 void RegisterFile::allocatePhysRegs(
const RegisterRenamingInfo &Entry,
120 unsigned RegisterFileIndex = Entry.IndexPlusCost.first;
121 unsigned Cost = Entry.IndexPlusCost.second;
122 if (RegisterFileIndex) {
123 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
124 RMT.NumUsedPhysRegs += Cost;
125 UsedPhysRegs[RegisterFileIndex] += Cost;
129 RegisterFiles[0].NumUsedPhysRegs += Cost;
130 UsedPhysRegs[0] += Cost;
133 void RegisterFile::freePhysRegs(
const RegisterRenamingInfo &Entry,
135 unsigned RegisterFileIndex = Entry.IndexPlusCost.first;
136 unsigned Cost = Entry.IndexPlusCost.second;
137 if (RegisterFileIndex) {
138 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
139 RMT.NumUsedPhysRegs -= Cost;
140 FreedPhysRegs[RegisterFileIndex] += Cost;
144 RegisterFiles[0].NumUsedPhysRegs -= Cost;
145 FreedPhysRegs[0] += Cost;
152 assert(RegID &&
"Adding an invalid register definition?");
156 <<
", " << MRI.
getName(RegID) <<
"]\n";
174 bool ShouldAllocatePhysRegs = !IsWriteZero && !IsEliminated;
175 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
176 WS.
setPRF(RRI.IndexPlusCost.first);
178 if (RRI.RenameAs && RRI.RenameAs != RegID) {
179 RegID = RRI.RenameAs;
180 WriteRef &OtherWrite = RegisterMappings[RegID].first;
186 ShouldAllocatePhysRegs =
false;
191 assert(!IsEliminated &&
"Unexpected partial update!");
198 unsigned ZeroRegisterID =
201 ZeroRegisters.
setBit(ZeroRegisterID);
205 ZeroRegisters.
clearBit(ZeroRegisterID);
214 RegisterMappings[RegID].first = Write;
215 RegisterMappings[RegID].second.AliasRegID = 0U;
217 RegisterMappings[*
I].first = Write;
218 RegisterMappings[*
I].second.AliasRegID = 0U;
224 if (ShouldAllocatePhysRegs)
225 allocatePhysRegs(RegisterMappings[RegID].
second, UsedPhysRegs);
233 RegisterMappings[*
I].first = Write;
234 RegisterMappings[*
I].second.AliasRegID = 0U;
253 assert(RegID != 0 &&
"Invalidating an already invalid register?");
255 "Invalidating a write of unknown cycles!");
259 unsigned RenameAs = RegisterMappings[RegID].second.RenameAs;
260 if (RenameAs && RenameAs != RegID) {
265 ShouldFreePhysRegs =
false;
269 if (ShouldFreePhysRegs)
270 freePhysRegs(RegisterMappings[RegID].
second, FreedPhysRegs);
272 WriteRef &WR = RegisterMappings[RegID].first;
277 WriteRef &OtherWR = RegisterMappings[*
I].first;
286 WriteRef &OtherWR = RegisterMappings[*
I].first;
293 const RegisterMapping &RMFrom = RegisterMappings[RS.
getRegisterID()];
294 const RegisterMapping &RMTo = RegisterMappings[WS.
getRegisterID()];
297 const RegisterRenamingInfo &RRIFrom = RMFrom.second;
298 const RegisterRenamingInfo &RRITo = RMTo.second;
299 unsigned RegisterFileIndex = RRIFrom.IndexPlusCost.first;
300 if (RegisterFileIndex != RRITo.IndexPlusCost.first)
317 if (RRITo.RenameAs && RRITo.RenameAs != WS.
getRegisterID()) {
319 if (!RegisterMappings[RRITo.RenameAs].second.AllowMoveElimination)
325 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
326 if (RMT.MaxMoveEliminatedPerCycle &&
327 RMT.NumMoveEliminated == RMT.MaxMoveEliminatedPerCycle)
331 if (RMT.AllowZeroMoveEliminationOnly && !IsZeroMove)
339 if (RRIFrom.RenameAs)
340 AliasReg = RRIFrom.RenameAs;
342 const RegisterRenamingInfo &RMAlias = RegisterMappings[AliasReg].second;
343 if (RMAlias.AliasRegID)
344 AliasReg = RMAlias.AliasRegID;
346 if (AliasReg != ToReg) {
347 RegisterMappings[ToReg].second.AliasRegID = AliasReg;
349 RegisterMappings[*
I].
second.AliasRegID = AliasReg;
352 RMT.NumMoveEliminated++;
362 void RegisterFile::collectWrites(
const ReadState &RS,
365 assert(RegID && RegID < RegisterMappings.size());
366 LLVM_DEBUG(
dbgs() <<
"RegisterFile: collecting writes for register " 367 << MRI.
getName(RegID) <<
'\n');
370 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
372 RegID = RRI.AliasRegID;
374 const WriteRef &WR = RegisterMappings[RegID].first;
380 const WriteRef &WR = RegisterMappings[*
I].first;
386 if (Writes.
size() > 1) {
390 auto It = std::unique(Writes.
begin(), Writes.
end());
397 dbgs() <<
"[PRF] Found a dependent use of Register " 407 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
408 RS.
setPRF(RRI.IndexPlusCost.first);
414 collectWrites(RS, Defs);
422 for (
const unsigned RegID : Regs) {
423 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
424 const IndexPlusCostPairTy &Entry = RRI.IndexPlusCost;
426 NumPhysRegs[Entry.first] += Entry.second;
427 NumPhysRegs[0] += Entry.second;
430 unsigned Response = 0;
432 unsigned NumRegs = NumPhysRegs[
I];
436 const RegisterMappingTracker &RMT = RegisterFiles[
I];
437 if (!RMT.NumPhysRegs) {
443 if (RMT.NumPhysRegs < NumRegs) {
448 LLVM_DEBUG(
dbgs() <<
"Not enough registers in the register file.\n");
455 NumRegs = RMT.NumPhysRegs;
458 if (RMT.NumPhysRegs < (RMT.NumUsedPhysRegs + NumRegs))
459 Response |= (1U <<
I);
468 const RegisterMapping &
RM = RegisterMappings[
I];
469 const RegisterRenamingInfo &RRI = RM.second;
470 if (ZeroRegisters[
I]) {
472 <<
", PRF=" << RRI.IndexPlusCost.first
473 <<
", Cost=" << RRI.IndexPlusCost.second
474 <<
", RenameAs=" << RRI.RenameAs <<
", IsZero=" << ZeroRegisters[
I]
482 dbgs() <<
"Register File #" <<
I;
483 const RegisterMappingTracker &RMT = RegisterFiles[
I];
484 dbgs() <<
"\n TotalMappings: " << RMT.NumPhysRegs
485 <<
"\n NumUsedMappings: " << RMT.NumUsedPhysRegs <<
'\n';
const WriteState * getWriteState() const
bool isEliminated() const
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
This class represents lattice values for constants.
void addRegisterWrite(WriteRef Write, MutableArrayRef< unsigned > UsedPhysRegs)
constexpr int UNKNOWN_CYCLES
void push_back(const T &Elt)
unsigned getNumRegisterFiles() const
bool AllowZeroMoveEliminationOnly
void dump() const
debug method
void setBit(unsigned BitPosition)
Set a given bit to 1.
MCSuperRegIterator enumerates all super-registers of Reg.
Tracks register operand latency in cycles.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
A register file descriptor.
unsigned getRegisterID() const
Specify the cost of a register definition in terms of number of physical register allocated at regist...
uint16_t MaxMovesEliminatedPerCycle
void clearBit(unsigned BitPosition)
Set a given bit to 0.
This file defines a register mapping file class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
MCRegisterClass - Base class of TargetRegisterClass.
Analysis containing CSE Info
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
const char * getName(unsigned RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register...
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
bool isSuperRegister(unsigned RegA, unsigned RegB) const
Returns true if RegB is a super-register of RegA.
int getCyclesLeft() const
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
unsigned const MachineRegisterInfo * MRI
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
bool hasExtraProcessorInfo() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
unsigned isAvailable(ArrayRef< unsigned > Regs) const
RegisterFile(const MCSchedModel &SM, const MCRegisterInfo &mri, unsigned NumRegs=0)
MCSubRegIterator enumerates all sub-registers of Reg.
void removeRegisterWrite(const WriteState &WS, MutableArrayRef< unsigned > FreedPhysRegs)
void setDependentWrites(unsigned Writes)
void sort(IteratorTy Start, IteratorTy End)
void addUser(ReadState *Use, int ReadAdvance)
Tracks uses of a register definition (e.g.
A reference to a register write.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isIndependentFromDef() const
void setPRF(unsigned PRF)
unsigned getSourceIndex() const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
void emplace_back(ArgTypes &&... Args)
This file defines abstractions used by the Pipeline to model register reads, register writes and inst...
bool tryEliminateMove(WriteState &WS, ReadState &RS)
const MCExtraProcessorInfo & getExtraProcessorInfo() const
unsigned getRegisterID() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void addRegisterRead(ReadState &RS, SmallVectorImpl< WriteRef > &Writes) const
uint16_t NumRegisterCostEntries
bool clearsSuperRegisters() const
Machine model for scheduling, bundling, and heuristics.
bool empty() const
empty - Check if the array is empty.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
uint16_t RegisterCostEntryIdx