LLVM: lib/CodeGen/RenameIndependentSubregs.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
40
41using namespace llvm;
42
43#define DEBUG_TYPE "rename-independent-subregs"
44
45namespace {
46
47class RenameIndependentSubregs {
48public:
49 RenameIndependentSubregs(LiveIntervals *LIS) : LIS(LIS) {}
50
52
53private:
54 struct SubRangeInfo {
57 unsigned Index;
58
60 unsigned Index)
61 : ConEQ(LIS), SR(&SR), Index(Index) {}
62 };
63
64
65 bool renameComponents(LiveInterval &LI) const;
66
67
68
69
73
74
75
79
80
81 void computeMainRangesFixFlags(const IntEqClasses &Classes,
84
85
86 void rewriteOperands(const IntEqClasses &Classes,
89
90
94};
95
97public:
98 static char ID;
101 StringRef getPassName() const override {
102 return "Rename Disconnected Subregister Components";
103 }
104
105 void getAnalysisUsage(AnalysisUsage &AU) const override {
112 }
113};
114
115}
116
117char RenameIndependentSubregsLegacy::ID;
118
120
122 "Rename Independent Subregisters", false, false)
127
128bool RenameIndependentSubregs::renameComponents(LiveInterval &LI) const {
129
130 if (LI.valnos.size() < 2)
131 return false;
132
135 if (!findComponents(Classes, SubRangeInfos, LI))
136 return false;
137
138
144 << " equivalence classes.\n");
146 for (unsigned I = 1, NumClasses = Classes.getNumClasses(); I < NumClasses;
147 ++I) {
148 Register NewVReg = MRI->createVirtualRegister(RegClass);
149 LiveInterval &NewLI = LIS->createEmptyInterval(NewVReg);
152 }
154
155 rewriteOperands(Classes, SubRangeInfos, Intervals);
156 distribute(Classes, SubRangeInfos, Intervals);
157 computeMainRangesFixFlags(Classes, SubRangeInfos, Intervals);
158 return true;
159}
160
161bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes,
164
165
166 unsigned NumComponents = 0;
167 for (LiveInterval::SubRange &SR : LI.subranges()) {
168 SubRangeInfos.push_back(SubRangeInfo(*LIS, SR, NumComponents));
169 ConnectedVNInfoEqClasses &ConEQ = SubRangeInfos.back().ConEQ;
170
171 unsigned NumSubComponents = ConEQ.Classify(SR);
172 NumComponents += NumSubComponents;
173 }
174
175
176
177 if (SubRangeInfos.size() < 2)
178 return false;
179
180
181
182 const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
183 Classes.grow(NumComponents);
185 for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
186 if (!MO.isDef() && !MO.readsReg())
187 continue;
188 unsigned SubRegIdx = MO.getSubReg();
189 LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
190 unsigned MergedID = ~0u;
191 for (RenameIndependentSubregs::SubRangeInfo &SRInfo : SubRangeInfos) {
192 const LiveInterval::SubRange &SR = *SRInfo.SR;
193 if ((SR.LaneMask & LaneMask).none())
194 continue;
196 Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber())
199 if (VNI == nullptr)
200 continue;
201
202
203 unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
204
205 unsigned ID = LocalID + SRInfo.Index;
206
207 MergedID = MergedID == ~0u ? ID : Classes.join(MergedID, ID);
208 }
209 }
210
211
214 return NumClasses > 1;
215}
216
217void RenameIndependentSubregs::rewriteOperands(const IntEqClasses &Classes,
218 const SmallVectorImpl &SubRangeInfos,
219 const SmallVectorImpl<LiveInterval*> &Intervals) const {
220 const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
223 E = MRI->reg_nodbg_end(); I != E; ) {
224 MachineOperand &MO = *I++;
226 continue;
227
232 unsigned SubRegIdx = MO.getSubReg();
233 LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
234
236 for (const SubRangeInfo &SRInfo : SubRangeInfos) {
237 const LiveInterval::SubRange &SR = *SRInfo.SR;
238 if ((SR.LaneMask & LaneMask).none())
239 continue;
241 if (VNI == nullptr)
242 continue;
243
244
245 unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
246
247 ID = Classes[LocalID + SRInfo.Index];
248 break;
249 }
250
251 Register VReg = Intervals[ID]->reg();
253
254 if (MO.isTied() && Reg != VReg) {
255
256
257
259 unsigned TiedIdx = MI->findTiedOperandIdx(OperandNo);
260 MI->getOperand(TiedIdx).setReg(VReg);
261
262
263 I = MRI->reg_nodbg_begin(Reg);
264 }
265 }
266
267
268
269}
270
271void RenameIndependentSubregs::distribute(const IntEqClasses &Classes,
272 const SmallVectorImpl &SubRangeInfos,
273 const SmallVectorImpl<LiveInterval*> &Intervals) const {
275 SmallVector<unsigned, 8> VNIMapping;
278 for (const SubRangeInfo &SRInfo : SubRangeInfos) {
279 LiveInterval::SubRange &SR = *SRInfo.SR;
280 unsigned NumValNos = SR.valnos.size();
281 VNIMapping.clear();
282 VNIMapping.reserve(NumValNos);
283 SubRanges.clear();
284 SubRanges.resize(NumClasses-1, nullptr);
285 for (unsigned I = 0; I < NumValNos; ++I) {
286 const VNInfo &VNI = *SR.valnos[I];
287 unsigned LocalID = SRInfo.ConEQ.getEqClass(&VNI);
288 unsigned ID = Classes[LocalID + SRInfo.Index];
290 if (ID > 0 && SubRanges[ID-1] == nullptr)
292 }
294 }
295}
296
300 return true;
301 }
302 return false;
303}
304
305void RenameIndependentSubregs::computeMainRangesFixFlags(
306 const IntEqClasses &Classes,
307 const SmallVectorImpl &SubRangeInfos,
308 const SmallVectorImpl<LiveInterval*> &Intervals) const {
312 for (size_t I = 0, E = Intervals.size(); I < E; ++I) {
313 LiveInterval &LI = *Intervals[I];
315
317
318
319
320
321 LaneBitmask UsedMask, UnusedMask;
322 for (LiveInterval::SubRange &SR : LI.subranges())
324 SmallVector SubRegIdxs;
325 unsigned Flags = 0;
327
328 if (TRI.getCoveringSubRegIndexes(MRI->getRegClass(Reg), UsedMask,
329 SubRegIdxs) &&
330 SubRegIdxs.size() == 1) {
333 } else {
334 UnusedMask = MRI->getMaxLaneMaskForVReg(Reg) & ~UsedMask;
335 }
336
337
338
339
340 for (const LiveInterval::SubRange &SR : LI.subranges()) {
341
342
343
344 for (unsigned I = 0; I < SR.valnos.size(); ++I) {
345 const VNInfo &VNI = *SR.valnos[I];
347 continue;
348
352 SlotIndex PredEnd = Indexes.getMBBEndIdx(PredMBB);
354 continue;
355
358 const MCInstrDesc &MCDesc = TII->get(TargetOpcode::IMPLICIT_DEF);
359 MachineInstrBuilder ImpDef =
363 SlotIndex RegDefIdx = DefIdx.getRegSlot();
364 for (LiveInterval::SubRange &SR : LI.subranges()) {
366 SR.addSegment(LiveRange::Segment(RegDefIdx, PredEnd, SRVNI));
367 }
368 if (!UnusedMask.none()) {
369 LiveInterval::SubRange *SR =
372 }
373 }
374 }
375 }
376
377 for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
379 continue;
380 unsigned SubRegIdx = MO.getSubReg();
381 if (SubRegIdx == 0)
382 continue;
383
384
385
390 }
395 }
396 }
397
398 if (I == 0)
401
402
403
404
406 }
407}
408
409PreservedAnalyses
413 if (!RenameIndependentSubregs(&LIS).run(MF))
419 return PA;
420}
421
422bool RenameIndependentSubregsLegacy::runOnMachineFunction(MachineFunction &MF) {
423 auto &LIS = getAnalysis().getLIS();
424 return RenameIndependentSubregs(&LIS).run(MF);
425}
426
428
430 if (->subRegLivenessEnabled())
431 return false;
432
433 LLVM_DEBUG(dbgs() << "Renaming independent subregister live ranges in "
434 << MF.getName() << '\n');
435
437
438
439
440
442 for (size_t I = 0, E = MRI->getNumVirtRegs(); I < E; ++I) {
445 continue;
448 continue;
449
450 Changed |= renameComponents(LI);
451 }
452
454}
unsigned const MachineRegisterInfo * MRI
const TargetInstrInfo & TII
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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)
Definition RenameIndependentSubregs.cpp:297
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.
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.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
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, unsigned Flags=0, 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,...
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.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Definition RenameIndependentSubregs.cpp:410
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.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
const TargetRegisterInfo & getRegisterInfo() const
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.
@ Undef
Value of the register doesn't matter.
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.
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 ...
Definition RenameIndependentSubregs.cpp:119
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.
constexpr bool none() const