10b57cec5SDimitry Andric //===-- RenameIndependentSubregs.cpp - Live Interval Analysis -------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric /// Rename independent subregisters looks for virtual registers with
100b57cec5SDimitry Andric /// independently used subregisters and renames them to new virtual registers.
110b57cec5SDimitry Andric /// Example: In the following:
120b57cec5SDimitry Andric /// %0:sub0<read-undef> = ...
130b57cec5SDimitry Andric /// %0:sub1 = ...
140b57cec5SDimitry Andric /// use %0:sub0
150b57cec5SDimitry Andric /// %0:sub0 = ...
160b57cec5SDimitry Andric /// use %0:sub0
170b57cec5SDimitry Andric /// use %0:sub1
180b57cec5SDimitry Andric /// sub0 and sub1 are never used together, and we have two independent sub0
190b57cec5SDimitry Andric /// definitions. This pass will rename to:
200b57cec5SDimitry Andric /// %0:sub0<read-undef> = ...
210b57cec5SDimitry Andric /// %1:sub1<read-undef> = ...
220b57cec5SDimitry Andric /// use %1:sub1
230b57cec5SDimitry Andric /// %2:sub1<read-undef> = ...
240b57cec5SDimitry Andric /// use %2:sub1
250b57cec5SDimitry Andric /// use %0:sub0
260b57cec5SDimitry Andric //
270b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
280b57cec5SDimitry Andric
290b57cec5SDimitry Andric #include "LiveRangeUtils.h"
300b57cec5SDimitry Andric #include "PHIEliminationUtils.h"
310b57cec5SDimitry Andric #include "llvm/CodeGen/LiveInterval.h"
320b57cec5SDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
330b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
340b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
350b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
360b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
37480093f4SDimitry Andric #include "llvm/InitializePasses.h"
3881ad6265SDimitry Andric #include "llvm/Pass.h"
390b57cec5SDimitry Andric
400b57cec5SDimitry Andric using namespace llvm;
410b57cec5SDimitry Andric
420b57cec5SDimitry Andric #define DEBUG_TYPE "rename-independent-subregs"
430b57cec5SDimitry Andric
440b57cec5SDimitry Andric namespace {
450b57cec5SDimitry Andric
460b57cec5SDimitry Andric class RenameIndependentSubregs : public MachineFunctionPass {
470b57cec5SDimitry Andric public:
480b57cec5SDimitry Andric static char ID;
RenameIndependentSubregs()490b57cec5SDimitry Andric RenameIndependentSubregs() : MachineFunctionPass(ID) {}
500b57cec5SDimitry Andric
getPassName() const510b57cec5SDimitry Andric StringRef getPassName() const override {
520b57cec5SDimitry Andric return "Rename Disconnected Subregister Components";
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric
getAnalysisUsage(AnalysisUsage & AU) const550b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override {
560b57cec5SDimitry Andric AU.setPreservesCFG();
57*0fca6ea1SDimitry Andric AU.addRequired<LiveIntervalsWrapperPass>();
58*0fca6ea1SDimitry Andric AU.addPreserved<LiveIntervalsWrapperPass>();
59*0fca6ea1SDimitry Andric AU.addRequired<SlotIndexesWrapperPass>();
60*0fca6ea1SDimitry Andric AU.addPreserved<SlotIndexesWrapperPass>();
610b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU);
620b57cec5SDimitry Andric }
630b57cec5SDimitry Andric
640b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override;
650b57cec5SDimitry Andric
660b57cec5SDimitry Andric private:
670b57cec5SDimitry Andric struct SubRangeInfo {
680b57cec5SDimitry Andric ConnectedVNInfoEqClasses ConEQ;
690b57cec5SDimitry Andric LiveInterval::SubRange *SR;
700b57cec5SDimitry Andric unsigned Index;
710b57cec5SDimitry Andric
SubRangeInfo__anon60dd69b50111::RenameIndependentSubregs::SubRangeInfo720b57cec5SDimitry Andric SubRangeInfo(LiveIntervals &LIS, LiveInterval::SubRange &SR,
730b57cec5SDimitry Andric unsigned Index)
740b57cec5SDimitry Andric : ConEQ(LIS), SR(&SR), Index(Index) {}
750b57cec5SDimitry Andric };
760b57cec5SDimitry Andric
770b57cec5SDimitry Andric /// Split unrelated subregister components and rename them to new vregs.
780b57cec5SDimitry Andric bool renameComponents(LiveInterval &LI) const;
790b57cec5SDimitry Andric
800b57cec5SDimitry Andric /// Build a vector of SubRange infos and a union find set of
810b57cec5SDimitry Andric /// equivalence classes.
820b57cec5SDimitry Andric /// Returns true if more than 1 equivalence class was found.
830b57cec5SDimitry Andric bool findComponents(IntEqClasses &Classes,
840b57cec5SDimitry Andric SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
850b57cec5SDimitry Andric LiveInterval &LI) const;
860b57cec5SDimitry Andric
870b57cec5SDimitry Andric /// Distribute the LiveInterval segments into the new LiveIntervals
880b57cec5SDimitry Andric /// belonging to their class.
890b57cec5SDimitry Andric void distribute(const IntEqClasses &Classes,
900b57cec5SDimitry Andric const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
910b57cec5SDimitry Andric const SmallVectorImpl<LiveInterval*> &Intervals) const;
920b57cec5SDimitry Andric
930b57cec5SDimitry Andric /// Constructs main liverange and add missing undef+dead flags.
940b57cec5SDimitry Andric void computeMainRangesFixFlags(const IntEqClasses &Classes,
950b57cec5SDimitry Andric const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
960b57cec5SDimitry Andric const SmallVectorImpl<LiveInterval*> &Intervals) const;
970b57cec5SDimitry Andric
980b57cec5SDimitry Andric /// Rewrite Machine Operands to use the new vreg belonging to their class.
990b57cec5SDimitry Andric void rewriteOperands(const IntEqClasses &Classes,
1000b57cec5SDimitry Andric const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
1010b57cec5SDimitry Andric const SmallVectorImpl<LiveInterval*> &Intervals) const;
1020b57cec5SDimitry Andric
1030b57cec5SDimitry Andric
10406c3fb27SDimitry Andric LiveIntervals *LIS = nullptr;
10506c3fb27SDimitry Andric MachineRegisterInfo *MRI = nullptr;
10606c3fb27SDimitry Andric const TargetInstrInfo *TII = nullptr;
1070b57cec5SDimitry Andric };
1080b57cec5SDimitry Andric
1090b57cec5SDimitry Andric } // end anonymous namespace
1100b57cec5SDimitry Andric
1110b57cec5SDimitry Andric char RenameIndependentSubregs::ID;
1120b57cec5SDimitry Andric
1130b57cec5SDimitry Andric char &llvm::RenameIndependentSubregsID = RenameIndependentSubregs::ID;
1140b57cec5SDimitry Andric
1150b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(RenameIndependentSubregs, DEBUG_TYPE,
1160b57cec5SDimitry Andric "Rename Independent Subregisters", false, false)
INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)117*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
118*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
1190b57cec5SDimitry Andric INITIALIZE_PASS_END(RenameIndependentSubregs, DEBUG_TYPE,
1200b57cec5SDimitry Andric "Rename Independent Subregisters", false, false)
1210b57cec5SDimitry Andric
1220b57cec5SDimitry Andric bool RenameIndependentSubregs::renameComponents(LiveInterval &LI) const {
1230b57cec5SDimitry Andric // Shortcut: We cannot have split components with a single definition.
1240b57cec5SDimitry Andric if (LI.valnos.size() < 2)
1250b57cec5SDimitry Andric return false;
1260b57cec5SDimitry Andric
1270b57cec5SDimitry Andric SmallVector<SubRangeInfo, 4> SubRangeInfos;
1280b57cec5SDimitry Andric IntEqClasses Classes;
1290b57cec5SDimitry Andric if (!findComponents(Classes, SubRangeInfos, LI))
1300b57cec5SDimitry Andric return false;
1310b57cec5SDimitry Andric
1320b57cec5SDimitry Andric // Create a new VReg for each class.
133bdd1243dSDimitry Andric Register Reg = LI.reg();
1340b57cec5SDimitry Andric const TargetRegisterClass *RegClass = MRI->getRegClass(Reg);
1350b57cec5SDimitry Andric SmallVector<LiveInterval*, 4> Intervals;
1360b57cec5SDimitry Andric Intervals.push_back(&LI);
1370b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << printReg(Reg) << ": Found " << Classes.getNumClasses()
1380b57cec5SDimitry Andric << " equivalence classes.\n");
1390b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << printReg(Reg) << ": Splitting into newly created:");
1400b57cec5SDimitry Andric for (unsigned I = 1, NumClasses = Classes.getNumClasses(); I < NumClasses;
1410b57cec5SDimitry Andric ++I) {
1428bcb0991SDimitry Andric Register NewVReg = MRI->createVirtualRegister(RegClass);
1430b57cec5SDimitry Andric LiveInterval &NewLI = LIS->createEmptyInterval(NewVReg);
1440b57cec5SDimitry Andric Intervals.push_back(&NewLI);
1450b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << ' ' << printReg(NewVReg));
1460b57cec5SDimitry Andric }
1470b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << '\n');
1480b57cec5SDimitry Andric
1490b57cec5SDimitry Andric rewriteOperands(Classes, SubRangeInfos, Intervals);
1500b57cec5SDimitry Andric distribute(Classes, SubRangeInfos, Intervals);
1510b57cec5SDimitry Andric computeMainRangesFixFlags(Classes, SubRangeInfos, Intervals);
1520b57cec5SDimitry Andric return true;
1530b57cec5SDimitry Andric }
1540b57cec5SDimitry Andric
findComponents(IntEqClasses & Classes,SmallVectorImpl<RenameIndependentSubregs::SubRangeInfo> & SubRangeInfos,LiveInterval & LI) const1550b57cec5SDimitry Andric bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes,
1560b57cec5SDimitry Andric SmallVectorImpl<RenameIndependentSubregs::SubRangeInfo> &SubRangeInfos,
1570b57cec5SDimitry Andric LiveInterval &LI) const {
1580b57cec5SDimitry Andric // First step: Create connected components for the VNInfos inside the
1590b57cec5SDimitry Andric // subranges and count the global number of such components.
1600b57cec5SDimitry Andric unsigned NumComponents = 0;
1610b57cec5SDimitry Andric for (LiveInterval::SubRange &SR : LI.subranges()) {
1620b57cec5SDimitry Andric SubRangeInfos.push_back(SubRangeInfo(*LIS, SR, NumComponents));
1630b57cec5SDimitry Andric ConnectedVNInfoEqClasses &ConEQ = SubRangeInfos.back().ConEQ;
1640b57cec5SDimitry Andric
1650b57cec5SDimitry Andric unsigned NumSubComponents = ConEQ.Classify(SR);
1660b57cec5SDimitry Andric NumComponents += NumSubComponents;
1670b57cec5SDimitry Andric }
1680b57cec5SDimitry Andric // Shortcut: With only 1 subrange, the normal separate component tests are
1690b57cec5SDimitry Andric // enough and we do not need to perform the union-find on the subregister
1700b57cec5SDimitry Andric // segments.
1710b57cec5SDimitry Andric if (SubRangeInfos.size() < 2)
1720b57cec5SDimitry Andric return false;
1730b57cec5SDimitry Andric
1740b57cec5SDimitry Andric // Next step: Build union-find structure over all subranges and merge classes
1750b57cec5SDimitry Andric // across subranges when they are affected by the same MachineOperand.
1760b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
1770b57cec5SDimitry Andric Classes.grow(NumComponents);
178bdd1243dSDimitry Andric Register Reg = LI.reg();
1790b57cec5SDimitry Andric for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
1800b57cec5SDimitry Andric if (!MO.isDef() && !MO.readsReg())
1810b57cec5SDimitry Andric continue;
1820b57cec5SDimitry Andric unsigned SubRegIdx = MO.getSubReg();
1830b57cec5SDimitry Andric LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
1840b57cec5SDimitry Andric unsigned MergedID = ~0u;
1850b57cec5SDimitry Andric for (RenameIndependentSubregs::SubRangeInfo &SRInfo : SubRangeInfos) {
1860b57cec5SDimitry Andric const LiveInterval::SubRange &SR = *SRInfo.SR;
1870b57cec5SDimitry Andric if ((SR.LaneMask & LaneMask).none())
1880b57cec5SDimitry Andric continue;
1890b57cec5SDimitry Andric SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
1900b57cec5SDimitry Andric Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber())
1910b57cec5SDimitry Andric : Pos.getBaseIndex();
1920b57cec5SDimitry Andric const VNInfo *VNI = SR.getVNInfoAt(Pos);
1930b57cec5SDimitry Andric if (VNI == nullptr)
1940b57cec5SDimitry Andric continue;
1950b57cec5SDimitry Andric
1960b57cec5SDimitry Andric // Map to local representant ID.
1970b57cec5SDimitry Andric unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
1980b57cec5SDimitry Andric // Global ID
1990b57cec5SDimitry Andric unsigned ID = LocalID + SRInfo.Index;
2000b57cec5SDimitry Andric // Merge other sets
2010b57cec5SDimitry Andric MergedID = MergedID == ~0u ? ID : Classes.join(MergedID, ID);
2020b57cec5SDimitry Andric }
2030b57cec5SDimitry Andric }
2040b57cec5SDimitry Andric
2050b57cec5SDimitry Andric // Early exit if we ended up with a single equivalence class.
2060b57cec5SDimitry Andric Classes.compress();
2070b57cec5SDimitry Andric unsigned NumClasses = Classes.getNumClasses();
2080b57cec5SDimitry Andric return NumClasses > 1;
2090b57cec5SDimitry Andric }
2100b57cec5SDimitry Andric
rewriteOperands(const IntEqClasses & Classes,const SmallVectorImpl<SubRangeInfo> & SubRangeInfos,const SmallVectorImpl<LiveInterval * > & Intervals) const2110b57cec5SDimitry Andric void RenameIndependentSubregs::rewriteOperands(const IntEqClasses &Classes,
2120b57cec5SDimitry Andric const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
2130b57cec5SDimitry Andric const SmallVectorImpl<LiveInterval*> &Intervals) const {
2140b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
215e8d8bef9SDimitry Andric unsigned Reg = Intervals[0]->reg();
2160b57cec5SDimitry Andric for (MachineRegisterInfo::reg_nodbg_iterator I = MRI->reg_nodbg_begin(Reg),
2170b57cec5SDimitry Andric E = MRI->reg_nodbg_end(); I != E; ) {
2180b57cec5SDimitry Andric MachineOperand &MO = *I++;
2190b57cec5SDimitry Andric if (!MO.isDef() && !MO.readsReg())
2200b57cec5SDimitry Andric continue;
2210b57cec5SDimitry Andric
2220b57cec5SDimitry Andric auto *MI = MO.getParent();
2230b57cec5SDimitry Andric SlotIndex Pos = LIS->getInstructionIndex(*MI);
2240b57cec5SDimitry Andric Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber())
2250b57cec5SDimitry Andric : Pos.getBaseIndex();
2260b57cec5SDimitry Andric unsigned SubRegIdx = MO.getSubReg();
2270b57cec5SDimitry Andric LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
2280b57cec5SDimitry Andric
2290b57cec5SDimitry Andric unsigned ID = ~0u;
2300b57cec5SDimitry Andric for (const SubRangeInfo &SRInfo : SubRangeInfos) {
2310b57cec5SDimitry Andric const LiveInterval::SubRange &SR = *SRInfo.SR;
2320b57cec5SDimitry Andric if ((SR.LaneMask & LaneMask).none())
2330b57cec5SDimitry Andric continue;
2340b57cec5SDimitry Andric const VNInfo *VNI = SR.getVNInfoAt(Pos);
2350b57cec5SDimitry Andric if (VNI == nullptr)
2360b57cec5SDimitry Andric continue;
2370b57cec5SDimitry Andric
2380b57cec5SDimitry Andric // Map to local representant ID.
2390b57cec5SDimitry Andric unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
2400b57cec5SDimitry Andric // Global ID
2410b57cec5SDimitry Andric ID = Classes[LocalID + SRInfo.Index];
2420b57cec5SDimitry Andric break;
2430b57cec5SDimitry Andric }
2440b57cec5SDimitry Andric
245e8d8bef9SDimitry Andric unsigned VReg = Intervals[ID]->reg();
2460b57cec5SDimitry Andric MO.setReg(VReg);
2470b57cec5SDimitry Andric
2480b57cec5SDimitry Andric if (MO.isTied() && Reg != VReg) {
2490b57cec5SDimitry Andric /// Undef use operands are not tracked in the equivalence class,
2500b57cec5SDimitry Andric /// but need to be updated if they are tied; take care to only
2510b57cec5SDimitry Andric /// update the tied operand.
25206c3fb27SDimitry Andric unsigned OperandNo = MO.getOperandNo();
2530b57cec5SDimitry Andric unsigned TiedIdx = MI->findTiedOperandIdx(OperandNo);
2540b57cec5SDimitry Andric MI->getOperand(TiedIdx).setReg(VReg);
2550b57cec5SDimitry Andric
2560b57cec5SDimitry Andric // above substitution breaks the iterator, so restart.
2570b57cec5SDimitry Andric I = MRI->reg_nodbg_begin(Reg);
2580b57cec5SDimitry Andric }
2590b57cec5SDimitry Andric }
2600b57cec5SDimitry Andric // TODO: We could attempt to recompute new register classes while visiting
2610b57cec5SDimitry Andric // the operands: Some of the split register may be fine with less constraint
2620b57cec5SDimitry Andric // classes than the original vreg.
2630b57cec5SDimitry Andric }
2640b57cec5SDimitry Andric
distribute(const IntEqClasses & Classes,const SmallVectorImpl<SubRangeInfo> & SubRangeInfos,const SmallVectorImpl<LiveInterval * > & Intervals) const2650b57cec5SDimitry Andric void RenameIndependentSubregs::distribute(const IntEqClasses &Classes,
2660b57cec5SDimitry Andric const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
2670b57cec5SDimitry Andric const SmallVectorImpl<LiveInterval*> &Intervals) const {
2680b57cec5SDimitry Andric unsigned NumClasses = Classes.getNumClasses();
2690b57cec5SDimitry Andric SmallVector<unsigned, 8> VNIMapping;
2700b57cec5SDimitry Andric SmallVector<LiveInterval::SubRange*, 8> SubRanges;
2710b57cec5SDimitry Andric BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
2720b57cec5SDimitry Andric for (const SubRangeInfo &SRInfo : SubRangeInfos) {
2730b57cec5SDimitry Andric LiveInterval::SubRange &SR = *SRInfo.SR;
2740b57cec5SDimitry Andric unsigned NumValNos = SR.valnos.size();
2750b57cec5SDimitry Andric VNIMapping.clear();
2760b57cec5SDimitry Andric VNIMapping.reserve(NumValNos);
2770b57cec5SDimitry Andric SubRanges.clear();
2780b57cec5SDimitry Andric SubRanges.resize(NumClasses-1, nullptr);
2790b57cec5SDimitry Andric for (unsigned I = 0; I < NumValNos; ++I) {
2800b57cec5SDimitry Andric const VNInfo &VNI = *SR.valnos[I];
2810b57cec5SDimitry Andric unsigned LocalID = SRInfo.ConEQ.getEqClass(&VNI);
2820b57cec5SDimitry Andric unsigned ID = Classes[LocalID + SRInfo.Index];
2830b57cec5SDimitry Andric VNIMapping.push_back(ID);
2840b57cec5SDimitry Andric if (ID > 0 && SubRanges[ID-1] == nullptr)
2850b57cec5SDimitry Andric SubRanges[ID-1] = Intervals[ID]->createSubRange(Allocator, SR.LaneMask);
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric DistributeRange(SR, SubRanges.data(), VNIMapping);
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric }
2900b57cec5SDimitry Andric
subRangeLiveAt(const LiveInterval & LI,SlotIndex Pos)2910b57cec5SDimitry Andric static bool subRangeLiveAt(const LiveInterval &LI, SlotIndex Pos) {
2920b57cec5SDimitry Andric for (const LiveInterval::SubRange &SR : LI.subranges()) {
2930b57cec5SDimitry Andric if (SR.liveAt(Pos))
2940b57cec5SDimitry Andric return true;
2950b57cec5SDimitry Andric }
2960b57cec5SDimitry Andric return false;
2970b57cec5SDimitry Andric }
2980b57cec5SDimitry Andric
computeMainRangesFixFlags(const IntEqClasses & Classes,const SmallVectorImpl<SubRangeInfo> & SubRangeInfos,const SmallVectorImpl<LiveInterval * > & Intervals) const2990b57cec5SDimitry Andric void RenameIndependentSubregs::computeMainRangesFixFlags(
3000b57cec5SDimitry Andric const IntEqClasses &Classes,
3010b57cec5SDimitry Andric const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
3020b57cec5SDimitry Andric const SmallVectorImpl<LiveInterval*> &Intervals) const {
3030b57cec5SDimitry Andric BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
3040b57cec5SDimitry Andric const SlotIndexes &Indexes = *LIS->getSlotIndexes();
3050b57cec5SDimitry Andric for (size_t I = 0, E = Intervals.size(); I < E; ++I) {
3060b57cec5SDimitry Andric LiveInterval &LI = *Intervals[I];
307bdd1243dSDimitry Andric Register Reg = LI.reg();
3080b57cec5SDimitry Andric
3090b57cec5SDimitry Andric LI.removeEmptySubRanges();
3100b57cec5SDimitry Andric
3110b57cec5SDimitry Andric // There must be a def (or live-in) before every use. Splitting vregs may
3120b57cec5SDimitry Andric // violate this principle as the splitted vreg may not have a definition on
3130b57cec5SDimitry Andric // every path. Fix this by creating IMPLICIT_DEF instruction as necessary.
3140b57cec5SDimitry Andric for (const LiveInterval::SubRange &SR : LI.subranges()) {
3150b57cec5SDimitry Andric // Search for "PHI" value numbers in the subranges. We must find a live
3160b57cec5SDimitry Andric // value in each predecessor block, add an IMPLICIT_DEF where it is
3170b57cec5SDimitry Andric // missing.
3180b57cec5SDimitry Andric for (unsigned I = 0; I < SR.valnos.size(); ++I) {
3190b57cec5SDimitry Andric const VNInfo &VNI = *SR.valnos[I];
3200b57cec5SDimitry Andric if (VNI.isUnused() || !VNI.isPHIDef())
3210b57cec5SDimitry Andric continue;
3220b57cec5SDimitry Andric
3230b57cec5SDimitry Andric SlotIndex Def = VNI.def;
3240b57cec5SDimitry Andric MachineBasicBlock &MBB = *Indexes.getMBBFromIndex(Def);
3250b57cec5SDimitry Andric for (MachineBasicBlock *PredMBB : MBB.predecessors()) {
3260b57cec5SDimitry Andric SlotIndex PredEnd = Indexes.getMBBEndIdx(PredMBB);
3270b57cec5SDimitry Andric if (subRangeLiveAt(LI, PredEnd.getPrevSlot()))
3280b57cec5SDimitry Andric continue;
3290b57cec5SDimitry Andric
3300b57cec5SDimitry Andric MachineBasicBlock::iterator InsertPos =
3310b57cec5SDimitry Andric llvm::findPHICopyInsertPoint(PredMBB, &MBB, Reg);
3320b57cec5SDimitry Andric const MCInstrDesc &MCDesc = TII->get(TargetOpcode::IMPLICIT_DEF);
3330b57cec5SDimitry Andric MachineInstrBuilder ImpDef = BuildMI(*PredMBB, InsertPos,
3340b57cec5SDimitry Andric DebugLoc(), MCDesc, Reg);
3350b57cec5SDimitry Andric SlotIndex DefIdx = LIS->InsertMachineInstrInMaps(*ImpDef);
3360b57cec5SDimitry Andric SlotIndex RegDefIdx = DefIdx.getRegSlot();
337*0fca6ea1SDimitry Andric LaneBitmask Mask = MRI->getMaxLaneMaskForVReg(Reg);
3380b57cec5SDimitry Andric for (LiveInterval::SubRange &SR : LI.subranges()) {
339*0fca6ea1SDimitry Andric Mask = Mask & ~SR.LaneMask;
3400b57cec5SDimitry Andric VNInfo *SRVNI = SR.getNextValue(RegDefIdx, Allocator);
3410b57cec5SDimitry Andric SR.addSegment(LiveRange::Segment(RegDefIdx, PredEnd, SRVNI));
3420b57cec5SDimitry Andric }
343*0fca6ea1SDimitry Andric
344*0fca6ea1SDimitry Andric if (!Mask.none()) {
345*0fca6ea1SDimitry Andric LiveInterval::SubRange *SR = LI.createSubRange(Allocator, Mask);
346*0fca6ea1SDimitry Andric SR->createDeadDef(RegDefIdx, Allocator);
347*0fca6ea1SDimitry Andric }
3480b57cec5SDimitry Andric }
3490b57cec5SDimitry Andric }
3500b57cec5SDimitry Andric }
3510b57cec5SDimitry Andric
3520b57cec5SDimitry Andric for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
3530b57cec5SDimitry Andric if (!MO.isDef())
3540b57cec5SDimitry Andric continue;
3550b57cec5SDimitry Andric unsigned SubRegIdx = MO.getSubReg();
3560b57cec5SDimitry Andric if (SubRegIdx == 0)
3570b57cec5SDimitry Andric continue;
3580b57cec5SDimitry Andric // After assigning the new vreg we may not have any other sublanes living
3590b57cec5SDimitry Andric // in and out of the instruction anymore. We need to add new dead and
3600b57cec5SDimitry Andric // undef flags in these cases.
3610b57cec5SDimitry Andric if (!MO.isUndef()) {
3620b57cec5SDimitry Andric SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
3630b57cec5SDimitry Andric if (!subRangeLiveAt(LI, Pos))
3640b57cec5SDimitry Andric MO.setIsUndef();
3650b57cec5SDimitry Andric }
3660b57cec5SDimitry Andric if (!MO.isDead()) {
3670b57cec5SDimitry Andric SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()).getDeadSlot();
3680b57cec5SDimitry Andric if (!subRangeLiveAt(LI, Pos))
3690b57cec5SDimitry Andric MO.setIsDead();
3700b57cec5SDimitry Andric }
3710b57cec5SDimitry Andric }
3720b57cec5SDimitry Andric
3730b57cec5SDimitry Andric if (I == 0)
3740b57cec5SDimitry Andric LI.clear();
3750b57cec5SDimitry Andric LIS->constructMainRangeFromSubranges(LI);
3760b57cec5SDimitry Andric // A def of a subregister may be a use of other register lanes. Replacing
3770b57cec5SDimitry Andric // such a def with a def of a different register will eliminate the use,
3780b57cec5SDimitry Andric // and may cause the recorded live range to be larger than the actual
3790b57cec5SDimitry Andric // liveness in the program IR.
3800b57cec5SDimitry Andric LIS->shrinkToUses(&LI);
3810b57cec5SDimitry Andric }
3820b57cec5SDimitry Andric }
3830b57cec5SDimitry Andric
runOnMachineFunction(MachineFunction & MF)3840b57cec5SDimitry Andric bool RenameIndependentSubregs::runOnMachineFunction(MachineFunction &MF) {
3850b57cec5SDimitry Andric // Skip renaming if liveness of subregister is not tracked.
3860b57cec5SDimitry Andric MRI = &MF.getRegInfo();
3870b57cec5SDimitry Andric if (!MRI->subRegLivenessEnabled())
3880b57cec5SDimitry Andric return false;
3890b57cec5SDimitry Andric
3900b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Renaming independent subregister live ranges in "
3910b57cec5SDimitry Andric << MF.getName() << '\n');
3920b57cec5SDimitry Andric
393*0fca6ea1SDimitry Andric LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
3940b57cec5SDimitry Andric TII = MF.getSubtarget().getInstrInfo();
3950b57cec5SDimitry Andric
3960b57cec5SDimitry Andric // Iterate over all vregs. Note that we query getNumVirtRegs() the newly
3970b57cec5SDimitry Andric // created vregs end up with higher numbers but do not need to be visited as
3980b57cec5SDimitry Andric // there can't be any further splitting.
3990b57cec5SDimitry Andric bool Changed = false;
4000b57cec5SDimitry Andric for (size_t I = 0, E = MRI->getNumVirtRegs(); I < E; ++I) {
401bdd1243dSDimitry Andric Register Reg = Register::index2VirtReg(I);
4020b57cec5SDimitry Andric if (!LIS->hasInterval(Reg))
4030b57cec5SDimitry Andric continue;
4040b57cec5SDimitry Andric LiveInterval &LI = LIS->getInterval(Reg);
4050b57cec5SDimitry Andric if (!LI.hasSubRanges())
4060b57cec5SDimitry Andric continue;
4070b57cec5SDimitry Andric
4080b57cec5SDimitry Andric Changed |= renameComponents(LI);
4090b57cec5SDimitry Andric }
4100b57cec5SDimitry Andric
4110b57cec5SDimitry Andric return Changed;
4120b57cec5SDimitry Andric }
413