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