20#define DEBUG_TYPE "llvm-mca"
25const unsigned WriteRef::INVALID_IID = std::numeric_limits<unsigned>::max();
33 : IID(SourceIndex), WriteBackCycle(), WriteResID(), RegisterID(),
37 assert(Write && Write->isExecuted() &&
"Cannot commit before write back!");
38 RegisterID = Write->getRegisterID();
39 WriteResID = Write->getWriteResourceID();
44 assert(Write && Write->isExecuted() &&
"Not executed!");
45 WriteBackCycle =
Cycle;
49 return isValid() && (!Write || Write->isExecuted());
59 return Write->getWriteResourceID();
65 return Write->getRegisterID();
72 RegisterMappings(mri.getNumRegs(), {
WriteRef(), RegisterRenamingInfo()}),
73 ZeroRegisters(mri.getNumRegs(),
false), CurrentCycle() {
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) {
182 errs() <<
"warning: register " <<
MRI.getName(
Reg)
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 ||
194 MRI.isSuperRegister(
I, OtherEntry.RenameAs))) {
195 OtherEntry.IndexPlusCost = IPC;
196 OtherEntry.RenameAs =
Reg;
203void RegisterFile::allocatePhysRegs(
const RegisterRenamingInfo &Entry,
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,
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);
292 ZeroRegisters.setBitVal(
I, 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;
335 ZeroRegisters.setBitVal(
I, IsWriteZero);
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)
456 for (
size_t I = 0,
E = Writes.
size();
I <
E; ++
I) {
463 for (
size_t I = 0,
E = Writes.
size();
I <
E; ++
I) {
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++;
500 assert((!Write || Write->getCyclesLeft() <= 0) &&
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))
557 if (Writes.
size() > 1) {
568 dbgs() <<
"[PRF] Found a dependent use of Register "
569 << MRI.getName(WS.
getRegisterID()) <<
" (defined by instruction #"
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);
726 for (
unsigned I = 0,
E = MRI.getNumRegs();
I <
E; ++
I) {
727 const RegisterMapping &RM = RegisterMappings[
I];
728 const RegisterRenamingInfo &RRI = RM.second;
729 if (ZeroRegisters[
I]) {
730 dbgs() << MRI.getName(
I) <<
", " <<
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
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
This file defines abstractions used by the Pipeline to model register reads, register writes and inst...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
This file defines a register mapping file class.
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
MCRegisterClass - Base class of TargetRegisterClass.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
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.
LLVM_ABI 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
LLVM_ABI 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.
auto unique(Range &&R, Predicate P)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI 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...
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
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.