xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/RenameIndependentSubregs.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
1 //===-- RenameIndependentSubregs.cpp - Live Interval Analysis -------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// Rename independent subregisters looks for virtual registers with
10 /// independently used subregisters and renames them to new virtual registers.
11 /// Example: In the following:
12 ///   %0:sub0<read-undef> = ...
13 ///   %0:sub1 = ...
14 ///   use %0:sub0
15 ///   %0:sub0 = ...
16 ///   use %0:sub0
17 ///   use %0:sub1
18 /// sub0 and sub1 are never used together, and we have two independent sub0
19 /// definitions. This pass will rename to:
20 ///   %0:sub0<read-undef> = ...
21 ///   %1:sub1<read-undef> = ...
22 ///   use %1:sub1
23 ///   %2:sub1<read-undef> = ...
24 ///   use %2:sub1
25 ///   use %0:sub0
26 //
27 //===----------------------------------------------------------------------===//
28 
29 #include "llvm/CodeGen/RenameIndependentSubregs.h"
30 #include "LiveRangeUtils.h"
31 #include "PHIEliminationUtils.h"
32 #include "llvm/CodeGen/LiveInterval.h"
33 #include "llvm/CodeGen/LiveIntervals.h"
34 #include "llvm/CodeGen/MachineFunctionPass.h"
35 #include "llvm/CodeGen/MachineInstrBuilder.h"
36 #include "llvm/CodeGen/MachineRegisterInfo.h"
37 #include "llvm/CodeGen/TargetInstrInfo.h"
38 #include "llvm/InitializePasses.h"
39 #include "llvm/Pass.h"
40 
41 using namespace llvm;
42 
43 #define DEBUG_TYPE "rename-independent-subregs"
44 
45 namespace {
46 
47 class RenameIndependentSubregs {
48 public:
49   RenameIndependentSubregs(LiveIntervals *LIS) : LIS(LIS) {}
50 
51   bool run(MachineFunction &MF);
52 
53 private:
54   struct SubRangeInfo {
55     ConnectedVNInfoEqClasses ConEQ;
56     LiveInterval::SubRange *SR;
57     unsigned Index;
58 
59     SubRangeInfo(LiveIntervals &LIS, LiveInterval::SubRange &SR,
60                  unsigned Index)
61       : ConEQ(LIS), SR(&SR), Index(Index) {}
62   };
63 
64   /// Split unrelated subregister components and rename them to new vregs.
65   bool renameComponents(LiveInterval &LI) const;
66 
67   /// Build a vector of SubRange infos and a union find set of
68   /// equivalence classes.
69   /// Returns true if more than 1 equivalence class was found.
70   bool findComponents(IntEqClasses &Classes,
71                       SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
72                       LiveInterval &LI) const;
73 
74   /// Distribute the LiveInterval segments into the new LiveIntervals
75   /// belonging to their class.
76   void distribute(const IntEqClasses &Classes,
77                   const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
78                   const SmallVectorImpl<LiveInterval*> &Intervals) const;
79 
80   /// Constructs main liverange and add missing undef+dead flags.
81   void computeMainRangesFixFlags(const IntEqClasses &Classes,
82       const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
83       const SmallVectorImpl<LiveInterval*> &Intervals) const;
84 
85   /// Rewrite Machine Operands to use the new vreg belonging to their class.
86   void rewriteOperands(const IntEqClasses &Classes,
87                        const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
88                        const SmallVectorImpl<LiveInterval*> &Intervals) const;
89 
90 
91   LiveIntervals *LIS = nullptr;
92   MachineRegisterInfo *MRI = nullptr;
93   const TargetInstrInfo *TII = nullptr;
94 };
95 
96 class RenameIndependentSubregsLegacy : public MachineFunctionPass {
97 public:
98   static char ID;
99   RenameIndependentSubregsLegacy() : MachineFunctionPass(ID) {}
100   bool runOnMachineFunction(MachineFunction &MF) override;
101   StringRef getPassName() const override {
102     return "Rename Disconnected Subregister Components";
103   }
104 
105   void getAnalysisUsage(AnalysisUsage &AU) const override {
106     AU.setPreservesCFG();
107     AU.addRequired<LiveIntervalsWrapperPass>();
108     AU.addPreserved<LiveIntervalsWrapperPass>();
109     AU.addRequired<SlotIndexesWrapperPass>();
110     AU.addPreserved<SlotIndexesWrapperPass>();
111     MachineFunctionPass::getAnalysisUsage(AU);
112   }
113 };
114 
115 } // end anonymous namespace
116 
117 char RenameIndependentSubregsLegacy::ID;
118 
119 char &llvm::RenameIndependentSubregsID = RenameIndependentSubregsLegacy::ID;
120 
121 INITIALIZE_PASS_BEGIN(RenameIndependentSubregsLegacy, DEBUG_TYPE,
122                       "Rename Independent Subregisters", false, false)
123 INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
124 INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
125 INITIALIZE_PASS_END(RenameIndependentSubregsLegacy, DEBUG_TYPE,
126                     "Rename Independent Subregisters", false, false)
127 
128 bool RenameIndependentSubregs::renameComponents(LiveInterval &LI) const {
129   // Shortcut: We cannot have split components with a single definition.
130   if (LI.valnos.size() < 2)
131     return false;
132 
133   SmallVector<SubRangeInfo, 4> SubRangeInfos;
134   IntEqClasses Classes;
135   if (!findComponents(Classes, SubRangeInfos, LI))
136     return false;
137 
138   // Create a new VReg for each class.
139   Register Reg = LI.reg();
140   const TargetRegisterClass *RegClass = MRI->getRegClass(Reg);
141   SmallVector<LiveInterval*, 4> Intervals;
142   Intervals.push_back(&LI);
143   LLVM_DEBUG(dbgs() << printReg(Reg) << ": Found " << Classes.getNumClasses()
144                     << " equivalence classes.\n");
145   LLVM_DEBUG(dbgs() << printReg(Reg) << ": Splitting into newly created:");
146   for (unsigned I = 1, NumClasses = Classes.getNumClasses(); I < NumClasses;
147        ++I) {
148     Register NewVReg = MRI->createVirtualRegister(RegClass);
149     LiveInterval &NewLI = LIS->createEmptyInterval(NewVReg);
150     Intervals.push_back(&NewLI);
151     LLVM_DEBUG(dbgs() << ' ' << printReg(NewVReg));
152   }
153   LLVM_DEBUG(dbgs() << '\n');
154 
155   rewriteOperands(Classes, SubRangeInfos, Intervals);
156   distribute(Classes, SubRangeInfos, Intervals);
157   computeMainRangesFixFlags(Classes, SubRangeInfos, Intervals);
158   return true;
159 }
160 
161 bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes,
162     SmallVectorImpl<RenameIndependentSubregs::SubRangeInfo> &SubRangeInfos,
163     LiveInterval &LI) const {
164   // First step: Create connected components for the VNInfos inside the
165   // subranges and count the global number of such components.
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   // Shortcut: With only 1 subrange, the normal separate component tests are
175   // enough and we do not need to perform the union-find on the subregister
176   // segments.
177   if (SubRangeInfos.size() < 2)
178     return false;
179 
180   // Next step: Build union-find structure over all subranges and merge classes
181   // across subranges when they are affected by the same MachineOperand.
182   const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
183   Classes.grow(NumComponents);
184   Register Reg = LI.reg();
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;
195       SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
196       Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber())
197                        : Pos.getBaseIndex();
198       const VNInfo *VNI = SR.getVNInfoAt(Pos);
199       if (VNI == nullptr)
200         continue;
201 
202       // Map to local representant ID.
203       unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
204       // Global ID
205       unsigned ID = LocalID + SRInfo.Index;
206       // Merge other sets
207       MergedID = MergedID == ~0u ? ID : Classes.join(MergedID, ID);
208     }
209   }
210 
211   // Early exit if we ended up with a single equivalence class.
212   Classes.compress();
213   unsigned NumClasses = Classes.getNumClasses();
214   return NumClasses > 1;
215 }
216 
217 void RenameIndependentSubregs::rewriteOperands(const IntEqClasses &Classes,
218     const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
219     const SmallVectorImpl<LiveInterval*> &Intervals) const {
220   const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
221   Register Reg = Intervals[0]->reg();
222   for (MachineRegisterInfo::reg_nodbg_iterator I = MRI->reg_nodbg_begin(Reg),
223        E = MRI->reg_nodbg_end(); I != E; ) {
224     MachineOperand &MO = *I++;
225     if (!MO.isDef() && !MO.readsReg())
226       continue;
227 
228     auto *MI = MO.getParent();
229     SlotIndex Pos = LIS->getInstructionIndex(*MI);
230     Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber())
231                      : Pos.getBaseIndex();
232     unsigned SubRegIdx = MO.getSubReg();
233     LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
234 
235     unsigned ID = ~0u;
236     for (const SubRangeInfo &SRInfo : SubRangeInfos) {
237       const LiveInterval::SubRange &SR = *SRInfo.SR;
238       if ((SR.LaneMask & LaneMask).none())
239         continue;
240       const VNInfo *VNI = SR.getVNInfoAt(Pos);
241       if (VNI == nullptr)
242         continue;
243 
244       // Map to local representant ID.
245       unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
246       // Global ID
247       ID = Classes[LocalID + SRInfo.Index];
248       break;
249     }
250 
251     Register VReg = Intervals[ID]->reg();
252     MO.setReg(VReg);
253 
254     if (MO.isTied() && Reg != VReg) {
255       /// Undef use operands are not tracked in the equivalence class,
256       /// but need to be updated if they are tied; take care to only
257       /// update the tied operand.
258       unsigned OperandNo = MO.getOperandNo();
259       unsigned TiedIdx = MI->findTiedOperandIdx(OperandNo);
260       MI->getOperand(TiedIdx).setReg(VReg);
261 
262       // above substitution breaks the iterator, so restart.
263       I = MRI->reg_nodbg_begin(Reg);
264     }
265   }
266   // TODO: We could attempt to recompute new register classes while visiting
267   // the operands: Some of the split register may be fine with less constraint
268   // classes than the original vreg.
269 }
270 
271 void RenameIndependentSubregs::distribute(const IntEqClasses &Classes,
272     const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
273     const SmallVectorImpl<LiveInterval*> &Intervals) const {
274   unsigned NumClasses = Classes.getNumClasses();
275   SmallVector<unsigned, 8> VNIMapping;
276   SmallVector<LiveInterval::SubRange*, 8> SubRanges;
277   BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
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];
289       VNIMapping.push_back(ID);
290       if (ID > 0 && SubRanges[ID-1] == nullptr)
291         SubRanges[ID-1] = Intervals[ID]->createSubRange(Allocator, SR.LaneMask);
292     }
293     DistributeRange(SR, SubRanges.data(), VNIMapping);
294   }
295 }
296 
297 static bool subRangeLiveAt(const LiveInterval &LI, SlotIndex Pos) {
298   for (const LiveInterval::SubRange &SR : LI.subranges()) {
299     if (SR.liveAt(Pos))
300       return true;
301   }
302   return false;
303 }
304 
305 void RenameIndependentSubregs::computeMainRangesFixFlags(
306     const IntEqClasses &Classes,
307     const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
308     const SmallVectorImpl<LiveInterval*> &Intervals) const {
309   BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
310   const SlotIndexes &Indexes = *LIS->getSlotIndexes();
311   for (size_t I = 0, E = Intervals.size(); I < E; ++I) {
312     LiveInterval &LI = *Intervals[I];
313     Register Reg = LI.reg();
314 
315     LI.removeEmptySubRanges();
316 
317     // There must be a def (or live-in) before every use. Splitting vregs may
318     // violate this principle as the splitted vreg may not have a definition on
319     // every path. Fix this by creating IMPLICIT_DEF instruction as necessary.
320     for (const LiveInterval::SubRange &SR : LI.subranges()) {
321       // Search for "PHI" value numbers in the subranges. We must find a live
322       // value in each predecessor block, add an IMPLICIT_DEF where it is
323       // missing.
324       for (unsigned I = 0; I < SR.valnos.size(); ++I) {
325         const VNInfo &VNI = *SR.valnos[I];
326         if (VNI.isUnused() || !VNI.isPHIDef())
327           continue;
328 
329         SlotIndex Def = VNI.def;
330         MachineBasicBlock &MBB = *Indexes.getMBBFromIndex(Def);
331         for (MachineBasicBlock *PredMBB : MBB.predecessors()) {
332           SlotIndex PredEnd = Indexes.getMBBEndIdx(PredMBB);
333           if (subRangeLiveAt(LI, PredEnd.getPrevSlot()))
334             continue;
335 
336           MachineBasicBlock::iterator InsertPos =
337             llvm::findPHICopyInsertPoint(PredMBB, &MBB, Reg);
338           const MCInstrDesc &MCDesc = TII->get(TargetOpcode::IMPLICIT_DEF);
339           MachineInstrBuilder ImpDef = BuildMI(*PredMBB, InsertPos,
340                                                DebugLoc(), MCDesc, Reg);
341           SlotIndex DefIdx = LIS->InsertMachineInstrInMaps(*ImpDef);
342           SlotIndex RegDefIdx = DefIdx.getRegSlot();
343           LaneBitmask Mask = MRI->getMaxLaneMaskForVReg(Reg);
344           for (LiveInterval::SubRange &SR : LI.subranges()) {
345             Mask = Mask & ~SR.LaneMask;
346             VNInfo *SRVNI = SR.getNextValue(RegDefIdx, Allocator);
347             SR.addSegment(LiveRange::Segment(RegDefIdx, PredEnd, SRVNI));
348           }
349 
350           if (!Mask.none()) {
351             LiveInterval::SubRange *SR = LI.createSubRange(Allocator, Mask);
352             SR->createDeadDef(RegDefIdx, Allocator);
353           }
354         }
355       }
356     }
357 
358     for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
359       if (!MO.isDef())
360         continue;
361       unsigned SubRegIdx = MO.getSubReg();
362       if (SubRegIdx == 0)
363         continue;
364       // After assigning the new vreg we may not have any other sublanes living
365       // in and out of the instruction anymore. We need to add new dead and
366       // undef flags in these cases.
367       if (!MO.isUndef()) {
368         SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
369         if (!subRangeLiveAt(LI, Pos))
370           MO.setIsUndef();
371       }
372       if (!MO.isDead()) {
373         SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()).getDeadSlot();
374         if (!subRangeLiveAt(LI, Pos))
375           MO.setIsDead();
376       }
377     }
378 
379     if (I == 0)
380       LI.clear();
381     LIS->constructMainRangeFromSubranges(LI);
382     // A def of a subregister may be a use of other register lanes. Replacing
383     // such a def with a def of a different register will eliminate the use,
384     // and may cause the recorded live range to be larger than the actual
385     // liveness in the program IR.
386     LIS->shrinkToUses(&LI);
387   }
388 }
389 
390 PreservedAnalyses
391 RenameIndependentSubregsPass::run(MachineFunction &MF,
392                                   MachineFunctionAnalysisManager &MFAM) {
393   auto &LIS = MFAM.getResult<LiveIntervalsAnalysis>(MF);
394   if (!RenameIndependentSubregs(&LIS).run(MF))
395     return PreservedAnalyses::all();
396   auto PA = getMachineFunctionPassPreservedAnalyses();
397   PA.preserveSet<CFGAnalyses>();
398   PA.preserve<LiveIntervalsAnalysis>();
399   PA.preserve<SlotIndexesAnalysis>();
400   return PA;
401 }
402 
403 bool RenameIndependentSubregsLegacy::runOnMachineFunction(MachineFunction &MF) {
404   auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
405   return RenameIndependentSubregs(&LIS).run(MF);
406 }
407 
408 bool RenameIndependentSubregs::run(MachineFunction &MF) {
409   // Skip renaming if liveness of subregister is not tracked.
410   MRI = &MF.getRegInfo();
411   if (!MRI->subRegLivenessEnabled())
412     return false;
413 
414   LLVM_DEBUG(dbgs() << "Renaming independent subregister live ranges in "
415                     << MF.getName() << '\n');
416 
417   TII = MF.getSubtarget().getInstrInfo();
418 
419   // Iterate over all vregs. Note that we query getNumVirtRegs() the newly
420   // created vregs end up with higher numbers but do not need to be visited as
421   // there can't be any further splitting.
422   bool Changed = false;
423   for (size_t I = 0, E = MRI->getNumVirtRegs(); I < E; ++I) {
424     Register Reg = Register::index2VirtReg(I);
425     if (!LIS->hasInterval(Reg))
426       continue;
427     LiveInterval &LI = LIS->getInterval(Reg);
428     if (!LI.hasSubRanges())
429       continue;
430 
431     Changed |= renameComponents(LI);
432   }
433 
434   return Changed;
435 }
436