xref: /aosp_15_r20/external/llvm/lib/CodeGen/RenameIndependentSubregs.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- RenameIndependentSubregs.cpp - Live Interval Analysis -------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker /// Rename independent subregisters looks for virtual registers with
11*9880d681SAndroid Build Coastguard Worker /// independently used subregisters and renames them to new virtual registers.
12*9880d681SAndroid Build Coastguard Worker /// Example: In the following:
13*9880d681SAndroid Build Coastguard Worker ///   %vreg0:sub0<read-undef> = ...
14*9880d681SAndroid Build Coastguard Worker ///   %vreg0:sub1 = ...
15*9880d681SAndroid Build Coastguard Worker ///   use %vreg0:sub0
16*9880d681SAndroid Build Coastguard Worker ///   %vreg0:sub0 = ...
17*9880d681SAndroid Build Coastguard Worker ///   use %vreg0:sub0
18*9880d681SAndroid Build Coastguard Worker ///   use %vreg0:sub1
19*9880d681SAndroid Build Coastguard Worker /// sub0 and sub1 are never used together, and we have two independent sub0
20*9880d681SAndroid Build Coastguard Worker /// definitions. This pass will rename to:
21*9880d681SAndroid Build Coastguard Worker ///   %vreg0:sub0<read-undef> = ...
22*9880d681SAndroid Build Coastguard Worker ///   %vreg1:sub1<read-undef> = ...
23*9880d681SAndroid Build Coastguard Worker ///   use %vreg1:sub1
24*9880d681SAndroid Build Coastguard Worker ///   %vreg2:sub1<read-undef> = ...
25*9880d681SAndroid Build Coastguard Worker ///   use %vreg2:sub1
26*9880d681SAndroid Build Coastguard Worker ///   use %vreg0:sub0
27*9880d681SAndroid Build Coastguard Worker //
28*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
29*9880d681SAndroid Build Coastguard Worker 
30*9880d681SAndroid Build Coastguard Worker #include "LiveRangeUtils.h"
31*9880d681SAndroid Build Coastguard Worker #include "PHIEliminationUtils.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LiveInterval.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LiveIntervalAnalysis.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
39*9880d681SAndroid Build Coastguard Worker 
40*9880d681SAndroid Build Coastguard Worker using namespace llvm;
41*9880d681SAndroid Build Coastguard Worker 
42*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "rename-independent-subregs"
43*9880d681SAndroid Build Coastguard Worker 
44*9880d681SAndroid Build Coastguard Worker namespace {
45*9880d681SAndroid Build Coastguard Worker 
46*9880d681SAndroid Build Coastguard Worker class RenameIndependentSubregs : public MachineFunctionPass {
47*9880d681SAndroid Build Coastguard Worker public:
48*9880d681SAndroid Build Coastguard Worker   static char ID;
RenameIndependentSubregs()49*9880d681SAndroid Build Coastguard Worker   RenameIndependentSubregs() : MachineFunctionPass(ID) {}
50*9880d681SAndroid Build Coastguard Worker 
getPassName() const51*9880d681SAndroid Build Coastguard Worker   const char *getPassName() const override {
52*9880d681SAndroid Build Coastguard Worker     return "Rename Disconnected Subregister Components";
53*9880d681SAndroid Build Coastguard Worker   }
54*9880d681SAndroid Build Coastguard Worker 
getAnalysisUsage(AnalysisUsage & AU) const55*9880d681SAndroid Build Coastguard Worker   void getAnalysisUsage(AnalysisUsage &AU) const override {
56*9880d681SAndroid Build Coastguard Worker     AU.setPreservesCFG();
57*9880d681SAndroid Build Coastguard Worker     AU.addRequired<LiveIntervals>();
58*9880d681SAndroid Build Coastguard Worker     AU.addPreserved<LiveIntervals>();
59*9880d681SAndroid Build Coastguard Worker     AU.addRequired<SlotIndexes>();
60*9880d681SAndroid Build Coastguard Worker     AU.addPreserved<SlotIndexes>();
61*9880d681SAndroid Build Coastguard Worker     MachineFunctionPass::getAnalysisUsage(AU);
62*9880d681SAndroid Build Coastguard Worker   }
63*9880d681SAndroid Build Coastguard Worker 
64*9880d681SAndroid Build Coastguard Worker   bool runOnMachineFunction(MachineFunction &MF) override;
65*9880d681SAndroid Build Coastguard Worker 
66*9880d681SAndroid Build Coastguard Worker private:
67*9880d681SAndroid Build Coastguard Worker   struct SubRangeInfo {
68*9880d681SAndroid Build Coastguard Worker     ConnectedVNInfoEqClasses ConEQ;
69*9880d681SAndroid Build Coastguard Worker     LiveInterval::SubRange *SR;
70*9880d681SAndroid Build Coastguard Worker     unsigned Index;
71*9880d681SAndroid Build Coastguard Worker 
SubRangeInfo__anon03a26c4d0111::RenameIndependentSubregs::SubRangeInfo72*9880d681SAndroid Build Coastguard Worker     SubRangeInfo(LiveIntervals &LIS, LiveInterval::SubRange &SR,
73*9880d681SAndroid Build Coastguard Worker                  unsigned Index)
74*9880d681SAndroid Build Coastguard Worker       : ConEQ(LIS), SR(&SR), Index(Index) {}
75*9880d681SAndroid Build Coastguard Worker   };
76*9880d681SAndroid Build Coastguard Worker 
77*9880d681SAndroid Build Coastguard Worker   /// Split unrelated subregister components and rename them to new vregs.
78*9880d681SAndroid Build Coastguard Worker   bool renameComponents(LiveInterval &LI) const;
79*9880d681SAndroid Build Coastguard Worker 
80*9880d681SAndroid Build Coastguard Worker   /// \brief Build a vector of SubRange infos and a union find set of
81*9880d681SAndroid Build Coastguard Worker   /// equivalence classes.
82*9880d681SAndroid Build Coastguard Worker   /// Returns true if more than 1 equivalence class was found.
83*9880d681SAndroid Build Coastguard Worker   bool findComponents(IntEqClasses &Classes,
84*9880d681SAndroid Build Coastguard Worker                       SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
85*9880d681SAndroid Build Coastguard Worker                       LiveInterval &LI) const;
86*9880d681SAndroid Build Coastguard Worker 
87*9880d681SAndroid Build Coastguard Worker   /// \brief Distribute the LiveInterval segments into the new LiveIntervals
88*9880d681SAndroid Build Coastguard Worker   /// belonging to their class.
89*9880d681SAndroid Build Coastguard Worker   void distribute(const IntEqClasses &Classes,
90*9880d681SAndroid Build Coastguard Worker                   const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
91*9880d681SAndroid Build Coastguard Worker                   const SmallVectorImpl<LiveInterval*> &Intervals) const;
92*9880d681SAndroid Build Coastguard Worker 
93*9880d681SAndroid Build Coastguard Worker   /// \brief Constructs main liverange and add missing undef+dead flags.
94*9880d681SAndroid Build Coastguard Worker   void computeMainRangesFixFlags(const IntEqClasses &Classes,
95*9880d681SAndroid Build Coastguard Worker       const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
96*9880d681SAndroid Build Coastguard Worker       const SmallVectorImpl<LiveInterval*> &Intervals) const;
97*9880d681SAndroid Build Coastguard Worker 
98*9880d681SAndroid Build Coastguard Worker   /// Rewrite Machine Operands to use the new vreg belonging to their class.
99*9880d681SAndroid Build Coastguard Worker   void rewriteOperands(const IntEqClasses &Classes,
100*9880d681SAndroid Build Coastguard Worker                        const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
101*9880d681SAndroid Build Coastguard Worker                        const SmallVectorImpl<LiveInterval*> &Intervals) const;
102*9880d681SAndroid Build Coastguard Worker 
103*9880d681SAndroid Build Coastguard Worker 
104*9880d681SAndroid Build Coastguard Worker   LiveIntervals *LIS;
105*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo *MRI;
106*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo *TII;
107*9880d681SAndroid Build Coastguard Worker };
108*9880d681SAndroid Build Coastguard Worker 
109*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
110*9880d681SAndroid Build Coastguard Worker 
111*9880d681SAndroid Build Coastguard Worker char RenameIndependentSubregs::ID;
112*9880d681SAndroid Build Coastguard Worker 
113*9880d681SAndroid Build Coastguard Worker char &llvm::RenameIndependentSubregsID = RenameIndependentSubregs::ID;
114*9880d681SAndroid Build Coastguard Worker 
115*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_BEGIN(RenameIndependentSubregs, "rename-independent-subregs",
116*9880d681SAndroid Build Coastguard Worker                       "Rename Independent Subregisters", false, false)
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)117*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
118*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
119*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_END(RenameIndependentSubregs, "rename-independent-subregs",
120*9880d681SAndroid Build Coastguard Worker                     "Rename Independent Subregisters", false, false)
121*9880d681SAndroid Build Coastguard Worker 
122*9880d681SAndroid Build Coastguard Worker bool RenameIndependentSubregs::renameComponents(LiveInterval &LI) const {
123*9880d681SAndroid Build Coastguard Worker   // Shortcut: We cannot have split components with a single definition.
124*9880d681SAndroid Build Coastguard Worker   if (LI.valnos.size() < 2)
125*9880d681SAndroid Build Coastguard Worker     return false;
126*9880d681SAndroid Build Coastguard Worker 
127*9880d681SAndroid Build Coastguard Worker   SmallVector<SubRangeInfo, 4> SubRangeInfos;
128*9880d681SAndroid Build Coastguard Worker   IntEqClasses Classes;
129*9880d681SAndroid Build Coastguard Worker   if (!findComponents(Classes, SubRangeInfos, LI))
130*9880d681SAndroid Build Coastguard Worker     return false;
131*9880d681SAndroid Build Coastguard Worker 
132*9880d681SAndroid Build Coastguard Worker   // Create a new VReg for each class.
133*9880d681SAndroid Build Coastguard Worker   unsigned Reg = LI.reg;
134*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *RegClass = MRI->getRegClass(Reg);
135*9880d681SAndroid Build Coastguard Worker   SmallVector<LiveInterval*, 4> Intervals;
136*9880d681SAndroid Build Coastguard Worker   Intervals.push_back(&LI);
137*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << PrintReg(Reg) << ": Found " << Classes.getNumClasses()
138*9880d681SAndroid Build Coastguard Worker         << " equivalence classes.\n");
139*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << PrintReg(Reg) << ": Splitting into newly created:");
140*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 1, NumClasses = Classes.getNumClasses(); I < NumClasses;
141*9880d681SAndroid Build Coastguard Worker        ++I) {
142*9880d681SAndroid Build Coastguard Worker     unsigned NewVReg = MRI->createVirtualRegister(RegClass);
143*9880d681SAndroid Build Coastguard Worker     LiveInterval &NewLI = LIS->createEmptyInterval(NewVReg);
144*9880d681SAndroid Build Coastguard Worker     Intervals.push_back(&NewLI);
145*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << ' ' << PrintReg(NewVReg));
146*9880d681SAndroid Build Coastguard Worker   }
147*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << '\n');
148*9880d681SAndroid Build Coastguard Worker 
149*9880d681SAndroid Build Coastguard Worker   rewriteOperands(Classes, SubRangeInfos, Intervals);
150*9880d681SAndroid Build Coastguard Worker   distribute(Classes, SubRangeInfos, Intervals);
151*9880d681SAndroid Build Coastguard Worker   computeMainRangesFixFlags(Classes, SubRangeInfos, Intervals);
152*9880d681SAndroid Build Coastguard Worker   return true;
153*9880d681SAndroid Build Coastguard Worker }
154*9880d681SAndroid Build Coastguard Worker 
findComponents(IntEqClasses & Classes,SmallVectorImpl<RenameIndependentSubregs::SubRangeInfo> & SubRangeInfos,LiveInterval & LI) const155*9880d681SAndroid Build Coastguard Worker bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes,
156*9880d681SAndroid Build Coastguard Worker     SmallVectorImpl<RenameIndependentSubregs::SubRangeInfo> &SubRangeInfos,
157*9880d681SAndroid Build Coastguard Worker     LiveInterval &LI) const {
158*9880d681SAndroid Build Coastguard Worker   // First step: Create connected components for the VNInfos inside the
159*9880d681SAndroid Build Coastguard Worker   // subranges and count the global number of such components.
160*9880d681SAndroid Build Coastguard Worker   unsigned NumComponents = 0;
161*9880d681SAndroid Build Coastguard Worker   for (LiveInterval::SubRange &SR : LI.subranges()) {
162*9880d681SAndroid Build Coastguard Worker     SubRangeInfos.push_back(SubRangeInfo(*LIS, SR, NumComponents));
163*9880d681SAndroid Build Coastguard Worker     ConnectedVNInfoEqClasses &ConEQ = SubRangeInfos.back().ConEQ;
164*9880d681SAndroid Build Coastguard Worker 
165*9880d681SAndroid Build Coastguard Worker     unsigned NumSubComponents = ConEQ.Classify(SR);
166*9880d681SAndroid Build Coastguard Worker     NumComponents += NumSubComponents;
167*9880d681SAndroid Build Coastguard Worker   }
168*9880d681SAndroid Build Coastguard Worker   // Shortcut: With only 1 subrange, the normal separate component tests are
169*9880d681SAndroid Build Coastguard Worker   // enough and we do not need to perform the union-find on the subregister
170*9880d681SAndroid Build Coastguard Worker   // segments.
171*9880d681SAndroid Build Coastguard Worker   if (SubRangeInfos.size() < 2)
172*9880d681SAndroid Build Coastguard Worker     return false;
173*9880d681SAndroid Build Coastguard Worker 
174*9880d681SAndroid Build Coastguard Worker   // Next step: Build union-find structure over all subranges and merge classes
175*9880d681SAndroid Build Coastguard Worker   // across subranges when they are affected by the same MachineOperand.
176*9880d681SAndroid Build Coastguard Worker   const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
177*9880d681SAndroid Build Coastguard Worker   Classes.grow(NumComponents);
178*9880d681SAndroid Build Coastguard Worker   unsigned Reg = LI.reg;
179*9880d681SAndroid Build Coastguard Worker   for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
180*9880d681SAndroid Build Coastguard Worker     if (!MO.isDef() && !MO.readsReg())
181*9880d681SAndroid Build Coastguard Worker       continue;
182*9880d681SAndroid Build Coastguard Worker     unsigned SubRegIdx = MO.getSubReg();
183*9880d681SAndroid Build Coastguard Worker     LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
184*9880d681SAndroid Build Coastguard Worker     unsigned MergedID = ~0u;
185*9880d681SAndroid Build Coastguard Worker     for (RenameIndependentSubregs::SubRangeInfo &SRInfo : SubRangeInfos) {
186*9880d681SAndroid Build Coastguard Worker       const LiveInterval::SubRange &SR = *SRInfo.SR;
187*9880d681SAndroid Build Coastguard Worker       if ((SR.LaneMask & LaneMask) == 0)
188*9880d681SAndroid Build Coastguard Worker         continue;
189*9880d681SAndroid Build Coastguard Worker       SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
190*9880d681SAndroid Build Coastguard Worker       Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber())
191*9880d681SAndroid Build Coastguard Worker                        : Pos.getBaseIndex();
192*9880d681SAndroid Build Coastguard Worker       const VNInfo *VNI = SR.getVNInfoAt(Pos);
193*9880d681SAndroid Build Coastguard Worker       if (VNI == nullptr)
194*9880d681SAndroid Build Coastguard Worker         continue;
195*9880d681SAndroid Build Coastguard Worker 
196*9880d681SAndroid Build Coastguard Worker       // Map to local representant ID.
197*9880d681SAndroid Build Coastguard Worker       unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
198*9880d681SAndroid Build Coastguard Worker       // Global ID
199*9880d681SAndroid Build Coastguard Worker       unsigned ID = LocalID + SRInfo.Index;
200*9880d681SAndroid Build Coastguard Worker       // Merge other sets
201*9880d681SAndroid Build Coastguard Worker       MergedID = MergedID == ~0u ? ID : Classes.join(MergedID, ID);
202*9880d681SAndroid Build Coastguard Worker     }
203*9880d681SAndroid Build Coastguard Worker   }
204*9880d681SAndroid Build Coastguard Worker 
205*9880d681SAndroid Build Coastguard Worker   // Early exit if we ended up with a single equivalence class.
206*9880d681SAndroid Build Coastguard Worker   Classes.compress();
207*9880d681SAndroid Build Coastguard Worker   unsigned NumClasses = Classes.getNumClasses();
208*9880d681SAndroid Build Coastguard Worker   return NumClasses > 1;
209*9880d681SAndroid Build Coastguard Worker }
210*9880d681SAndroid Build Coastguard Worker 
rewriteOperands(const IntEqClasses & Classes,const SmallVectorImpl<SubRangeInfo> & SubRangeInfos,const SmallVectorImpl<LiveInterval * > & Intervals) const211*9880d681SAndroid Build Coastguard Worker void RenameIndependentSubregs::rewriteOperands(const IntEqClasses &Classes,
212*9880d681SAndroid Build Coastguard Worker     const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
213*9880d681SAndroid Build Coastguard Worker     const SmallVectorImpl<LiveInterval*> &Intervals) const {
214*9880d681SAndroid Build Coastguard Worker   const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
215*9880d681SAndroid Build Coastguard Worker   unsigned Reg = Intervals[0]->reg;;
216*9880d681SAndroid Build Coastguard Worker   for (MachineRegisterInfo::reg_nodbg_iterator I = MRI->reg_nodbg_begin(Reg),
217*9880d681SAndroid Build Coastguard Worker        E = MRI->reg_nodbg_end(); I != E; ) {
218*9880d681SAndroid Build Coastguard Worker     MachineOperand &MO = *I++;
219*9880d681SAndroid Build Coastguard Worker     if (!MO.isDef() && !MO.readsReg())
220*9880d681SAndroid Build Coastguard Worker       continue;
221*9880d681SAndroid Build Coastguard Worker 
222*9880d681SAndroid Build Coastguard Worker     MachineInstr &MI = *MO.getParent();
223*9880d681SAndroid Build Coastguard Worker 
224*9880d681SAndroid Build Coastguard Worker     SlotIndex Pos = LIS->getInstructionIndex(MI);
225*9880d681SAndroid Build Coastguard Worker     unsigned SubRegIdx = MO.getSubReg();
226*9880d681SAndroid Build Coastguard Worker     LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
227*9880d681SAndroid Build Coastguard Worker 
228*9880d681SAndroid Build Coastguard Worker     unsigned ID = ~0u;
229*9880d681SAndroid Build Coastguard Worker     for (const SubRangeInfo &SRInfo : SubRangeInfos) {
230*9880d681SAndroid Build Coastguard Worker       const LiveInterval::SubRange &SR = *SRInfo.SR;
231*9880d681SAndroid Build Coastguard Worker       if ((SR.LaneMask & LaneMask) == 0)
232*9880d681SAndroid Build Coastguard Worker         continue;
233*9880d681SAndroid Build Coastguard Worker       LiveRange::const_iterator I = SR.find(Pos);
234*9880d681SAndroid Build Coastguard Worker       if (I == SR.end())
235*9880d681SAndroid Build Coastguard Worker         continue;
236*9880d681SAndroid Build Coastguard Worker 
237*9880d681SAndroid Build Coastguard Worker       const VNInfo &VNI = *I->valno;
238*9880d681SAndroid Build Coastguard Worker       // Map to local representant ID.
239*9880d681SAndroid Build Coastguard Worker       unsigned LocalID = SRInfo.ConEQ.getEqClass(&VNI);
240*9880d681SAndroid Build Coastguard Worker       // Global ID
241*9880d681SAndroid Build Coastguard Worker       ID = Classes[LocalID + SRInfo.Index];
242*9880d681SAndroid Build Coastguard Worker       break;
243*9880d681SAndroid Build Coastguard Worker     }
244*9880d681SAndroid Build Coastguard Worker 
245*9880d681SAndroid Build Coastguard Worker     unsigned VReg = Intervals[ID]->reg;
246*9880d681SAndroid Build Coastguard Worker     MO.setReg(VReg);
247*9880d681SAndroid Build Coastguard Worker   }
248*9880d681SAndroid Build Coastguard Worker   // TODO: We could attempt to recompute new register classes while visiting
249*9880d681SAndroid Build Coastguard Worker   // the operands: Some of the split register may be fine with less constraint
250*9880d681SAndroid Build Coastguard Worker   // classes than the original vreg.
251*9880d681SAndroid Build Coastguard Worker }
252*9880d681SAndroid Build Coastguard Worker 
distribute(const IntEqClasses & Classes,const SmallVectorImpl<SubRangeInfo> & SubRangeInfos,const SmallVectorImpl<LiveInterval * > & Intervals) const253*9880d681SAndroid Build Coastguard Worker void RenameIndependentSubregs::distribute(const IntEqClasses &Classes,
254*9880d681SAndroid Build Coastguard Worker     const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
255*9880d681SAndroid Build Coastguard Worker     const SmallVectorImpl<LiveInterval*> &Intervals) const {
256*9880d681SAndroid Build Coastguard Worker   unsigned NumClasses = Classes.getNumClasses();
257*9880d681SAndroid Build Coastguard Worker   SmallVector<unsigned, 8> VNIMapping;
258*9880d681SAndroid Build Coastguard Worker   SmallVector<LiveInterval::SubRange*, 8> SubRanges;
259*9880d681SAndroid Build Coastguard Worker   BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
260*9880d681SAndroid Build Coastguard Worker   for (const SubRangeInfo &SRInfo : SubRangeInfos) {
261*9880d681SAndroid Build Coastguard Worker     LiveInterval::SubRange &SR = *SRInfo.SR;
262*9880d681SAndroid Build Coastguard Worker     unsigned NumValNos = SR.valnos.size();
263*9880d681SAndroid Build Coastguard Worker     VNIMapping.clear();
264*9880d681SAndroid Build Coastguard Worker     VNIMapping.reserve(NumValNos);
265*9880d681SAndroid Build Coastguard Worker     SubRanges.clear();
266*9880d681SAndroid Build Coastguard Worker     SubRanges.resize(NumClasses-1, nullptr);
267*9880d681SAndroid Build Coastguard Worker     for (unsigned I = 0; I < NumValNos; ++I) {
268*9880d681SAndroid Build Coastguard Worker       const VNInfo &VNI = *SR.valnos[I];
269*9880d681SAndroid Build Coastguard Worker       unsigned LocalID = SRInfo.ConEQ.getEqClass(&VNI);
270*9880d681SAndroid Build Coastguard Worker       unsigned ID = Classes[LocalID + SRInfo.Index];
271*9880d681SAndroid Build Coastguard Worker       VNIMapping.push_back(ID);
272*9880d681SAndroid Build Coastguard Worker       if (ID > 0 && SubRanges[ID-1] == nullptr)
273*9880d681SAndroid Build Coastguard Worker         SubRanges[ID-1] = Intervals[ID]->createSubRange(Allocator, SR.LaneMask);
274*9880d681SAndroid Build Coastguard Worker     }
275*9880d681SAndroid Build Coastguard Worker     DistributeRange(SR, SubRanges.data(), VNIMapping);
276*9880d681SAndroid Build Coastguard Worker   }
277*9880d681SAndroid Build Coastguard Worker }
278*9880d681SAndroid Build Coastguard Worker 
subRangeLiveAt(const LiveInterval & LI,SlotIndex Pos)279*9880d681SAndroid Build Coastguard Worker static bool subRangeLiveAt(const LiveInterval &LI, SlotIndex Pos) {
280*9880d681SAndroid Build Coastguard Worker   for (const LiveInterval::SubRange &SR : LI.subranges()) {
281*9880d681SAndroid Build Coastguard Worker     if (SR.liveAt(Pos))
282*9880d681SAndroid Build Coastguard Worker       return true;
283*9880d681SAndroid Build Coastguard Worker   }
284*9880d681SAndroid Build Coastguard Worker   return false;
285*9880d681SAndroid Build Coastguard Worker }
286*9880d681SAndroid Build Coastguard Worker 
computeMainRangesFixFlags(const IntEqClasses & Classes,const SmallVectorImpl<SubRangeInfo> & SubRangeInfos,const SmallVectorImpl<LiveInterval * > & Intervals) const287*9880d681SAndroid Build Coastguard Worker void RenameIndependentSubregs::computeMainRangesFixFlags(
288*9880d681SAndroid Build Coastguard Worker     const IntEqClasses &Classes,
289*9880d681SAndroid Build Coastguard Worker     const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
290*9880d681SAndroid Build Coastguard Worker     const SmallVectorImpl<LiveInterval*> &Intervals) const {
291*9880d681SAndroid Build Coastguard Worker   BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
292*9880d681SAndroid Build Coastguard Worker   const SlotIndexes &Indexes = *LIS->getSlotIndexes();
293*9880d681SAndroid Build Coastguard Worker   for (size_t I = 0, E = Intervals.size(); I < E; ++I) {
294*9880d681SAndroid Build Coastguard Worker     LiveInterval &LI = *Intervals[I];
295*9880d681SAndroid Build Coastguard Worker     unsigned Reg = LI.reg;
296*9880d681SAndroid Build Coastguard Worker 
297*9880d681SAndroid Build Coastguard Worker     LI.removeEmptySubRanges();
298*9880d681SAndroid Build Coastguard Worker 
299*9880d681SAndroid Build Coastguard Worker     // There must be a def (or live-in) before every use. Splitting vregs may
300*9880d681SAndroid Build Coastguard Worker     // violate this principle as the splitted vreg may not have a definition on
301*9880d681SAndroid Build Coastguard Worker     // every path. Fix this by creating IMPLICIT_DEF instruction as necessary.
302*9880d681SAndroid Build Coastguard Worker     for (const LiveInterval::SubRange &SR : LI.subranges()) {
303*9880d681SAndroid Build Coastguard Worker       // Search for "PHI" value numbers in the subranges. We must find a live
304*9880d681SAndroid Build Coastguard Worker       // value in each predecessor block, add an IMPLICIT_DEF where it is
305*9880d681SAndroid Build Coastguard Worker       // missing.
306*9880d681SAndroid Build Coastguard Worker       for (unsigned I = 0; I < SR.valnos.size(); ++I) {
307*9880d681SAndroid Build Coastguard Worker         const VNInfo &VNI = *SR.valnos[I];
308*9880d681SAndroid Build Coastguard Worker         if (VNI.isUnused() || !VNI.isPHIDef())
309*9880d681SAndroid Build Coastguard Worker           continue;
310*9880d681SAndroid Build Coastguard Worker 
311*9880d681SAndroid Build Coastguard Worker         SlotIndex Def = VNI.def;
312*9880d681SAndroid Build Coastguard Worker         MachineBasicBlock &MBB = *Indexes.getMBBFromIndex(Def);
313*9880d681SAndroid Build Coastguard Worker         for (MachineBasicBlock *PredMBB : MBB.predecessors()) {
314*9880d681SAndroid Build Coastguard Worker           SlotIndex PredEnd = Indexes.getMBBEndIdx(PredMBB);
315*9880d681SAndroid Build Coastguard Worker           if (subRangeLiveAt(LI, PredEnd.getPrevSlot()))
316*9880d681SAndroid Build Coastguard Worker             continue;
317*9880d681SAndroid Build Coastguard Worker 
318*9880d681SAndroid Build Coastguard Worker           MachineBasicBlock::iterator InsertPos =
319*9880d681SAndroid Build Coastguard Worker             llvm::findPHICopyInsertPoint(PredMBB, &MBB, Reg);
320*9880d681SAndroid Build Coastguard Worker           const MCInstrDesc &MCDesc = TII->get(TargetOpcode::IMPLICIT_DEF);
321*9880d681SAndroid Build Coastguard Worker           MachineInstrBuilder ImpDef = BuildMI(*PredMBB, InsertPos,
322*9880d681SAndroid Build Coastguard Worker                                                DebugLoc(), MCDesc, Reg);
323*9880d681SAndroid Build Coastguard Worker           SlotIndex DefIdx = LIS->InsertMachineInstrInMaps(*ImpDef);
324*9880d681SAndroid Build Coastguard Worker           SlotIndex RegDefIdx = DefIdx.getRegSlot();
325*9880d681SAndroid Build Coastguard Worker           for (LiveInterval::SubRange &SR : LI.subranges()) {
326*9880d681SAndroid Build Coastguard Worker             VNInfo *SRVNI = SR.getNextValue(RegDefIdx, Allocator);
327*9880d681SAndroid Build Coastguard Worker             SR.addSegment(LiveRange::Segment(RegDefIdx, PredEnd, SRVNI));
328*9880d681SAndroid Build Coastguard Worker           }
329*9880d681SAndroid Build Coastguard Worker         }
330*9880d681SAndroid Build Coastguard Worker       }
331*9880d681SAndroid Build Coastguard Worker     }
332*9880d681SAndroid Build Coastguard Worker 
333*9880d681SAndroid Build Coastguard Worker     for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
334*9880d681SAndroid Build Coastguard Worker       if (!MO.isDef())
335*9880d681SAndroid Build Coastguard Worker         continue;
336*9880d681SAndroid Build Coastguard Worker       unsigned SubRegIdx = MO.getSubReg();
337*9880d681SAndroid Build Coastguard Worker       if (SubRegIdx == 0)
338*9880d681SAndroid Build Coastguard Worker         continue;
339*9880d681SAndroid Build Coastguard Worker       // After assigning the new vreg we may not have any other sublanes living
340*9880d681SAndroid Build Coastguard Worker       // in and out of the instruction anymore. We need to add new dead and
341*9880d681SAndroid Build Coastguard Worker       // undef flags in these cases.
342*9880d681SAndroid Build Coastguard Worker       if (!MO.isUndef()) {
343*9880d681SAndroid Build Coastguard Worker         SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
344*9880d681SAndroid Build Coastguard Worker         if (!subRangeLiveAt(LI, Pos))
345*9880d681SAndroid Build Coastguard Worker           MO.setIsUndef();
346*9880d681SAndroid Build Coastguard Worker       }
347*9880d681SAndroid Build Coastguard Worker       if (!MO.isDead()) {
348*9880d681SAndroid Build Coastguard Worker         SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()).getDeadSlot();
349*9880d681SAndroid Build Coastguard Worker         if (!subRangeLiveAt(LI, Pos))
350*9880d681SAndroid Build Coastguard Worker           MO.setIsDead();
351*9880d681SAndroid Build Coastguard Worker       }
352*9880d681SAndroid Build Coastguard Worker     }
353*9880d681SAndroid Build Coastguard Worker 
354*9880d681SAndroid Build Coastguard Worker     if (I == 0)
355*9880d681SAndroid Build Coastguard Worker       LI.clear();
356*9880d681SAndroid Build Coastguard Worker     LIS->constructMainRangeFromSubranges(LI);
357*9880d681SAndroid Build Coastguard Worker   }
358*9880d681SAndroid Build Coastguard Worker }
359*9880d681SAndroid Build Coastguard Worker 
runOnMachineFunction(MachineFunction & MF)360*9880d681SAndroid Build Coastguard Worker bool RenameIndependentSubregs::runOnMachineFunction(MachineFunction &MF) {
361*9880d681SAndroid Build Coastguard Worker   // Skip renaming if liveness of subregister is not tracked.
362*9880d681SAndroid Build Coastguard Worker   if (!MF.getSubtarget().enableSubRegLiveness())
363*9880d681SAndroid Build Coastguard Worker     return false;
364*9880d681SAndroid Build Coastguard Worker 
365*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "Renaming independent subregister live ranges in "
366*9880d681SAndroid Build Coastguard Worker         << MF.getName() << '\n');
367*9880d681SAndroid Build Coastguard Worker 
368*9880d681SAndroid Build Coastguard Worker   LIS = &getAnalysis<LiveIntervals>();
369*9880d681SAndroid Build Coastguard Worker   MRI = &MF.getRegInfo();
370*9880d681SAndroid Build Coastguard Worker   TII = MF.getSubtarget().getInstrInfo();
371*9880d681SAndroid Build Coastguard Worker 
372*9880d681SAndroid Build Coastguard Worker   // Iterate over all vregs. Note that we query getNumVirtRegs() the newly
373*9880d681SAndroid Build Coastguard Worker   // created vregs end up with higher numbers but do not need to be visited as
374*9880d681SAndroid Build Coastguard Worker   // there can't be any further splitting.
375*9880d681SAndroid Build Coastguard Worker   bool Changed = false;
376*9880d681SAndroid Build Coastguard Worker   for (size_t I = 0, E = MRI->getNumVirtRegs(); I < E; ++I) {
377*9880d681SAndroid Build Coastguard Worker     unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
378*9880d681SAndroid Build Coastguard Worker     if (!LIS->hasInterval(Reg))
379*9880d681SAndroid Build Coastguard Worker       continue;
380*9880d681SAndroid Build Coastguard Worker     LiveInterval &LI = LIS->getInterval(Reg);
381*9880d681SAndroid Build Coastguard Worker     if (!LI.hasSubRanges())
382*9880d681SAndroid Build Coastguard Worker       continue;
383*9880d681SAndroid Build Coastguard Worker 
384*9880d681SAndroid Build Coastguard Worker     Changed |= renameComponents(LI);
385*9880d681SAndroid Build Coastguard Worker   }
386*9880d681SAndroid Build Coastguard Worker 
387*9880d681SAndroid Build Coastguard Worker   return Changed;
388*9880d681SAndroid Build Coastguard Worker }
389