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; 490b57cec5SDimitry Andric RenameIndependentSubregs() : MachineFunctionPass(ID) {} 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric StringRef getPassName() const override { 520b57cec5SDimitry Andric return "Rename Disconnected Subregister Components"; 530b57cec5SDimitry Andric } 540b57cec5SDimitry Andric 550b57cec5SDimitry 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 720b57cec5SDimitry 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) 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 1550b57cec5SDimitry 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 2110b57cec5SDimitry 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 2650b57cec5SDimitry 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 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 2990b57cec5SDimitry 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 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