1 //===- GCNRegPressure.cpp -------------------------------------------------===// 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 /// \file 10 /// This file implements the GCNRegPressure class. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "GCNRegPressure.h" 15 #include "AMDGPU.h" 16 #include "llvm/CodeGen/RegisterPressure.h" 17 18 using namespace llvm; 19 20 #define DEBUG_TYPE "machine-scheduler" 21 22 bool llvm::isEqual(const GCNRPTracker::LiveRegSet &S1, 23 const GCNRPTracker::LiveRegSet &S2) { 24 if (S1.size() != S2.size()) 25 return false; 26 27 for (const auto &P : S1) { 28 auto I = S2.find(P.first); 29 if (I == S2.end() || I->second != P.second) 30 return false; 31 } 32 return true; 33 } 34 35 /////////////////////////////////////////////////////////////////////////////// 36 // GCNRegPressure 37 38 unsigned GCNRegPressure::getRegKind(Register Reg, 39 const MachineRegisterInfo &MRI) { 40 assert(Reg.isVirtual()); 41 const auto RC = MRI.getRegClass(Reg); 42 auto STI = static_cast<const SIRegisterInfo*>(MRI.getTargetRegisterInfo()); 43 return STI->isSGPRClass(RC) 44 ? (STI->getRegSizeInBits(*RC) == 32 ? SGPR32 : SGPR_TUPLE) 45 : STI->isAGPRClass(RC) 46 ? (STI->getRegSizeInBits(*RC) == 32 ? AGPR32 : AGPR_TUPLE) 47 : (STI->getRegSizeInBits(*RC) == 32 ? VGPR32 : VGPR_TUPLE); 48 } 49 50 void GCNRegPressure::inc(unsigned Reg, 51 LaneBitmask PrevMask, 52 LaneBitmask NewMask, 53 const MachineRegisterInfo &MRI) { 54 if (SIRegisterInfo::getNumCoveredRegs(NewMask) == 55 SIRegisterInfo::getNumCoveredRegs(PrevMask)) 56 return; 57 58 int Sign = 1; 59 if (NewMask < PrevMask) { 60 std::swap(NewMask, PrevMask); 61 Sign = -1; 62 } 63 64 switch (auto Kind = getRegKind(Reg, MRI)) { 65 case SGPR32: 66 case VGPR32: 67 case AGPR32: 68 Value[Kind] += Sign; 69 break; 70 71 case SGPR_TUPLE: 72 case VGPR_TUPLE: 73 case AGPR_TUPLE: 74 assert(PrevMask < NewMask); 75 76 Value[Kind == SGPR_TUPLE ? SGPR32 : Kind == AGPR_TUPLE ? AGPR32 : VGPR32] += 77 Sign * SIRegisterInfo::getNumCoveredRegs(~PrevMask & NewMask); 78 79 if (PrevMask.none()) { 80 assert(NewMask.any()); 81 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo(); 82 Value[Kind] += 83 Sign * TRI->getRegClassWeight(MRI.getRegClass(Reg)).RegWeight; 84 } 85 break; 86 87 default: llvm_unreachable("Unknown register kind"); 88 } 89 } 90 91 bool GCNRegPressure::less(const GCNSubtarget &ST, 92 const GCNRegPressure& O, 93 unsigned MaxOccupancy) const { 94 const auto SGPROcc = std::min(MaxOccupancy, 95 ST.getOccupancyWithNumSGPRs(getSGPRNum())); 96 const auto VGPROcc = 97 std::min(MaxOccupancy, 98 ST.getOccupancyWithNumVGPRs(getVGPRNum(ST.hasGFX90AInsts()))); 99 const auto OtherSGPROcc = std::min(MaxOccupancy, 100 ST.getOccupancyWithNumSGPRs(O.getSGPRNum())); 101 const auto OtherVGPROcc = 102 std::min(MaxOccupancy, 103 ST.getOccupancyWithNumVGPRs(O.getVGPRNum(ST.hasGFX90AInsts()))); 104 105 const auto Occ = std::min(SGPROcc, VGPROcc); 106 const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc); 107 if (Occ != OtherOcc) 108 return Occ > OtherOcc; 109 110 bool SGPRImportant = SGPROcc < VGPROcc; 111 const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc; 112 113 // if both pressures disagree on what is more important compare vgprs 114 if (SGPRImportant != OtherSGPRImportant) { 115 SGPRImportant = false; 116 } 117 118 // compare large regs pressure 119 bool SGPRFirst = SGPRImportant; 120 for (int I = 2; I > 0; --I, SGPRFirst = !SGPRFirst) { 121 if (SGPRFirst) { 122 auto SW = getSGPRTuplesWeight(); 123 auto OtherSW = O.getSGPRTuplesWeight(); 124 if (SW != OtherSW) 125 return SW < OtherSW; 126 } else { 127 auto VW = getVGPRTuplesWeight(); 128 auto OtherVW = O.getVGPRTuplesWeight(); 129 if (VW != OtherVW) 130 return VW < OtherVW; 131 } 132 } 133 return SGPRImportant ? (getSGPRNum() < O.getSGPRNum()): 134 (getVGPRNum(ST.hasGFX90AInsts()) < 135 O.getVGPRNum(ST.hasGFX90AInsts())); 136 } 137 138 Printable llvm::print(const GCNRegPressure &RP, const GCNSubtarget *ST) { 139 return Printable([&RP, ST](raw_ostream &OS) { 140 OS << "VGPRs: " << RP.Value[GCNRegPressure::VGPR32] << ' ' 141 << "AGPRs: " << RP.getAGPRNum(); 142 if (ST) 143 OS << "(O" 144 << ST->getOccupancyWithNumVGPRs(RP.getVGPRNum(ST->hasGFX90AInsts())) 145 << ')'; 146 OS << ", SGPRs: " << RP.getSGPRNum(); 147 if (ST) 148 OS << "(O" << ST->getOccupancyWithNumSGPRs(RP.getSGPRNum()) << ')'; 149 OS << ", LVGPR WT: " << RP.getVGPRTuplesWeight() 150 << ", LSGPR WT: " << RP.getSGPRTuplesWeight(); 151 if (ST) 152 OS << " -> Occ: " << RP.getOccupancy(*ST); 153 OS << '\n'; 154 }); 155 } 156 157 static LaneBitmask getDefRegMask(const MachineOperand &MO, 158 const MachineRegisterInfo &MRI) { 159 assert(MO.isDef() && MO.isReg() && MO.getReg().isVirtual()); 160 161 // We don't rely on read-undef flag because in case of tentative schedule 162 // tracking it isn't set correctly yet. This works correctly however since 163 // use mask has been tracked before using LIS. 164 return MO.getSubReg() == 0 ? 165 MRI.getMaxLaneMaskForVReg(MO.getReg()) : 166 MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(MO.getSubReg()); 167 } 168 169 static void 170 collectVirtualRegUses(SmallVectorImpl<RegisterMaskPair> &RegMaskPairs, 171 const MachineInstr &MI, const LiveIntervals &LIS, 172 const MachineRegisterInfo &MRI) { 173 SlotIndex InstrSI; 174 for (const auto &MO : MI.operands()) { 175 if (!MO.isReg() || !MO.getReg().isVirtual()) 176 continue; 177 if (!MO.isUse() || !MO.readsReg()) 178 continue; 179 180 Register Reg = MO.getReg(); 181 if (llvm::any_of(RegMaskPairs, [Reg](const RegisterMaskPair &RM) { 182 return RM.RegUnit == Reg; 183 })) 184 continue; 185 186 LaneBitmask UseMask; 187 auto &LI = LIS.getInterval(Reg); 188 if (!LI.hasSubRanges()) 189 UseMask = MRI.getMaxLaneMaskForVReg(Reg); 190 else { 191 // For a tentative schedule LIS isn't updated yet but livemask should 192 // remain the same on any schedule. Subreg defs can be reordered but they 193 // all must dominate uses anyway. 194 if (!InstrSI) 195 InstrSI = LIS.getInstructionIndex(*MO.getParent()).getBaseIndex(); 196 UseMask = getLiveLaneMask(LI, InstrSI, MRI); 197 } 198 199 RegMaskPairs.emplace_back(Reg, UseMask); 200 } 201 } 202 203 /////////////////////////////////////////////////////////////////////////////// 204 // GCNRPTracker 205 206 LaneBitmask llvm::getLiveLaneMask(unsigned Reg, SlotIndex SI, 207 const LiveIntervals &LIS, 208 const MachineRegisterInfo &MRI) { 209 return getLiveLaneMask(LIS.getInterval(Reg), SI, MRI); 210 } 211 212 LaneBitmask llvm::getLiveLaneMask(const LiveInterval &LI, SlotIndex SI, 213 const MachineRegisterInfo &MRI) { 214 LaneBitmask LiveMask; 215 if (LI.hasSubRanges()) { 216 for (const auto &S : LI.subranges()) 217 if (S.liveAt(SI)) { 218 LiveMask |= S.LaneMask; 219 assert(LiveMask == (LiveMask & MRI.getMaxLaneMaskForVReg(LI.reg()))); 220 } 221 } else if (LI.liveAt(SI)) { 222 LiveMask = MRI.getMaxLaneMaskForVReg(LI.reg()); 223 } 224 return LiveMask; 225 } 226 227 GCNRPTracker::LiveRegSet llvm::getLiveRegs(SlotIndex SI, 228 const LiveIntervals &LIS, 229 const MachineRegisterInfo &MRI) { 230 GCNRPTracker::LiveRegSet LiveRegs; 231 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { 232 auto Reg = Register::index2VirtReg(I); 233 if (!LIS.hasInterval(Reg)) 234 continue; 235 auto LiveMask = getLiveLaneMask(Reg, SI, LIS, MRI); 236 if (LiveMask.any()) 237 LiveRegs[Reg] = LiveMask; 238 } 239 return LiveRegs; 240 } 241 242 void GCNRPTracker::reset(const MachineInstr &MI, 243 const LiveRegSet *LiveRegsCopy, 244 bool After) { 245 const MachineFunction &MF = *MI.getMF(); 246 MRI = &MF.getRegInfo(); 247 if (LiveRegsCopy) { 248 if (&LiveRegs != LiveRegsCopy) 249 LiveRegs = *LiveRegsCopy; 250 } else { 251 LiveRegs = After ? getLiveRegsAfter(MI, LIS) 252 : getLiveRegsBefore(MI, LIS); 253 } 254 255 MaxPressure = CurPressure = getRegPressure(*MRI, LiveRegs); 256 } 257 258 //////////////////////////////////////////////////////////////////////////////// 259 // GCNUpwardRPTracker 260 261 void GCNUpwardRPTracker::reset(const MachineRegisterInfo &MRI_, 262 const LiveRegSet &LiveRegs_) { 263 MRI = &MRI_; 264 LiveRegs = LiveRegs_; 265 LastTrackedMI = nullptr; 266 MaxPressure = CurPressure = getRegPressure(MRI_, LiveRegs_); 267 } 268 269 void GCNUpwardRPTracker::recede(const MachineInstr &MI) { 270 assert(MRI && "call reset first"); 271 272 LastTrackedMI = &MI; 273 274 if (MI.isDebugInstr()) 275 return; 276 277 // Kill all defs. 278 GCNRegPressure DefPressure, ECDefPressure; 279 bool HasECDefs = false; 280 for (const MachineOperand &MO : MI.all_defs()) { 281 if (!MO.getReg().isVirtual()) 282 continue; 283 284 Register Reg = MO.getReg(); 285 LaneBitmask DefMask = getDefRegMask(MO, *MRI); 286 287 // Treat a def as fully live at the moment of definition: keep a record. 288 if (MO.isEarlyClobber()) { 289 ECDefPressure.inc(Reg, LaneBitmask::getNone(), DefMask, *MRI); 290 HasECDefs = true; 291 } else 292 DefPressure.inc(Reg, LaneBitmask::getNone(), DefMask, *MRI); 293 294 auto I = LiveRegs.find(Reg); 295 if (I == LiveRegs.end()) 296 continue; 297 298 LaneBitmask &LiveMask = I->second; 299 LaneBitmask PrevMask = LiveMask; 300 LiveMask &= ~DefMask; 301 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI); 302 if (LiveMask.none()) 303 LiveRegs.erase(I); 304 } 305 306 // Update MaxPressure with defs pressure. 307 DefPressure += CurPressure; 308 if (HasECDefs) 309 DefPressure += ECDefPressure; 310 MaxPressure = max(DefPressure, MaxPressure); 311 312 // Make uses alive. 313 SmallVector<RegisterMaskPair, 8> RegUses; 314 collectVirtualRegUses(RegUses, MI, LIS, *MRI); 315 for (const RegisterMaskPair &U : RegUses) { 316 LaneBitmask &LiveMask = LiveRegs[U.RegUnit]; 317 LaneBitmask PrevMask = LiveMask; 318 LiveMask |= U.LaneMask; 319 CurPressure.inc(U.RegUnit, PrevMask, LiveMask, *MRI); 320 } 321 322 // Update MaxPressure with uses plus early-clobber defs pressure. 323 MaxPressure = HasECDefs ? max(CurPressure + ECDefPressure, MaxPressure) 324 : max(CurPressure, MaxPressure); 325 326 assert(CurPressure == getRegPressure(*MRI, LiveRegs)); 327 } 328 329 //////////////////////////////////////////////////////////////////////////////// 330 // GCNDownwardRPTracker 331 332 bool GCNDownwardRPTracker::reset(const MachineInstr &MI, 333 const LiveRegSet *LiveRegsCopy) { 334 MRI = &MI.getParent()->getParent()->getRegInfo(); 335 LastTrackedMI = nullptr; 336 MBBEnd = MI.getParent()->end(); 337 NextMI = &MI; 338 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd); 339 if (NextMI == MBBEnd) 340 return false; 341 GCNRPTracker::reset(*NextMI, LiveRegsCopy, false); 342 return true; 343 } 344 345 bool GCNDownwardRPTracker::advanceBeforeNext() { 346 assert(MRI && "call reset first"); 347 if (!LastTrackedMI) 348 return NextMI == MBBEnd; 349 350 assert(NextMI == MBBEnd || !NextMI->isDebugInstr()); 351 352 SlotIndex SI = NextMI == MBBEnd 353 ? LIS.getInstructionIndex(*LastTrackedMI).getDeadSlot() 354 : LIS.getInstructionIndex(*NextMI).getBaseIndex(); 355 assert(SI.isValid()); 356 357 // Remove dead registers or mask bits. 358 SmallSet<Register, 8> SeenRegs; 359 for (auto &MO : LastTrackedMI->operands()) { 360 if (!MO.isReg() || !MO.getReg().isVirtual()) 361 continue; 362 if (MO.isUse() && !MO.readsReg()) 363 continue; 364 if (!SeenRegs.insert(MO.getReg()).second) 365 continue; 366 const LiveInterval &LI = LIS.getInterval(MO.getReg()); 367 if (LI.hasSubRanges()) { 368 auto It = LiveRegs.end(); 369 for (const auto &S : LI.subranges()) { 370 if (!S.liveAt(SI)) { 371 if (It == LiveRegs.end()) { 372 It = LiveRegs.find(MO.getReg()); 373 if (It == LiveRegs.end()) 374 llvm_unreachable("register isn't live"); 375 } 376 auto PrevMask = It->second; 377 It->second &= ~S.LaneMask; 378 CurPressure.inc(MO.getReg(), PrevMask, It->second, *MRI); 379 } 380 } 381 if (It != LiveRegs.end() && It->second.none()) 382 LiveRegs.erase(It); 383 } else if (!LI.liveAt(SI)) { 384 auto It = LiveRegs.find(MO.getReg()); 385 if (It == LiveRegs.end()) 386 llvm_unreachable("register isn't live"); 387 CurPressure.inc(MO.getReg(), It->second, LaneBitmask::getNone(), *MRI); 388 LiveRegs.erase(It); 389 } 390 } 391 392 MaxPressure = max(MaxPressure, CurPressure); 393 394 LastTrackedMI = nullptr; 395 396 return NextMI == MBBEnd; 397 } 398 399 void GCNDownwardRPTracker::advanceToNext() { 400 LastTrackedMI = &*NextMI++; 401 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd); 402 403 // Add new registers or mask bits. 404 for (const auto &MO : LastTrackedMI->all_defs()) { 405 Register Reg = MO.getReg(); 406 if (!Reg.isVirtual()) 407 continue; 408 auto &LiveMask = LiveRegs[Reg]; 409 auto PrevMask = LiveMask; 410 LiveMask |= getDefRegMask(MO, *MRI); 411 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI); 412 } 413 414 MaxPressure = max(MaxPressure, CurPressure); 415 } 416 417 bool GCNDownwardRPTracker::advance() { 418 if (NextMI == MBBEnd) 419 return false; 420 advanceBeforeNext(); 421 advanceToNext(); 422 return true; 423 } 424 425 bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator End) { 426 while (NextMI != End) 427 if (!advance()) return false; 428 return true; 429 } 430 431 bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator Begin, 432 MachineBasicBlock::const_iterator End, 433 const LiveRegSet *LiveRegsCopy) { 434 reset(*Begin, LiveRegsCopy); 435 return advance(End); 436 } 437 438 Printable llvm::reportMismatch(const GCNRPTracker::LiveRegSet &LISLR, 439 const GCNRPTracker::LiveRegSet &TrackedLR, 440 const TargetRegisterInfo *TRI, StringRef Pfx) { 441 return Printable([&LISLR, &TrackedLR, TRI, Pfx](raw_ostream &OS) { 442 for (auto const &P : TrackedLR) { 443 auto I = LISLR.find(P.first); 444 if (I == LISLR.end()) { 445 OS << Pfx << printReg(P.first, TRI) << ":L" << PrintLaneMask(P.second) 446 << " isn't found in LIS reported set\n"; 447 } else if (I->second != P.second) { 448 OS << Pfx << printReg(P.first, TRI) 449 << " masks doesn't match: LIS reported " << PrintLaneMask(I->second) 450 << ", tracked " << PrintLaneMask(P.second) << '\n'; 451 } 452 } 453 for (auto const &P : LISLR) { 454 auto I = TrackedLR.find(P.first); 455 if (I == TrackedLR.end()) { 456 OS << Pfx << printReg(P.first, TRI) << ":L" << PrintLaneMask(P.second) 457 << " isn't found in tracked set\n"; 458 } 459 } 460 }); 461 } 462 463 bool GCNUpwardRPTracker::isValid() const { 464 const auto &SI = LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex(); 465 const auto LISLR = llvm::getLiveRegs(SI, LIS, *MRI); 466 const auto &TrackedLR = LiveRegs; 467 468 if (!isEqual(LISLR, TrackedLR)) { 469 dbgs() << "\nGCNUpwardRPTracker error: Tracked and" 470 " LIS reported livesets mismatch:\n" 471 << print(LISLR, *MRI); 472 reportMismatch(LISLR, TrackedLR, MRI->getTargetRegisterInfo()); 473 return false; 474 } 475 476 auto LISPressure = getRegPressure(*MRI, LISLR); 477 if (LISPressure != CurPressure) { 478 dbgs() << "GCNUpwardRPTracker error: Pressure sets different\nTracked: " 479 << print(CurPressure) << "LIS rpt: " << print(LISPressure); 480 return false; 481 } 482 return true; 483 } 484 485 Printable llvm::print(const GCNRPTracker::LiveRegSet &LiveRegs, 486 const MachineRegisterInfo &MRI) { 487 return Printable([&LiveRegs, &MRI](raw_ostream &OS) { 488 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo(); 489 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { 490 Register Reg = Register::index2VirtReg(I); 491 auto It = LiveRegs.find(Reg); 492 if (It != LiveRegs.end() && It->second.any()) 493 OS << ' ' << printVRegOrUnit(Reg, TRI) << ':' 494 << PrintLaneMask(It->second); 495 } 496 OS << '\n'; 497 }); 498 } 499 500 void GCNRegPressure::dump() const { dbgs() << print(*this); } 501 502 static cl::opt<bool> UseDownwardTracker( 503 "amdgpu-print-rp-downward", 504 cl::desc("Use GCNDownwardRPTracker for GCNRegPressurePrinter pass"), 505 cl::init(false), cl::Hidden); 506 507 char llvm::GCNRegPressurePrinter::ID = 0; 508 char &llvm::GCNRegPressurePrinterID = GCNRegPressurePrinter::ID; 509 510 INITIALIZE_PASS(GCNRegPressurePrinter, "amdgpu-print-rp", "", true, true) 511 512 // Return lanemask of Reg's subregs that are live-through at [Begin, End] and 513 // are fully covered by Mask. 514 static LaneBitmask 515 getRegLiveThroughMask(const MachineRegisterInfo &MRI, const LiveIntervals &LIS, 516 Register Reg, SlotIndex Begin, SlotIndex End, 517 LaneBitmask Mask = LaneBitmask::getAll()) { 518 519 auto IsInOneSegment = [Begin, End](const LiveRange &LR) -> bool { 520 auto *Segment = LR.getSegmentContaining(Begin); 521 return Segment && Segment->contains(End); 522 }; 523 524 LaneBitmask LiveThroughMask; 525 const LiveInterval &LI = LIS.getInterval(Reg); 526 if (LI.hasSubRanges()) { 527 for (auto &SR : LI.subranges()) { 528 if ((SR.LaneMask & Mask) == SR.LaneMask && IsInOneSegment(SR)) 529 LiveThroughMask |= SR.LaneMask; 530 } 531 } else { 532 LaneBitmask RegMask = MRI.getMaxLaneMaskForVReg(Reg); 533 if ((RegMask & Mask) == RegMask && IsInOneSegment(LI)) 534 LiveThroughMask = RegMask; 535 } 536 537 return LiveThroughMask; 538 } 539 540 bool GCNRegPressurePrinter::runOnMachineFunction(MachineFunction &MF) { 541 const MachineRegisterInfo &MRI = MF.getRegInfo(); 542 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo(); 543 const LiveIntervals &LIS = getAnalysis<LiveIntervals>(); 544 545 auto &OS = dbgs(); 546 547 // Leading spaces are important for YAML syntax. 548 #define PFX " " 549 550 OS << "---\nname: " << MF.getName() << "\nbody: |\n"; 551 552 auto printRP = [](const GCNRegPressure &RP) { 553 return Printable([&RP](raw_ostream &OS) { 554 OS << format(PFX " %-5d", RP.getSGPRNum()) 555 << format(" %-5d", RP.getVGPRNum(false)); 556 }); 557 }; 558 559 auto ReportLISMismatchIfAny = [&](const GCNRPTracker::LiveRegSet &TrackedLR, 560 const GCNRPTracker::LiveRegSet &LISLR) { 561 if (LISLR != TrackedLR) { 562 OS << PFX " mis LIS: " << llvm::print(LISLR, MRI) 563 << reportMismatch(LISLR, TrackedLR, TRI, PFX " "); 564 } 565 }; 566 567 // Register pressure before and at an instruction (in program order). 568 SmallVector<std::pair<GCNRegPressure, GCNRegPressure>, 16> RP; 569 570 for (auto &MBB : MF) { 571 RP.clear(); 572 RP.reserve(MBB.size()); 573 574 OS << PFX; 575 MBB.printName(OS); 576 OS << ":\n"; 577 578 SlotIndex MBBStartSlot = LIS.getSlotIndexes()->getMBBStartIdx(&MBB); 579 SlotIndex MBBEndSlot = LIS.getSlotIndexes()->getMBBEndIdx(&MBB); 580 581 GCNRPTracker::LiveRegSet LiveIn, LiveOut; 582 GCNRegPressure RPAtMBBEnd; 583 584 if (UseDownwardTracker) { 585 if (MBB.empty()) { 586 LiveIn = LiveOut = getLiveRegs(MBBStartSlot, LIS, MRI); 587 RPAtMBBEnd = getRegPressure(MRI, LiveIn); 588 } else { 589 GCNDownwardRPTracker RPT(LIS); 590 RPT.reset(MBB.front()); 591 592 LiveIn = RPT.getLiveRegs(); 593 594 while (!RPT.advanceBeforeNext()) { 595 GCNRegPressure RPBeforeMI = RPT.getPressure(); 596 RPT.advanceToNext(); 597 RP.emplace_back(RPBeforeMI, RPT.getPressure()); 598 } 599 600 LiveOut = RPT.getLiveRegs(); 601 RPAtMBBEnd = RPT.getPressure(); 602 } 603 } else { 604 GCNUpwardRPTracker RPT(LIS); 605 RPT.reset(MRI, MBBEndSlot); 606 607 LiveOut = RPT.getLiveRegs(); 608 RPAtMBBEnd = RPT.getPressure(); 609 610 for (auto &MI : reverse(MBB)) { 611 RPT.resetMaxPressure(); 612 RPT.recede(MI); 613 if (!MI.isDebugInstr()) 614 RP.emplace_back(RPT.getPressure(), RPT.getMaxPressure()); 615 } 616 617 LiveIn = RPT.getLiveRegs(); 618 } 619 620 OS << PFX " Live-in: " << llvm::print(LiveIn, MRI); 621 if (!UseDownwardTracker) 622 ReportLISMismatchIfAny(LiveIn, getLiveRegs(MBBStartSlot, LIS, MRI)); 623 624 OS << PFX " SGPR VGPR\n"; 625 int I = 0; 626 for (auto &MI : MBB) { 627 if (!MI.isDebugInstr()) { 628 auto &[RPBeforeInstr, RPAtInstr] = 629 RP[UseDownwardTracker ? I : (RP.size() - 1 - I)]; 630 ++I; 631 OS << printRP(RPBeforeInstr) << '\n' << printRP(RPAtInstr) << " "; 632 } else 633 OS << PFX " "; 634 MI.print(OS); 635 } 636 OS << printRP(RPAtMBBEnd) << '\n'; 637 638 OS << PFX " Live-out:" << llvm::print(LiveOut, MRI); 639 if (UseDownwardTracker) 640 ReportLISMismatchIfAny(LiveOut, getLiveRegs(MBBEndSlot, LIS, MRI)); 641 642 GCNRPTracker::LiveRegSet LiveThrough; 643 for (auto [Reg, Mask] : LiveIn) { 644 LaneBitmask MaskIntersection = Mask & LiveOut.lookup(Reg); 645 if (MaskIntersection.any()) { 646 LaneBitmask LTMask = getRegLiveThroughMask( 647 MRI, LIS, Reg, MBBStartSlot, MBBEndSlot, MaskIntersection); 648 if (LTMask.any()) 649 LiveThrough[Reg] = LTMask; 650 } 651 } 652 OS << PFX " Live-thr:" << llvm::print(LiveThrough, MRI); 653 OS << printRP(getRegPressure(MRI, LiveThrough)) << '\n'; 654 } 655 OS << "...\n"; 656 return false; 657 658 #undef PFX 659 }