44#define DEBUG_TYPE "rename-independent-subregs"
48class RenameIndependentSubregs {
62 : ConEQ(LIS), SR(&SR), Index(Index) {}
82 void computeMainRangesFixFlags(
const IntEqClasses &Classes,
103 return "Rename Disconnected Subregister Components";
119char RenameIndependentSubregsLegacy::ID;
124 "Rename Independent Subregisters",
false,
false)
130bool RenameIndependentSubregs::renameComponents(
LiveInterval &LI)
const {
132 if (LI.valnos.size() < 2)
137 if (!findComponents(Classes, SubRangeInfos, LI))
146 <<
" equivalence classes.\n");
148 for (
unsigned I = 1, NumClasses = Classes.getNumClasses();
I < NumClasses;
150 Register NewVReg = MRI->createVirtualRegister(RegClass);
151 LiveInterval &NewLI = LIS->createEmptyInterval(NewVReg);
157 rewriteOperands(Classes, SubRangeInfos, Intervals);
158 distribute(Classes, SubRangeInfos, Intervals);
159 computeMainRangesFixFlags(Classes, SubRangeInfos, Intervals);
163bool RenameIndependentSubregs::findComponents(
IntEqClasses &Classes,
168 unsigned NumComponents = 0;
169 for (LiveInterval::SubRange &SR : LI.
subranges()) {
170 SubRangeInfos.
push_back(SubRangeInfo(*LIS, SR, NumComponents));
171 ConnectedVNInfoEqClasses &ConEQ = SubRangeInfos.
back().ConEQ;
173 unsigned NumSubComponents = ConEQ.
Classify(SR);
174 NumComponents += NumSubComponents;
179 if (SubRangeInfos.
size() < 2)
185 Classes.
grow(NumComponents);
188 if (!MO.isDef() && !MO.readsReg())
190 unsigned SubRegIdx = MO.getSubReg();
191 LaneBitmask LaneMask =
TRI.getSubRegIndexLaneMask(SubRegIdx);
192 unsigned MergedID = ~0
u;
193 for (RenameIndependentSubregs::SubRangeInfo &SRInfo : SubRangeInfos) {
194 const LiveInterval::SubRange &SR = *SRInfo.SR;
195 if ((SR.
LaneMask & LaneMask).none())
198 Pos = MO.isDef() ? Pos.
getRegSlot(MO.isEarlyClobber())
205 unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
207 unsigned ID = LocalID + SRInfo.Index;
209 MergedID = MergedID == ~0
u ?
ID : Classes.
join(MergedID,
ID);
216 return NumClasses > 1;
219void RenameIndependentSubregs::rewriteOperands(
const IntEqClasses &Classes,
220 const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
221 const SmallVectorImpl<LiveInterval*> &Intervals)
const {
226 MachineOperand &MO = *
I++;
235 LaneBitmask LaneMask =
TRI.getSubRegIndexLaneMask(SubRegIdx);
238 for (
const SubRangeInfo &SRInfo : SubRangeInfos) {
239 const LiveInterval::SubRange &SR = *SRInfo.SR;
240 if ((SR.
LaneMask & LaneMask).none())
247 unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
249 ID = Classes[LocalID + SRInfo.Index];
261 unsigned TiedIdx =
MI->findTiedOperandIdx(OperandNo);
262 MI->getOperand(TiedIdx).setReg(VReg);
273void RenameIndependentSubregs::distribute(
const IntEqClasses &Classes,
274 const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
275 const SmallVectorImpl<LiveInterval*> &Intervals)
const {
277 SmallVector<unsigned, 8> VNIMapping;
280 for (
const SubRangeInfo &SRInfo : SubRangeInfos) {
281 LiveInterval::SubRange &SR = *SRInfo.SR;
286 SubRanges.
resize(NumClasses-1,
nullptr);
287 for (
unsigned I = 0;
I < NumValNos; ++
I) {
288 const VNInfo &VNI = *SR.
valnos[
I];
289 unsigned LocalID = SRInfo.ConEQ.getEqClass(&VNI);
290 unsigned ID = Classes[LocalID + SRInfo.Index];
292 if (
ID > 0 && SubRanges[
ID-1] ==
nullptr)
307void RenameIndependentSubregs::computeMainRangesFixFlags(
308 const IntEqClasses &Classes,
309 const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
310 const SmallVectorImpl<LiveInterval*> &Intervals)
const {
314 for (
size_t I = 0,
E = Intervals.
size();
I <
E; ++
I) {
315 LiveInterval &LI = *Intervals[
I];
323 LaneBitmask UsedMask, UnusedMask;
324 for (LiveInterval::SubRange &SR : LI.
subranges())
326 SmallVector<unsigned> SubRegIdxs;
332 SubRegIdxs.
size() == 1) {
333 SubReg = SubRegIdxs.
front();
334 Flags = RegState::Undef;
342 bool NeedsUnusedSubrange = UnusedMask.
any();
343 for (
const LiveInterval::SubRange &SR : LI.
subranges()) {
348 const VNInfo &VNI = *SR.
valnos[
I];
361 const MCInstrDesc &MCDesc =
TII->get(TargetOpcode::IMPLICIT_DEF);
362 MachineInstrBuilder ImpDef =
367 for (LiveInterval::SubRange &SR : LI.
subranges()) {
369 SR.
addSegment(LiveRange::Segment(RegDefIdx, PredEnd, SRVNI));
371 if (NeedsUnusedSubrange) {
372 LiveInterval::SubRange *SR =
379 NeedsUnusedSubrange =
false;
421 if (!RenameIndependentSubregs(&LIS).
run(MF))
430bool RenameIndependentSubregsLegacy::runOnMachineFunction(
MachineFunction &MF) {
431 auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
432 return RenameIndependentSubregs(&LIS).
run(MF);
441 LLVM_DEBUG(
dbgs() <<
"Renaming independent subregister live ranges in "
458 Changed |= renameComponents(LI);
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
This file contains helper functions to modify live ranges.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static bool subRangeLiveAt(const LiveInterval &LI, SlotIndex Pos)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
ConnectedVNInfoEqClasses - Helper class that can divide VNInfos in a LiveInterval into equivalence cl...
LLVM_ABI unsigned Classify(const LiveRange &LR)
Classify the values in LR into connected components.
const HexagonRegisterInfo & getRegisterInfo() const
LLVM_ABI void compress()
compress - Compress equivalence classes by numbering them 0 .
unsigned getNumClasses() const
getNumClasses - Return the number of equivalence classes after compress() was called.
LLVM_ABI unsigned join(unsigned a, unsigned b)
Join the equivalence classes of a and b.
LLVM_ABI void grow(unsigned N)
grow - Increase capacity to hold 0 .
A live range for subregisters.
LiveInterval - This class represents the liveness of a register, or stack slot.
LLVM_ABI void removeEmptySubRanges()
Removes all subranges without any segments (subranges without segments are not considered valid and s...
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
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
SlotIndexes * getSlotIndexes() const
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
VNInfo::Allocator & getVNInfoAllocator()
LiveInterval & getInterval(Register Reg)
LLVM_ABI bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses.
LLVM_ABI void constructMainRangeFromSubranges(LiveInterval &LI)
For live interval LI with correct SubRanges construct matching information for the main live range.
LLVM_ABI iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
bool liveAt(SlotIndex index) const
LLVM_ABI VNInfo * createDeadDef(SlotIndex Def, VNInfo::Allocator &VNIAlloc)
createDeadDef - Make sure the range has a value defined at Def.
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.
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
unsigned getSubReg() const
LLVM_ABI unsigned getOperandNo() const
Returns the index of this operand in the instruction that it belongs to.
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register.
void setIsDead(bool Val=true)
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
void setIsUndef(bool Val=true)
bool isEarlyClobber() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
reg_nodbg_iterator reg_nodbg_begin(Register RegNo) const
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
bool subRegLivenessEnabled() const
static reg_nodbg_iterator reg_nodbg_end()
const TargetRegisterInfo * getTargetRegisterInfo() const
LLVM_ABI LaneBitmask getMaxLaneMaskForVReg(Register Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
iterator_range< reg_nodbg_iterator > reg_nodbg_operands(Register Reg) const
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
defusechain_iterator< true, true, true, true, false > reg_nodbg_iterator
reg_nodbg_iterator/reg_nodbg_begin/reg_nodbg_end - Walk all defs and uses of the specified register,...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
SlotIndex - An opaque wrapper around machine indexes.
SlotIndex getDeadSlot() const
Returns the dead def kill slot for the current instruction.
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
SlotIndex getPrevSlot() const
Returns the previous slot in the index list.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &)
MachineBasicBlock * getMBBFromIndex(SlotIndex index) const
Returns the basic block which the given index falls in.
SlotIndex getMBBEndIdx(unsigned Num) const
Returns the index past the last valid index in the given basic block.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
virtual const TargetInstrInfo * getInstrInfo() const
bool isUnused() const
Returns true if this value is unused.
SlotIndex def
The index of the defining instruction.
bool isPHIDef() const
Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
RegState
Flags to represent properties of register accesses.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
static void DistributeRange(LiveRangeT &LR, LiveRangeT *SplitLRs[], EqClassesT VNIClasses)
Helper function that distributes live range value numbers and the corresponding segments of a primary...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
MachineBasicBlock::iterator findPHICopyInsertPoint(MachineBasicBlock *MBB, MachineBasicBlock *SuccMBB, Register SrcReg)
findPHICopyInsertPoint - Find a safe place in MBB to insert a copy from SrcReg when following the CFG...
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
LLVM_ABI char & RenameIndependentSubregsID
This pass detects subregister lanes in a virtual register that are used independently of other lanes ...
LLVM_ABI 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.
MCRegisterClass TargetRegisterClass
constexpr bool any() const