25#define DEBUG_TYPE "regalloc"
27STATISTIC(NumDCEDeleted,
"Number of instructions deleted by DCE");
28STATISTIC(NumDCEFoldedLoads,
"Number of single use loads folded after DCE");
29STATISTIC(NumFracRanges,
"Number of live ranges fractured by DCE");
30STATISTIC(NumReMaterialization,
"Number of instructions rematerialized");
32void LiveRangeEdit::Delegate::anchor() { }
35 bool createSubRanges) {
43 if (createSubRanges) {
74 ScannedRemattable =
true;
77 Remattable.insert(VNI);
81void LiveRangeEdit::scanRemattable() {
95 ScannedRemattable =
true;
99 if (!ScannedRemattable)
101 return !Remattable.empty();
110 UseIdx = std::max(UseIdx, UseIdx.
getRegSlot(
true));
112 if (!MO.isReg() || !MO.getReg() || !MO.readsReg())
117 if (MO.getReg().isPhysical()) {
140 unsigned SubReg = MO.getSubReg();
144 if ((SR.LaneMask & LM).none())
146 if (!SR.liveAt(UseIdx))
160 assert(ScannedRemattable &&
"Call anyRematerializable first");
163 if (!Remattable.count(OrigVNI))
168 assert(RM.OrigMI &&
"No defining instruction for remattable value");
186 bool Late,
unsigned SubIdx,
188 assert(RM.OrigMI &&
"Invalid remat");
193 (*--
MI).clearRegisterDeads(DestReg);
194 Rematted.insert(RM.ParentVNI);
195 ++NumReMaterialization;
217 if (!
MI->canFoldAsLoad())
220 }
else if (!MO.isUndef()) {
240 bool SawStore =
true;
245 <<
" into single use: " << *
UseMI);
276 if ((S.LaneMask & LaneMask).any() && S.Query(
Idx).isKill())
283void LiveRangeEdit::eliminateDeadDef(
MachineInstr *
MI, ToShrinkSet &ToShrink) {
284 assert(
MI->allDefsAreDead() &&
"Def isn't really dead");
288 if (
MI->isBundled()) {
296 if (
MI->isInlineAsm()) {
302 bool SawStore =
false;
303 if (!
MI->isSafeToMove(SawStore)) {
312 bool ReadsPhysRegs =
false;
313 bool isOrigDef =
false;
319 if (VRM &&
MI->getOperand(0).isReg() &&
MI->getOperand(0).isDef() &&
320 MI->getDesc().getNumDefs() == 1) {
321 Dest =
MI->getOperand(0).getReg();
322 DestSubReg =
MI->getOperand(0).getSubReg();
334 bool HasLiveVRegUses =
false;
341 if (!
Reg.isVirtual()) {
344 ReadsPhysRegs =
true;
355 if ((
MI->readsVirtualRegister(Reg) &&
358 ToShrink.insert(&LI);
360 HasLiveVRegUses =
true;
380 MI->setDesc(TII.
get(TargetOpcode::KILL));
382 for (
unsigned i =
MI->getNumOperands(); i; --i) {
386 MI->removeOperand(i-1);
398 if (isOrigDef && DeadRemats && !HasLiveVRegUses &&
400 LiveInterval &NewLI = createEmptyIntervalFrom(Dest,
false);
408 Alloc,
TRI->getSubRegIndexLaneMask(DestSubReg));
414 DeadRemats->insert(
MI);
416 MI->substituteRegister(Dest, NewLI.
reg(), 0,
TRI);
422 MI->eraseFromParent();
443 while (!Dead.empty())
444 eliminateDeadDef(Dead.pop_back_val(), ToShrink);
446 if (ToShrink.
empty())
451 if (foldAsLoad(LI, Dead))
470 if (!SplitLIs.
empty())
478 if (Original != VReg && Original != 0)
489LiveRangeEdit::MRI_NoteNewVirtualRegister(
Register VReg) {
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
unsigned const TargetRegisterInfo * TRI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Allocate memory in an ever growing pool, as if by bump-pointer.
A live range for subregisters.
LiveInterval - This class represents the liveness of a register, or stack slot.
void markNotSpillable()
markNotSpillable - Mark interval as not spillable
bool isSpillable() const
isSpillable - Can this interval be spilled?
bool hasSubRanges() const
Returns true if subregister liveness information is available.
iterator_range< subrange_iterator > subranges()
SubRange * createSubRange(BumpPtrAllocator &Allocator, LaneBitmask LaneMask)
Creates a new empty subregister live range.
bool hasInterval(Register Reg) const
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
SlotIndexes * getSlotIndexes() const
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
VNInfo::Allocator & getVNInfoAllocator()
LiveInterval & getInterval(Register Reg)
void removeInterval(Register Reg)
Interval removal.
void removeVRegDefAt(LiveInterval &LI, SlotIndex Pos)
Remove value number and related live segments of LI and its subranges that start at position Pos.
bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses.
LiveInterval & createEmptyInterval(Register Reg)
Interval creation.
void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos)
Remove value numbers and related live segments starting at position Pos that are part of any liverang...
void splitSeparateComponents(LiveInterval &LI, SmallVectorImpl< LiveInterval * > &SplitLIs)
Split separate components in LiveInterval LI into separate intervals.
SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)
bool isKill() const
Return true if the live-in value is killed by this instruction.
virtual bool LRE_CanEraseVirtReg(Register)
Called when a virtual register is no longer used.
virtual void LRE_WillEraseInstruction(MachineInstr *MI)
Called immediately before erasing a dead machine instruction.
virtual void LRE_WillShrinkVirtReg(Register)
Called before shrinking the live range of a virtual register.
virtual void LRE_DidCloneVirtReg(Register New, Register Old)
Called after cloning a virtual register.
void eraseVirtReg(Register Reg)
eraseVirtReg - Notify the delegate that Reg is no longer in use, and try to erase it from LIS.
Register get(unsigned idx) const
void eliminateDeadDefs(SmallVectorImpl< MachineInstr * > &Dead, ArrayRef< Register > RegsBeingSpilled=std::nullopt)
eliminateDeadDefs - Try to delete machine instructions that are now dead (allDefsAreDead returns true...
Register createFrom(Register OldReg)
createFrom - Create a new virtual register based on OldReg.
void calculateRegClassAndHint(MachineFunction &, VirtRegAuxInfo &)
calculateRegClassAndHint - Recompute register class and hint for each new register.
const LiveInterval & getParent() const
SlotIndex rematerializeAt(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, const Remat &RM, const TargetRegisterInfo &, bool Late=false, unsigned SubIdx=0, MachineInstr *ReplaceIndexMI=nullptr)
rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an instruction into MBB before...
bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx, SlotIndex UseIdx) const
allUsesAvailableAt - Return true if all registers used by OrigMI at OrigIdx are also available with t...
void pop_back()
pop_back - It allows LiveRangeEdit users to drop new registers.
bool checkRematerializable(VNInfo *VNI, const MachineInstr *DefMI)
checkRematerializable - Manually add VNI to the list of rematerializable values if DefMI may be remat...
bool canRematerializeAt(Remat &RM, VNInfo *OrigVNI, SlotIndex UseIdx, bool cheapAsAMove)
canRematerializeAt - Determine if ParentVNI can be rematerialized at UseIdx.
bool anyRematerializable()
anyRematerializable - Return true if any parent values may be rematerializable.
iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
void RenumberValues()
RenumberValues - Renumber all values in order of appearance and remove unused values.
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
VNInfo * getNextValue(SlotIndex Def, VNInfo::Allocator &VNInfoAllocator)
getNextValue - Create a new value number and return it.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void moveCallSiteInfo(const MachineInstr *Old, const MachineInstr *New)
Move the call site info from Old to \New call site info.
Representation of each machine instruction.
std::pair< bool, bool > readsWritesVirtualRegister(Register Reg, SmallVectorImpl< unsigned > *Ops=nullptr) const
Return a pair of bools (reads, writes) indicating if this instruction reads or writes Reg.
bool isSafeToMove(bool &SawStore) const
Return true if it is safe to move this instruction.
bool shouldUpdateCallSiteInfo() const
Return true if copying, moving, or erasing this instruction requires updating Call Site Info (see cop...
iterator_range< mop_iterator > operands()
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool addRegisterDead(Register Reg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI defined a register without a use.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
bool recomputeRegClass(Register Reg)
recomputeRegClass - Try to find a legal super-class of Reg's register class that still satisfies the ...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
bool reg_nodbg_empty(Register RegNo) const
reg_nodbg_empty - Return true if the only instructions using or defining Reg are Debug instructions.
const TargetRegisterInfo * getTargetRegisterInfo() const
LaneBitmask getMaxLaneMaskForVReg(Register Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
bool isConstantPhysReg(MCRegister PhysReg) const
Returns true if PhysReg is unallocatable and constant throughout the function.
iterator_range< reg_nodbg_iterator > reg_nodbg_operands(Register Reg) const
Register cloneVirtualRegister(Register VReg, StringRef Name="")
Create and return a new virtual register in the function with the same attributes as the given regist...
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
bool empty() const
Determine if the SetVector is empty or not.
value_type pop_back_val()
SlotIndex - An opaque wrapper around machine indexes.
static bool isSameInstr(SlotIndex A, SlotIndex B)
isSameInstr - Return true if A and B refer to the same instruction.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
SlotIndex insertMachineInstrInMaps(MachineInstr &MI, bool Late=false)
Insert the given machine instruction into the mapping.
A SetVector that performs no allocations if smaller than a certain size.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
bool isTriviallyReMaterializable(const MachineInstr &MI) const
Return true if the instruction is trivially rematerializable, meaning it has no side effects and requ...
virtual bool isIgnorableUse(const MachineOperand &MO) const
Given MO is a PhysReg use return if it can be ignored for the purpose of instruction rematerializatio...
MachineInstr * foldMemoryOperand(MachineInstr &MI, ArrayRef< unsigned > Ops, int FI, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const
Attempt to fold a load or store of the specified stack slot into the specified machine instruction fo...
virtual bool isAsCheapAsAMove(const MachineInstr &MI) const
Return true if the instruction is as cheap as a move instruction.
virtual void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, unsigned SubIdx, const MachineInstr &Orig, const TargetRegisterInfo &TRI) const
Re-issue the specified 'original' instruction at the specific location targeting a new destination re...
std::optional< DestSourcePair > isCopyInstr(const MachineInstr &MI) const
If the specific machine instruction is a instruction that moves/copies value from one register to ano...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
VNInfo - Value Number Information.
SlotIndex def
The index of the defining instruction.
Calculate auxiliary information for a virtual register such as its spill weight and allocation hint.
void calculateSpillWeightAndHint(LiveInterval &LI)
(re)compute li's spill weight and allocation hint.
void setIsSplitFromReg(Register virtReg, Register SReg)
records virtReg is a split live interval from SReg.
Register getOriginal(Register VirtReg) const
getOriginal - Return the original virtual register that VirtReg descends from through splitting.
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
constexpr bool none() const
Remat - Information needed to rematerialize at a specific location.
This represents a simple continuous liveness interval for a value.