1f9acacaaSMatthias Braun //===-- RenameIndependentSubregs.cpp - Live Interval Analysis -------------===//
2f9acacaaSMatthias Braun //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f9acacaaSMatthias Braun //
7f9acacaaSMatthias Braun //===----------------------------------------------------------------------===//
8f9acacaaSMatthias Braun //
9f9acacaaSMatthias Braun /// Rename independent subregisters looks for virtual registers with
10f9acacaaSMatthias Braun /// independently used subregisters and renames them to new virtual registers.
11f9acacaaSMatthias Braun /// Example: In the following:
1293ef1458SFrancis Visoiu Mistrih /// %0:sub0<read-undef> = ...
1393ef1458SFrancis Visoiu Mistrih /// %0:sub1 = ...
1493ef1458SFrancis Visoiu Mistrih /// use %0:sub0
1593ef1458SFrancis Visoiu Mistrih /// %0:sub0 = ...
1693ef1458SFrancis Visoiu Mistrih /// use %0:sub0
1793ef1458SFrancis Visoiu Mistrih /// use %0:sub1
18f9acacaaSMatthias Braun /// sub0 and sub1 are never used together, and we have two independent sub0
19f9acacaaSMatthias Braun /// definitions. This pass will rename to:
2093ef1458SFrancis Visoiu Mistrih /// %0:sub0<read-undef> = ...
2193ef1458SFrancis Visoiu Mistrih /// %1:sub1<read-undef> = ...
2293ef1458SFrancis Visoiu Mistrih /// use %1:sub1
2393ef1458SFrancis Visoiu Mistrih /// %2:sub1<read-undef> = ...
2493ef1458SFrancis Visoiu Mistrih /// use %2:sub1
2593ef1458SFrancis Visoiu Mistrih /// use %0:sub0
26f9acacaaSMatthias Braun //
27f9acacaaSMatthias Braun //===----------------------------------------------------------------------===//
28f9acacaaSMatthias Braun
29f9acacaaSMatthias Braun #include "LiveRangeUtils.h"
30f9acacaaSMatthias Braun #include "PHIEliminationUtils.h"
31f9acacaaSMatthias Braun #include "llvm/CodeGen/LiveInterval.h"
32f842297dSMatthias Braun #include "llvm/CodeGen/LiveIntervals.h"
33f9acacaaSMatthias Braun #include "llvm/CodeGen/MachineFunctionPass.h"
346bda14b3SChandler Carruth #include "llvm/CodeGen/MachineInstrBuilder.h"
35f9acacaaSMatthias Braun #include "llvm/CodeGen/MachineRegisterInfo.h"
363f833edcSDavid Blaikie #include "llvm/CodeGen/TargetInstrInfo.h"
3705da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
38*989f1c72Sserge-sans-paille #include "llvm/Pass.h"
39f9acacaaSMatthias Braun
40f9acacaaSMatthias Braun using namespace llvm;
41f9acacaaSMatthias Braun
42f9acacaaSMatthias Braun #define DEBUG_TYPE "rename-independent-subregs"
43f9acacaaSMatthias Braun
44f9acacaaSMatthias Braun namespace {
45f9acacaaSMatthias Braun
46f9acacaaSMatthias Braun class RenameIndependentSubregs : public MachineFunctionPass {
47f9acacaaSMatthias Braun public:
48f9acacaaSMatthias Braun static char ID;
RenameIndependentSubregs()49f9acacaaSMatthias Braun RenameIndependentSubregs() : MachineFunctionPass(ID) {}
50f9acacaaSMatthias Braun
getPassName() const51117296c0SMehdi Amini StringRef getPassName() const override {
52f9acacaaSMatthias Braun return "Rename Disconnected Subregister Components";
53f9acacaaSMatthias Braun }
54f9acacaaSMatthias Braun
getAnalysisUsage(AnalysisUsage & AU) const55f9acacaaSMatthias Braun void getAnalysisUsage(AnalysisUsage &AU) const override {
56f9acacaaSMatthias Braun AU.setPreservesCFG();
57f9acacaaSMatthias Braun AU.addRequired<LiveIntervals>();
58f9acacaaSMatthias Braun AU.addPreserved<LiveIntervals>();
59f9acacaaSMatthias Braun AU.addRequired<SlotIndexes>();
60f9acacaaSMatthias Braun AU.addPreserved<SlotIndexes>();
61f9acacaaSMatthias Braun MachineFunctionPass::getAnalysisUsage(AU);
62f9acacaaSMatthias Braun }
63f9acacaaSMatthias Braun
64f9acacaaSMatthias Braun bool runOnMachineFunction(MachineFunction &MF) override;
65f9acacaaSMatthias Braun
66f9acacaaSMatthias Braun private:
67f9acacaaSMatthias Braun struct SubRangeInfo {
68f9acacaaSMatthias Braun ConnectedVNInfoEqClasses ConEQ;
69f9acacaaSMatthias Braun LiveInterval::SubRange *SR;
70f9acacaaSMatthias Braun unsigned Index;
71f9acacaaSMatthias Braun
SubRangeInfo__anon4f5f40e50111::RenameIndependentSubregs::SubRangeInfo72f9acacaaSMatthias Braun SubRangeInfo(LiveIntervals &LIS, LiveInterval::SubRange &SR,
73f9acacaaSMatthias Braun unsigned Index)
74f9acacaaSMatthias Braun : ConEQ(LIS), SR(&SR), Index(Index) {}
75f9acacaaSMatthias Braun };
76f9acacaaSMatthias Braun
77f9acacaaSMatthias Braun /// Split unrelated subregister components and rename them to new vregs.
78f9acacaaSMatthias Braun bool renameComponents(LiveInterval &LI) const;
79f9acacaaSMatthias Braun
805f8f34e4SAdrian Prantl /// Build a vector of SubRange infos and a union find set of
81f9acacaaSMatthias Braun /// equivalence classes.
82f9acacaaSMatthias Braun /// Returns true if more than 1 equivalence class was found.
83f9acacaaSMatthias Braun bool findComponents(IntEqClasses &Classes,
84f9acacaaSMatthias Braun SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
85f9acacaaSMatthias Braun LiveInterval &LI) const;
86f9acacaaSMatthias Braun
875f8f34e4SAdrian Prantl /// Distribute the LiveInterval segments into the new LiveIntervals
88f9acacaaSMatthias Braun /// belonging to their class.
89f9acacaaSMatthias Braun void distribute(const IntEqClasses &Classes,
90f9acacaaSMatthias Braun const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
91f9acacaaSMatthias Braun const SmallVectorImpl<LiveInterval*> &Intervals) const;
92f9acacaaSMatthias Braun
935f8f34e4SAdrian Prantl /// Constructs main liverange and add missing undef+dead flags.
94f9acacaaSMatthias Braun void computeMainRangesFixFlags(const IntEqClasses &Classes,
95f9acacaaSMatthias Braun const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
96f9acacaaSMatthias Braun const SmallVectorImpl<LiveInterval*> &Intervals) const;
97f9acacaaSMatthias Braun
98f9acacaaSMatthias Braun /// Rewrite Machine Operands to use the new vreg belonging to their class.
99f9acacaaSMatthias Braun void rewriteOperands(const IntEqClasses &Classes,
100f9acacaaSMatthias Braun const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
101f9acacaaSMatthias Braun const SmallVectorImpl<LiveInterval*> &Intervals) const;
102f9acacaaSMatthias Braun
103f9acacaaSMatthias Braun
104f9acacaaSMatthias Braun LiveIntervals *LIS;
105f9acacaaSMatthias Braun MachineRegisterInfo *MRI;
106f9acacaaSMatthias Braun const TargetInstrInfo *TII;
107f9acacaaSMatthias Braun };
108f9acacaaSMatthias Braun
109f9acacaaSMatthias Braun } // end anonymous namespace
110f9acacaaSMatthias Braun
111f9acacaaSMatthias Braun char RenameIndependentSubregs::ID;
112f9acacaaSMatthias Braun
113f9acacaaSMatthias Braun char &llvm::RenameIndependentSubregsID = RenameIndependentSubregs::ID;
114f9acacaaSMatthias Braun
1151527baabSMatthias Braun INITIALIZE_PASS_BEGIN(RenameIndependentSubregs, DEBUG_TYPE,
116f9acacaaSMatthias Braun "Rename Independent Subregisters", false, false)
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)117f9acacaaSMatthias Braun INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
118f9acacaaSMatthias Braun INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
1191527baabSMatthias Braun INITIALIZE_PASS_END(RenameIndependentSubregs, DEBUG_TYPE,
120f9acacaaSMatthias Braun "Rename Independent Subregisters", false, false)
121f9acacaaSMatthias Braun
122f9acacaaSMatthias Braun bool RenameIndependentSubregs::renameComponents(LiveInterval &LI) const {
123f9acacaaSMatthias Braun // Shortcut: We cannot have split components with a single definition.
124f9acacaaSMatthias Braun if (LI.valnos.size() < 2)
125f9acacaaSMatthias Braun return false;
126f9acacaaSMatthias Braun
127f9acacaaSMatthias Braun SmallVector<SubRangeInfo, 4> SubRangeInfos;
128f9acacaaSMatthias Braun IntEqClasses Classes;
129f9acacaaSMatthias Braun if (!findComponents(Classes, SubRangeInfos, LI))
130f9acacaaSMatthias Braun return false;
131f9acacaaSMatthias Braun
132f9acacaaSMatthias Braun // Create a new VReg for each class.
1336e85c3d5SMircea Trofin unsigned Reg = LI.reg();
134f9acacaaSMatthias Braun const TargetRegisterClass *RegClass = MRI->getRegClass(Reg);
135f9acacaaSMatthias Braun SmallVector<LiveInterval*, 4> Intervals;
136f9acacaaSMatthias Braun Intervals.push_back(&LI);
137d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << printReg(Reg) << ": Found " << Classes.getNumClasses()
138f9acacaaSMatthias Braun << " equivalence classes.\n");
139d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << printReg(Reg) << ": Splitting into newly created:");
140f9acacaaSMatthias Braun for (unsigned I = 1, NumClasses = Classes.getNumClasses(); I < NumClasses;
141f9acacaaSMatthias Braun ++I) {
1420c476111SDaniel Sanders Register NewVReg = MRI->createVirtualRegister(RegClass);
143f9acacaaSMatthias Braun LiveInterval &NewLI = LIS->createEmptyInterval(NewVReg);
144f9acacaaSMatthias Braun Intervals.push_back(&NewLI);
145d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << ' ' << printReg(NewVReg));
146f9acacaaSMatthias Braun }
147d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << '\n');
148f9acacaaSMatthias Braun
149f9acacaaSMatthias Braun rewriteOperands(Classes, SubRangeInfos, Intervals);
150f9acacaaSMatthias Braun distribute(Classes, SubRangeInfos, Intervals);
151f9acacaaSMatthias Braun computeMainRangesFixFlags(Classes, SubRangeInfos, Intervals);
152f9acacaaSMatthias Braun return true;
153f9acacaaSMatthias Braun }
154f9acacaaSMatthias Braun
findComponents(IntEqClasses & Classes,SmallVectorImpl<RenameIndependentSubregs::SubRangeInfo> & SubRangeInfos,LiveInterval & LI) const155f9acacaaSMatthias Braun bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes,
156f9acacaaSMatthias Braun SmallVectorImpl<RenameIndependentSubregs::SubRangeInfo> &SubRangeInfos,
157f9acacaaSMatthias Braun LiveInterval &LI) const {
158f9acacaaSMatthias Braun // First step: Create connected components for the VNInfos inside the
159f9acacaaSMatthias Braun // subranges and count the global number of such components.
160f9acacaaSMatthias Braun unsigned NumComponents = 0;
161f9acacaaSMatthias Braun for (LiveInterval::SubRange &SR : LI.subranges()) {
162f9acacaaSMatthias Braun SubRangeInfos.push_back(SubRangeInfo(*LIS, SR, NumComponents));
163f9acacaaSMatthias Braun ConnectedVNInfoEqClasses &ConEQ = SubRangeInfos.back().ConEQ;
164f9acacaaSMatthias Braun
165f9acacaaSMatthias Braun unsigned NumSubComponents = ConEQ.Classify(SR);
166f9acacaaSMatthias Braun NumComponents += NumSubComponents;
167f9acacaaSMatthias Braun }
168f9acacaaSMatthias Braun // Shortcut: With only 1 subrange, the normal separate component tests are
169f9acacaaSMatthias Braun // enough and we do not need to perform the union-find on the subregister
170f9acacaaSMatthias Braun // segments.
171f9acacaaSMatthias Braun if (SubRangeInfos.size() < 2)
172f9acacaaSMatthias Braun return false;
173f9acacaaSMatthias Braun
174f9acacaaSMatthias Braun // Next step: Build union-find structure over all subranges and merge classes
175f9acacaaSMatthias Braun // across subranges when they are affected by the same MachineOperand.
176f9acacaaSMatthias Braun const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
177f9acacaaSMatthias Braun Classes.grow(NumComponents);
1786e85c3d5SMircea Trofin unsigned Reg = LI.reg();
179f9acacaaSMatthias Braun for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
180f9acacaaSMatthias Braun if (!MO.isDef() && !MO.readsReg())
181f9acacaaSMatthias Braun continue;
182f9acacaaSMatthias Braun unsigned SubRegIdx = MO.getSubReg();
183f9acacaaSMatthias Braun LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
184f9acacaaSMatthias Braun unsigned MergedID = ~0u;
185f9acacaaSMatthias Braun for (RenameIndependentSubregs::SubRangeInfo &SRInfo : SubRangeInfos) {
186f9acacaaSMatthias Braun const LiveInterval::SubRange &SR = *SRInfo.SR;
18791b5cf84SKrzysztof Parzyszek if ((SR.LaneMask & LaneMask).none())
188f9acacaaSMatthias Braun continue;
189f9acacaaSMatthias Braun SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
190f9acacaaSMatthias Braun Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber())
191f9acacaaSMatthias Braun : Pos.getBaseIndex();
192f9acacaaSMatthias Braun const VNInfo *VNI = SR.getVNInfoAt(Pos);
193f9acacaaSMatthias Braun if (VNI == nullptr)
194f9acacaaSMatthias Braun continue;
195f9acacaaSMatthias Braun
196f9acacaaSMatthias Braun // Map to local representant ID.
197f9acacaaSMatthias Braun unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
198f9acacaaSMatthias Braun // Global ID
199f9acacaaSMatthias Braun unsigned ID = LocalID + SRInfo.Index;
200f9acacaaSMatthias Braun // Merge other sets
201f9acacaaSMatthias Braun MergedID = MergedID == ~0u ? ID : Classes.join(MergedID, ID);
202f9acacaaSMatthias Braun }
203f9acacaaSMatthias Braun }
204f9acacaaSMatthias Braun
205f9acacaaSMatthias Braun // Early exit if we ended up with a single equivalence class.
206f9acacaaSMatthias Braun Classes.compress();
207f9acacaaSMatthias Braun unsigned NumClasses = Classes.getNumClasses();
208f9acacaaSMatthias Braun return NumClasses > 1;
209f9acacaaSMatthias Braun }
210f9acacaaSMatthias Braun
rewriteOperands(const IntEqClasses & Classes,const SmallVectorImpl<SubRangeInfo> & SubRangeInfos,const SmallVectorImpl<LiveInterval * > & Intervals) const211f9acacaaSMatthias Braun void RenameIndependentSubregs::rewriteOperands(const IntEqClasses &Classes,
212f9acacaaSMatthias Braun const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
213f9acacaaSMatthias Braun const SmallVectorImpl<LiveInterval*> &Intervals) const {
214f9acacaaSMatthias Braun const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
2156e85c3d5SMircea Trofin unsigned Reg = Intervals[0]->reg();
216f9acacaaSMatthias Braun for (MachineRegisterInfo::reg_nodbg_iterator I = MRI->reg_nodbg_begin(Reg),
217f9acacaaSMatthias Braun E = MRI->reg_nodbg_end(); I != E; ) {
218f9acacaaSMatthias Braun MachineOperand &MO = *I++;
219f9acacaaSMatthias Braun if (!MO.isDef() && !MO.readsReg())
220f9acacaaSMatthias Braun continue;
221f9acacaaSMatthias Braun
2227139dea6SMark Searles auto *MI = MO.getParent();
2237139dea6SMark Searles SlotIndex Pos = LIS->getInstructionIndex(*MI);
2241873998bSMatthias Braun Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber())
2251873998bSMatthias Braun : Pos.getBaseIndex();
226f9acacaaSMatthias Braun unsigned SubRegIdx = MO.getSubReg();
227f9acacaaSMatthias Braun LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
228f9acacaaSMatthias Braun
229f9acacaaSMatthias Braun unsigned ID = ~0u;
230f9acacaaSMatthias Braun for (const SubRangeInfo &SRInfo : SubRangeInfos) {
231f9acacaaSMatthias Braun const LiveInterval::SubRange &SR = *SRInfo.SR;
23291b5cf84SKrzysztof Parzyszek if ((SR.LaneMask & LaneMask).none())
233f9acacaaSMatthias Braun continue;
2341873998bSMatthias Braun const VNInfo *VNI = SR.getVNInfoAt(Pos);
2351873998bSMatthias Braun if (VNI == nullptr)
236f9acacaaSMatthias Braun continue;
237f9acacaaSMatthias Braun
238f9acacaaSMatthias Braun // Map to local representant ID.
2391873998bSMatthias Braun unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
240f9acacaaSMatthias Braun // Global ID
241f9acacaaSMatthias Braun ID = Classes[LocalID + SRInfo.Index];
242f9acacaaSMatthias Braun break;
243f9acacaaSMatthias Braun }
244f9acacaaSMatthias Braun
2456e85c3d5SMircea Trofin unsigned VReg = Intervals[ID]->reg();
246f9acacaaSMatthias Braun MO.setReg(VReg);
247836d786eSMatt Arsenault
248836d786eSMatt Arsenault if (MO.isTied() && Reg != VReg) {
2497139dea6SMark Searles /// Undef use operands are not tracked in the equivalence class,
2507139dea6SMark Searles /// but need to be updated if they are tied; take care to only
2517139dea6SMark Searles /// update the tied operand.
2527139dea6SMark Searles unsigned OperandNo = MI->getOperandNo(&MO);
2537139dea6SMark Searles unsigned TiedIdx = MI->findTiedOperandIdx(OperandNo);
2547139dea6SMark Searles MI->getOperand(TiedIdx).setReg(VReg);
25553fae077SMatt Arsenault
2567139dea6SMark Searles // above substitution breaks the iterator, so restart.
25753fae077SMatt Arsenault I = MRI->reg_nodbg_begin(Reg);
2589e5b5053SMatt Arsenault }
259f9acacaaSMatthias Braun }
260f9acacaaSMatthias Braun // TODO: We could attempt to recompute new register classes while visiting
261f9acacaaSMatthias Braun // the operands: Some of the split register may be fine with less constraint
262f9acacaaSMatthias Braun // classes than the original vreg.
263f9acacaaSMatthias Braun }
264f9acacaaSMatthias Braun
distribute(const IntEqClasses & Classes,const SmallVectorImpl<SubRangeInfo> & SubRangeInfos,const SmallVectorImpl<LiveInterval * > & Intervals) const265f9acacaaSMatthias Braun void RenameIndependentSubregs::distribute(const IntEqClasses &Classes,
266f9acacaaSMatthias Braun const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
267f9acacaaSMatthias Braun const SmallVectorImpl<LiveInterval*> &Intervals) const {
268f9acacaaSMatthias Braun unsigned NumClasses = Classes.getNumClasses();
269f9acacaaSMatthias Braun SmallVector<unsigned, 8> VNIMapping;
270f9acacaaSMatthias Braun SmallVector<LiveInterval::SubRange*, 8> SubRanges;
271f9acacaaSMatthias Braun BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
272f9acacaaSMatthias Braun for (const SubRangeInfo &SRInfo : SubRangeInfos) {
273f9acacaaSMatthias Braun LiveInterval::SubRange &SR = *SRInfo.SR;
274f9acacaaSMatthias Braun unsigned NumValNos = SR.valnos.size();
275f9acacaaSMatthias Braun VNIMapping.clear();
276f9acacaaSMatthias Braun VNIMapping.reserve(NumValNos);
277f9acacaaSMatthias Braun SubRanges.clear();
278f9acacaaSMatthias Braun SubRanges.resize(NumClasses-1, nullptr);
279f9acacaaSMatthias Braun for (unsigned I = 0; I < NumValNos; ++I) {
280f9acacaaSMatthias Braun const VNInfo &VNI = *SR.valnos[I];
281f9acacaaSMatthias Braun unsigned LocalID = SRInfo.ConEQ.getEqClass(&VNI);
282f9acacaaSMatthias Braun unsigned ID = Classes[LocalID + SRInfo.Index];
283f9acacaaSMatthias Braun VNIMapping.push_back(ID);
284f9acacaaSMatthias Braun if (ID > 0 && SubRanges[ID-1] == nullptr)
285f9acacaaSMatthias Braun SubRanges[ID-1] = Intervals[ID]->createSubRange(Allocator, SR.LaneMask);
286f9acacaaSMatthias Braun }
287f9acacaaSMatthias Braun DistributeRange(SR, SubRanges.data(), VNIMapping);
288f9acacaaSMatthias Braun }
289f9acacaaSMatthias Braun }
290f9acacaaSMatthias Braun
subRangeLiveAt(const LiveInterval & LI,SlotIndex Pos)291f9acacaaSMatthias Braun static bool subRangeLiveAt(const LiveInterval &LI, SlotIndex Pos) {
292f9acacaaSMatthias Braun for (const LiveInterval::SubRange &SR : LI.subranges()) {
293f9acacaaSMatthias Braun if (SR.liveAt(Pos))
294f9acacaaSMatthias Braun return true;
295f9acacaaSMatthias Braun }
296f9acacaaSMatthias Braun return false;
297f9acacaaSMatthias Braun }
298f9acacaaSMatthias Braun
computeMainRangesFixFlags(const IntEqClasses & Classes,const SmallVectorImpl<SubRangeInfo> & SubRangeInfos,const SmallVectorImpl<LiveInterval * > & Intervals) const299f9acacaaSMatthias Braun void RenameIndependentSubregs::computeMainRangesFixFlags(
300f9acacaaSMatthias Braun const IntEqClasses &Classes,
301f9acacaaSMatthias Braun const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
302f9acacaaSMatthias Braun const SmallVectorImpl<LiveInterval*> &Intervals) const {
303f9acacaaSMatthias Braun BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
304f9acacaaSMatthias Braun const SlotIndexes &Indexes = *LIS->getSlotIndexes();
305f9acacaaSMatthias Braun for (size_t I = 0, E = Intervals.size(); I < E; ++I) {
306f9acacaaSMatthias Braun LiveInterval &LI = *Intervals[I];
3076e85c3d5SMircea Trofin unsigned Reg = LI.reg();
308f9acacaaSMatthias Braun
309f9acacaaSMatthias Braun LI.removeEmptySubRanges();
310f9acacaaSMatthias Braun
311f9acacaaSMatthias Braun // There must be a def (or live-in) before every use. Splitting vregs may
312f9acacaaSMatthias Braun // violate this principle as the splitted vreg may not have a definition on
313f9acacaaSMatthias Braun // every path. Fix this by creating IMPLICIT_DEF instruction as necessary.
314f9acacaaSMatthias Braun for (const LiveInterval::SubRange &SR : LI.subranges()) {
315f9acacaaSMatthias Braun // Search for "PHI" value numbers in the subranges. We must find a live
316f9acacaaSMatthias Braun // value in each predecessor block, add an IMPLICIT_DEF where it is
317f9acacaaSMatthias Braun // missing.
318f9acacaaSMatthias Braun for (unsigned I = 0; I < SR.valnos.size(); ++I) {
319f9acacaaSMatthias Braun const VNInfo &VNI = *SR.valnos[I];
320f9acacaaSMatthias Braun if (VNI.isUnused() || !VNI.isPHIDef())
321f9acacaaSMatthias Braun continue;
322f9acacaaSMatthias Braun
323f9acacaaSMatthias Braun SlotIndex Def = VNI.def;
324f9acacaaSMatthias Braun MachineBasicBlock &MBB = *Indexes.getMBBFromIndex(Def);
325f9acacaaSMatthias Braun for (MachineBasicBlock *PredMBB : MBB.predecessors()) {
326f9acacaaSMatthias Braun SlotIndex PredEnd = Indexes.getMBBEndIdx(PredMBB);
327f9acacaaSMatthias Braun if (subRangeLiveAt(LI, PredEnd.getPrevSlot()))
328f9acacaaSMatthias Braun continue;
329f9acacaaSMatthias Braun
330f9acacaaSMatthias Braun MachineBasicBlock::iterator InsertPos =
331f9acacaaSMatthias Braun llvm::findPHICopyInsertPoint(PredMBB, &MBB, Reg);
332f9acacaaSMatthias Braun const MCInstrDesc &MCDesc = TII->get(TargetOpcode::IMPLICIT_DEF);
333f9acacaaSMatthias Braun MachineInstrBuilder ImpDef = BuildMI(*PredMBB, InsertPos,
334f9acacaaSMatthias Braun DebugLoc(), MCDesc, Reg);
335f9acacaaSMatthias Braun SlotIndex DefIdx = LIS->InsertMachineInstrInMaps(*ImpDef);
336f9acacaaSMatthias Braun SlotIndex RegDefIdx = DefIdx.getRegSlot();
337f9acacaaSMatthias Braun for (LiveInterval::SubRange &SR : LI.subranges()) {
338f9acacaaSMatthias Braun VNInfo *SRVNI = SR.getNextValue(RegDefIdx, Allocator);
339f9acacaaSMatthias Braun SR.addSegment(LiveRange::Segment(RegDefIdx, PredEnd, SRVNI));
340f9acacaaSMatthias Braun }
341f9acacaaSMatthias Braun }
342f9acacaaSMatthias Braun }
343f9acacaaSMatthias Braun }
344f9acacaaSMatthias Braun
345f9acacaaSMatthias Braun for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
346f9acacaaSMatthias Braun if (!MO.isDef())
347f9acacaaSMatthias Braun continue;
348f9acacaaSMatthias Braun unsigned SubRegIdx = MO.getSubReg();
349f9acacaaSMatthias Braun if (SubRegIdx == 0)
350f9acacaaSMatthias Braun continue;
351f9acacaaSMatthias Braun // After assigning the new vreg we may not have any other sublanes living
352f9acacaaSMatthias Braun // in and out of the instruction anymore. We need to add new dead and
353f9acacaaSMatthias Braun // undef flags in these cases.
354f9acacaaSMatthias Braun if (!MO.isUndef()) {
355f9acacaaSMatthias Braun SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
356f9acacaaSMatthias Braun if (!subRangeLiveAt(LI, Pos))
357f9acacaaSMatthias Braun MO.setIsUndef();
358f9acacaaSMatthias Braun }
359f9acacaaSMatthias Braun if (!MO.isDead()) {
360f9acacaaSMatthias Braun SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()).getDeadSlot();
361f9acacaaSMatthias Braun if (!subRangeLiveAt(LI, Pos))
362f9acacaaSMatthias Braun MO.setIsDead();
363f9acacaaSMatthias Braun }
364f9acacaaSMatthias Braun }
365f9acacaaSMatthias Braun
366f9acacaaSMatthias Braun if (I == 0)
367f9acacaaSMatthias Braun LI.clear();
368f9acacaaSMatthias Braun LIS->constructMainRangeFromSubranges(LI);
369a7ed090bSKrzysztof Parzyszek // A def of a subregister may be a use of other register lanes. Replacing
370a7ed090bSKrzysztof Parzyszek // such a def with a def of a different register will eliminate the use,
371a7ed090bSKrzysztof Parzyszek // and may cause the recorded live range to be larger than the actual
372a7ed090bSKrzysztof Parzyszek // liveness in the program IR.
373a7ed090bSKrzysztof Parzyszek LIS->shrinkToUses(&LI);
374f9acacaaSMatthias Braun }
375f9acacaaSMatthias Braun }
376f9acacaaSMatthias Braun
runOnMachineFunction(MachineFunction & MF)377f9acacaaSMatthias Braun bool RenameIndependentSubregs::runOnMachineFunction(MachineFunction &MF) {
378f9acacaaSMatthias Braun // Skip renaming if liveness of subregister is not tracked.
379f1b20c52SMatthias Braun MRI = &MF.getRegInfo();
380f1b20c52SMatthias Braun if (!MRI->subRegLivenessEnabled())
381f9acacaaSMatthias Braun return false;
382f9acacaaSMatthias Braun
383d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Renaming independent subregister live ranges in "
384f9acacaaSMatthias Braun << MF.getName() << '\n');
385f9acacaaSMatthias Braun
386f9acacaaSMatthias Braun LIS = &getAnalysis<LiveIntervals>();
387f9acacaaSMatthias Braun TII = MF.getSubtarget().getInstrInfo();
388f9acacaaSMatthias Braun
389f9acacaaSMatthias Braun // Iterate over all vregs. Note that we query getNumVirtRegs() the newly
390f9acacaaSMatthias Braun // created vregs end up with higher numbers but do not need to be visited as
391f9acacaaSMatthias Braun // there can't be any further splitting.
392f9acacaaSMatthias Braun bool Changed = false;
393f9acacaaSMatthias Braun for (size_t I = 0, E = MRI->getNumVirtRegs(); I < E; ++I) {
3942bea69bfSDaniel Sanders unsigned Reg = Register::index2VirtReg(I);
395f9acacaaSMatthias Braun if (!LIS->hasInterval(Reg))
396f9acacaaSMatthias Braun continue;
397f9acacaaSMatthias Braun LiveInterval &LI = LIS->getInterval(Reg);
398f9acacaaSMatthias Braun if (!LI.hasSubRanges())
399f9acacaaSMatthias Braun continue;
400f9acacaaSMatthias Braun
401f9acacaaSMatthias Braun Changed |= renameComponents(LI);
402f9acacaaSMatthias Braun }
403f9acacaaSMatthias Braun
404f9acacaaSMatthias Braun return Changed;
405f9acacaaSMatthias Braun }
406