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