1 //===--------------------- SIOptimizeVGPRLiveRange.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 pass tries to remove unnecessary VGPR live ranges in divergent if-else 11 /// structures and waterfall loops. 12 /// 13 /// When we do structurization, we usually transform an if-else into two 14 /// successive if-then (with a flow block to do predicate inversion). Consider a 15 /// simple case after structurization: A divergent value %a was defined before 16 /// if-else and used in both THEN (use in THEN is optional) and ELSE part: 17 /// bb.if: 18 /// %a = ... 19 /// ... 20 /// bb.then: 21 /// ... = op %a 22 /// ... // %a can be dead here 23 /// bb.flow: 24 /// ... 25 /// bb.else: 26 /// ... = %a 27 /// ... 28 /// bb.endif 29 /// 30 /// As register allocator has no idea of the thread-control-flow, it will just 31 /// assume %a would be alive in the whole range of bb.then because of a later 32 /// use in bb.else. On AMDGPU architecture, the VGPR is accessed with respect 33 /// to exec mask. For this if-else case, the lanes active in bb.then will be 34 /// inactive in bb.else, and vice-versa. So we are safe to say that %a was dead 35 /// after the last use in bb.then until the end of the block. The reason is 36 /// the instructions in bb.then will only overwrite lanes that will never be 37 /// accessed in bb.else. 38 /// 39 /// This pass aims to to tell register allocator that %a is in-fact dead, 40 /// through inserting a phi-node in bb.flow saying that %a is undef when coming 41 /// from bb.then, and then replace the uses in the bb.else with the result of 42 /// newly inserted phi. 43 /// 44 /// Two key conditions must be met to ensure correctness: 45 /// 1.) The def-point should be in the same loop-level as if-else-endif to make 46 /// sure the second loop iteration still get correct data. 47 /// 2.) There should be no further uses after the IF-ELSE region. 48 /// 49 /// 50 /// Waterfall loops get inserted around instructions that use divergent values 51 /// but can only be executed with a uniform value. For example an indirect call 52 /// to a divergent address: 53 /// bb.start: 54 /// %a = ... 55 /// %fun = ... 56 /// ... 57 /// bb.loop: 58 /// call %fun (%a) 59 /// ... // %a can be dead here 60 /// loop %bb.loop 61 /// 62 /// The loop block is executed multiple times, but it is run exactly once for 63 /// each active lane. Similar to the if-else case, the register allocator 64 /// assumes that %a is live throughout the loop as it is used again in the next 65 /// iteration. If %a is a VGPR that is unused after the loop, it does not need 66 /// to be live after its last use in the loop block. By inserting a phi-node at 67 /// the start of bb.loop that is undef when coming from bb.loop, the register 68 /// allocation knows that the value of %a does not need to be preserved through 69 /// iterations of the loop. 70 /// 71 // 72 //===----------------------------------------------------------------------===// 73 74 #include "AMDGPU.h" 75 #include "GCNSubtarget.h" 76 #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 77 #include "SIMachineFunctionInfo.h" 78 #include "llvm/CodeGen/LiveVariables.h" 79 #include "llvm/CodeGen/MachineDominators.h" 80 #include "llvm/CodeGen/MachineLoopInfo.h" 81 #include "llvm/CodeGen/TargetRegisterInfo.h" 82 #include "llvm/InitializePasses.h" 83 84 using namespace llvm; 85 86 #define DEBUG_TYPE "si-opt-vgpr-liverange" 87 88 namespace { 89 90 class SIOptimizeVGPRLiveRange : public MachineFunctionPass { 91 private: 92 const SIRegisterInfo *TRI = nullptr; 93 const SIInstrInfo *TII = nullptr; 94 LiveVariables *LV = nullptr; 95 MachineDominatorTree *MDT = nullptr; 96 const MachineLoopInfo *Loops = nullptr; 97 MachineRegisterInfo *MRI = nullptr; 98 99 public: 100 static char ID; 101 102 MachineBasicBlock *getElseTarget(MachineBasicBlock *MBB) const; 103 104 void collectElseRegionBlocks(MachineBasicBlock *Flow, 105 MachineBasicBlock *Endif, 106 SmallSetVector<MachineBasicBlock *, 16> &) const; 107 108 void 109 collectCandidateRegisters(MachineBasicBlock *If, MachineBasicBlock *Flow, 110 MachineBasicBlock *Endif, 111 SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks, 112 SmallVectorImpl<Register> &CandidateRegs) const; 113 114 void collectWaterfallCandidateRegisters( 115 MachineBasicBlock *Loop, 116 SmallSetVector<Register, 16> &CandidateRegs) const; 117 118 void findNonPHIUsesInBlock(Register Reg, MachineBasicBlock *MBB, 119 SmallVectorImpl<MachineInstr *> &Uses) const; 120 121 void updateLiveRangeInThenRegion(Register Reg, MachineBasicBlock *If, 122 MachineBasicBlock *Flow) const; 123 124 void updateLiveRangeInElseRegion( 125 Register Reg, Register NewReg, MachineBasicBlock *Flow, 126 MachineBasicBlock *Endif, 127 SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks) const; 128 129 void 130 optimizeLiveRange(Register Reg, MachineBasicBlock *If, 131 MachineBasicBlock *Flow, MachineBasicBlock *Endif, 132 SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks) const; 133 134 void optimizeWaterfallLiveRange(Register Reg, MachineBasicBlock *If) const; 135 136 SIOptimizeVGPRLiveRange() : MachineFunctionPass(ID) {} 137 138 bool runOnMachineFunction(MachineFunction &MF) override; 139 140 StringRef getPassName() const override { 141 return "SI Optimize VGPR LiveRange"; 142 } 143 144 void getAnalysisUsage(AnalysisUsage &AU) const override { 145 AU.addRequired<LiveVariables>(); 146 AU.addRequired<MachineDominatorTree>(); 147 AU.addRequired<MachineLoopInfo>(); 148 AU.addPreserved<LiveVariables>(); 149 AU.addPreserved<MachineDominatorTree>(); 150 AU.addPreserved<MachineLoopInfo>(); 151 MachineFunctionPass::getAnalysisUsage(AU); 152 } 153 154 MachineFunctionProperties getRequiredProperties() const override { 155 return MachineFunctionProperties().set( 156 MachineFunctionProperties::Property::IsSSA); 157 } 158 159 MachineFunctionProperties getClearedProperties() const override { 160 return MachineFunctionProperties().set( 161 MachineFunctionProperties::Property::NoPHIs); 162 } 163 }; 164 165 } // end anonymous namespace 166 167 // Check whether the MBB is a else flow block and get the branching target which 168 // is the Endif block 169 MachineBasicBlock * 170 SIOptimizeVGPRLiveRange::getElseTarget(MachineBasicBlock *MBB) const { 171 for (auto &BR : MBB->terminators()) { 172 if (BR.getOpcode() == AMDGPU::SI_ELSE) 173 return BR.getOperand(2).getMBB(); 174 } 175 return nullptr; 176 } 177 178 void SIOptimizeVGPRLiveRange::collectElseRegionBlocks( 179 MachineBasicBlock *Flow, MachineBasicBlock *Endif, 180 SmallSetVector<MachineBasicBlock *, 16> &Blocks) const { 181 assert(Flow != Endif); 182 183 MachineBasicBlock *MBB = Endif; 184 unsigned Cur = 0; 185 while (MBB) { 186 for (auto *Pred : MBB->predecessors()) { 187 if (Pred != Flow && !Blocks.contains(Pred)) 188 Blocks.insert(Pred); 189 } 190 191 if (Cur < Blocks.size()) 192 MBB = Blocks[Cur++]; 193 else 194 MBB = nullptr; 195 } 196 197 LLVM_DEBUG({ 198 dbgs() << "Found Else blocks: "; 199 for (auto *MBB : Blocks) 200 dbgs() << printMBBReference(*MBB) << ' '; 201 dbgs() << '\n'; 202 }); 203 } 204 205 /// Find the instructions(excluding phi) in \p MBB that uses the \p Reg. 206 void SIOptimizeVGPRLiveRange::findNonPHIUsesInBlock( 207 Register Reg, MachineBasicBlock *MBB, 208 SmallVectorImpl<MachineInstr *> &Uses) const { 209 for (auto &UseMI : MRI->use_nodbg_instructions(Reg)) { 210 if (UseMI.getParent() == MBB && !UseMI.isPHI()) 211 Uses.push_back(&UseMI); 212 } 213 } 214 215 /// Collect the killed registers in the ELSE region which are not alive through 216 /// the whole THEN region. 217 void SIOptimizeVGPRLiveRange::collectCandidateRegisters( 218 MachineBasicBlock *If, MachineBasicBlock *Flow, MachineBasicBlock *Endif, 219 SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks, 220 SmallVectorImpl<Register> &CandidateRegs) const { 221 222 SmallSet<Register, 8> KillsInElse; 223 224 for (auto *Else : ElseBlocks) { 225 for (auto &MI : Else->instrs()) { 226 if (MI.isDebugInstr()) 227 continue; 228 229 for (auto &MO : MI.operands()) { 230 if (!MO.isReg() || !MO.getReg() || MO.isDef()) 231 continue; 232 233 Register MOReg = MO.getReg(); 234 // We can only optimize AGPR/VGPR virtual register 235 if (MOReg.isPhysical() || !TRI->isVectorRegister(*MRI, MOReg)) 236 continue; 237 238 if (MO.readsReg()) { 239 LiveVariables::VarInfo &VI = LV->getVarInfo(MOReg); 240 const MachineBasicBlock *DefMBB = MRI->getVRegDef(MOReg)->getParent(); 241 // Make sure two conditions are met: 242 // a.) the value is defined before/in the IF block 243 // b.) should be defined in the same loop-level. 244 if ((VI.AliveBlocks.test(If->getNumber()) || DefMBB == If) && 245 Loops->getLoopFor(DefMBB) == Loops->getLoopFor(If)) { 246 // Check if the register is live into the endif block. If not, 247 // consider it killed in the else region. 248 LiveVariables::VarInfo &VI = LV->getVarInfo(MOReg); 249 if (!VI.isLiveIn(*Endif, MOReg, *MRI)) { 250 KillsInElse.insert(MOReg); 251 } else { 252 LLVM_DEBUG(dbgs() << "Excluding " << printReg(MOReg, TRI) 253 << " as Live in Endif\n"); 254 } 255 } 256 } 257 } 258 } 259 } 260 261 // Check the phis in the Endif, looking for value coming from the ELSE 262 // region. Make sure the phi-use is the last use. 263 for (auto &MI : Endif->phis()) { 264 for (unsigned Idx = 1; Idx < MI.getNumOperands(); Idx += 2) { 265 auto &MO = MI.getOperand(Idx); 266 auto *Pred = MI.getOperand(Idx + 1).getMBB(); 267 if (Pred == Flow) 268 continue; 269 assert(ElseBlocks.contains(Pred) && "Should be from Else region\n"); 270 271 if (!MO.isReg() || !MO.getReg() || MO.isUndef()) 272 continue; 273 274 Register Reg = MO.getReg(); 275 if (Reg.isPhysical() || !TRI->isVectorRegister(*MRI, Reg)) 276 continue; 277 278 LiveVariables::VarInfo &VI = LV->getVarInfo(Reg); 279 280 if (VI.isLiveIn(*Endif, Reg, *MRI)) { 281 LLVM_DEBUG(dbgs() << "Excluding " << printReg(Reg, TRI) 282 << " as Live in Endif\n"); 283 continue; 284 } 285 // Make sure two conditions are met: 286 // a.) the value is defined before/in the IF block 287 // b.) should be defined in the same loop-level. 288 const MachineBasicBlock *DefMBB = MRI->getVRegDef(Reg)->getParent(); 289 if ((VI.AliveBlocks.test(If->getNumber()) || DefMBB == If) && 290 Loops->getLoopFor(DefMBB) == Loops->getLoopFor(If)) 291 KillsInElse.insert(Reg); 292 } 293 } 294 295 auto IsLiveThroughThen = [&](Register Reg) { 296 for (auto I = MRI->use_nodbg_begin(Reg), E = MRI->use_nodbg_end(); I != E; 297 ++I) { 298 if (!I->readsReg()) 299 continue; 300 auto *UseMI = I->getParent(); 301 auto *UseMBB = UseMI->getParent(); 302 if (UseMBB == Flow || UseMBB == Endif) { 303 if (!UseMI->isPHI()) 304 return true; 305 306 auto *IncomingMBB = UseMI->getOperand(I.getOperandNo() + 1).getMBB(); 307 // The register is live through the path If->Flow or Flow->Endif. 308 // we should not optimize for such cases. 309 if ((UseMBB == Flow && IncomingMBB != If) || 310 (UseMBB == Endif && IncomingMBB == Flow)) 311 return true; 312 } 313 } 314 return false; 315 }; 316 317 for (auto Reg : KillsInElse) { 318 if (!IsLiveThroughThen(Reg)) 319 CandidateRegs.push_back(Reg); 320 } 321 } 322 323 /// Collect the registers used in the waterfall loop block that are defined 324 /// before. 325 void SIOptimizeVGPRLiveRange::collectWaterfallCandidateRegisters( 326 MachineBasicBlock *Loop, 327 SmallSetVector<Register, 16> &CandidateRegs) const { 328 329 for (auto &MI : Loop->instrs()) { 330 if (MI.isDebugInstr()) 331 continue; 332 333 for (auto &MO : MI.operands()) { 334 if (!MO.isReg() || !MO.getReg() || MO.isDef()) 335 continue; 336 337 Register MOReg = MO.getReg(); 338 // We can only optimize AGPR/VGPR virtual register 339 if (MOReg.isPhysical() || !TRI->isVectorRegister(*MRI, MOReg)) 340 continue; 341 342 if (MO.readsReg()) { 343 const MachineBasicBlock *DefMBB = MRI->getVRegDef(MOReg)->getParent(); 344 // Make sure the value is defined before the LOOP block 345 if (DefMBB != Loop && !CandidateRegs.contains(MOReg)) { 346 // If the variable is used after the loop, the register coalescer will 347 // merge the newly created register and remove the phi node again. 348 // Just do nothing in that case. 349 LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(MOReg); 350 bool IsUsed = false; 351 for (auto *Succ : Loop->successors()) { 352 if (Succ != Loop && OldVarInfo.isLiveIn(*Succ, MOReg, *MRI)) { 353 IsUsed = true; 354 break; 355 } 356 } 357 if (!IsUsed) { 358 LLVM_DEBUG(dbgs() << "Found candidate reg: " 359 << printReg(MOReg, TRI, 0, MRI) << '\n'); 360 CandidateRegs.insert(MOReg); 361 } else { 362 LLVM_DEBUG(dbgs() << "Reg is used after loop, ignoring: " 363 << printReg(MOReg, TRI, 0, MRI) << '\n'); 364 } 365 } 366 } 367 } 368 } 369 } 370 371 // Re-calculate the liveness of \p Reg in the THEN-region 372 void SIOptimizeVGPRLiveRange::updateLiveRangeInThenRegion( 373 Register Reg, MachineBasicBlock *If, MachineBasicBlock *Flow) const { 374 375 SmallPtrSet<MachineBasicBlock *, 16> PHIIncoming; 376 377 MachineBasicBlock *ThenEntry = nullptr; 378 for (auto *Succ : If->successors()) { 379 if (Succ != Flow) { 380 ThenEntry = Succ; 381 break; 382 } 383 } 384 assert(ThenEntry && "No successor in Then region?"); 385 386 LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg); 387 df_iterator_default_set<MachineBasicBlock *, 16> Visited; 388 389 for (MachineBasicBlock *MBB : depth_first_ext(ThenEntry, Visited)) { 390 if (MBB == Flow) 391 break; 392 393 // Clear Live bit, as we will recalculate afterwards 394 LLVM_DEBUG(dbgs() << "Clear AliveBlock " << printMBBReference(*MBB) 395 << '\n'); 396 OldVarInfo.AliveBlocks.reset(MBB->getNumber()); 397 } 398 399 // Get the blocks the Reg should be alive through 400 for (auto I = MRI->use_nodbg_begin(Reg), E = MRI->use_nodbg_end(); I != E; 401 ++I) { 402 auto *UseMI = I->getParent(); 403 if (UseMI->isPHI() && I->readsReg()) { 404 if (Visited.contains(UseMI->getParent())) 405 PHIIncoming.insert(UseMI->getOperand(I.getOperandNo() + 1).getMBB()); 406 } 407 } 408 409 Visited.clear(); 410 411 for (MachineBasicBlock *MBB : depth_first_ext(ThenEntry, Visited)) { 412 if (MBB == Flow) 413 break; 414 415 SmallVector<MachineInstr *> Uses; 416 // PHI instructions has been processed before. 417 findNonPHIUsesInBlock(Reg, MBB, Uses); 418 419 if (Uses.size() == 1) { 420 LLVM_DEBUG(dbgs() << "Found one Non-PHI use in " 421 << printMBBReference(*MBB) << '\n'); 422 LV->HandleVirtRegUse(Reg, MBB, *(*Uses.begin())); 423 } else if (Uses.size() > 1) { 424 // Process the instructions in-order 425 LLVM_DEBUG(dbgs() << "Found " << Uses.size() << " Non-PHI uses in " 426 << printMBBReference(*MBB) << '\n'); 427 for (MachineInstr &MI : *MBB) { 428 if (llvm::is_contained(Uses, &MI)) 429 LV->HandleVirtRegUse(Reg, MBB, MI); 430 } 431 } 432 433 // Mark Reg alive through the block if this is a PHI incoming block 434 if (PHIIncoming.contains(MBB)) 435 LV->MarkVirtRegAliveInBlock(OldVarInfo, MRI->getVRegDef(Reg)->getParent(), 436 MBB); 437 } 438 439 // Set the isKilled flag if we get new Kills in the THEN region. 440 for (auto *MI : OldVarInfo.Kills) { 441 if (Visited.contains(MI->getParent())) 442 MI->addRegisterKilled(Reg, TRI); 443 } 444 } 445 446 void SIOptimizeVGPRLiveRange::updateLiveRangeInElseRegion( 447 Register Reg, Register NewReg, MachineBasicBlock *Flow, 448 MachineBasicBlock *Endif, 449 SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks) const { 450 LiveVariables::VarInfo &NewVarInfo = LV->getVarInfo(NewReg); 451 LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg); 452 453 // Transfer aliveBlocks from Reg to NewReg 454 for (auto *MBB : ElseBlocks) { 455 unsigned BBNum = MBB->getNumber(); 456 if (OldVarInfo.AliveBlocks.test(BBNum)) { 457 NewVarInfo.AliveBlocks.set(BBNum); 458 LLVM_DEBUG(dbgs() << "Removing AliveBlock " << printMBBReference(*MBB) 459 << '\n'); 460 OldVarInfo.AliveBlocks.reset(BBNum); 461 } 462 } 463 464 // Transfer the possible Kills in ElseBlocks from Reg to NewReg 465 auto I = OldVarInfo.Kills.begin(); 466 while (I != OldVarInfo.Kills.end()) { 467 if (ElseBlocks.contains((*I)->getParent())) { 468 NewVarInfo.Kills.push_back(*I); 469 I = OldVarInfo.Kills.erase(I); 470 } else { 471 ++I; 472 } 473 } 474 } 475 476 void SIOptimizeVGPRLiveRange::optimizeLiveRange( 477 Register Reg, MachineBasicBlock *If, MachineBasicBlock *Flow, 478 MachineBasicBlock *Endif, 479 SmallSetVector<MachineBasicBlock *, 16> &ElseBlocks) const { 480 // Insert a new PHI, marking the value from the THEN region being 481 // undef. 482 LLVM_DEBUG(dbgs() << "Optimizing " << printReg(Reg, TRI) << '\n'); 483 const auto *RC = MRI->getRegClass(Reg); 484 Register NewReg = MRI->createVirtualRegister(RC); 485 Register UndefReg = MRI->createVirtualRegister(RC); 486 MachineInstrBuilder PHI = BuildMI(*Flow, Flow->getFirstNonPHI(), DebugLoc(), 487 TII->get(TargetOpcode::PHI), NewReg); 488 for (auto *Pred : Flow->predecessors()) { 489 if (Pred == If) 490 PHI.addReg(Reg).addMBB(Pred); 491 else 492 PHI.addReg(UndefReg, RegState::Undef).addMBB(Pred); 493 } 494 495 // Replace all uses in the ELSE region or the PHIs in ENDIF block 496 // Use early increment range because setReg() will update the linked list. 497 for (auto &O : make_early_inc_range(MRI->use_operands(Reg))) { 498 auto *UseMI = O.getParent(); 499 auto *UseBlock = UseMI->getParent(); 500 // Replace uses in Endif block 501 if (UseBlock == Endif) { 502 assert(UseMI->isPHI() && "Uses should be PHI in Endif block"); 503 O.setReg(NewReg); 504 continue; 505 } 506 507 // Replace uses in Else region 508 if (ElseBlocks.contains(UseBlock)) 509 O.setReg(NewReg); 510 } 511 512 // The optimized Reg is not alive through Flow blocks anymore. 513 LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg); 514 OldVarInfo.AliveBlocks.reset(Flow->getNumber()); 515 516 updateLiveRangeInElseRegion(Reg, NewReg, Flow, Endif, ElseBlocks); 517 updateLiveRangeInThenRegion(Reg, If, Flow); 518 } 519 520 void SIOptimizeVGPRLiveRange::optimizeWaterfallLiveRange( 521 Register Reg, MachineBasicBlock *Loop) const { 522 // Insert a new PHI, marking the value from the last loop iteration undef. 523 LLVM_DEBUG(dbgs() << "Optimizing " << printReg(Reg, TRI) << '\n'); 524 const auto *RC = MRI->getRegClass(Reg); 525 Register NewReg = MRI->createVirtualRegister(RC); 526 Register UndefReg = MRI->createVirtualRegister(RC); 527 528 // Replace all uses in the LOOP region 529 // Use early increment range because setReg() will update the linked list. 530 for (auto &O : make_early_inc_range(MRI->use_operands(Reg))) { 531 auto *UseMI = O.getParent(); 532 auto *UseBlock = UseMI->getParent(); 533 // Replace uses in Loop block 534 if (UseBlock == Loop) 535 O.setReg(NewReg); 536 } 537 538 MachineInstrBuilder PHI = BuildMI(*Loop, Loop->getFirstNonPHI(), DebugLoc(), 539 TII->get(TargetOpcode::PHI), NewReg); 540 for (auto *Pred : Loop->predecessors()) { 541 if (Pred == Loop) 542 PHI.addReg(UndefReg, RegState::Undef).addMBB(Pred); 543 else 544 PHI.addReg(Reg).addMBB(Pred); 545 } 546 547 LiveVariables::VarInfo &NewVarInfo = LV->getVarInfo(NewReg); 548 LiveVariables::VarInfo &OldVarInfo = LV->getVarInfo(Reg); 549 550 // collectWaterfallCandidateRegisters only collects registers that are dead 551 // after the loop. So we know that the old reg is not live throughout the 552 // whole block anymore. 553 OldVarInfo.AliveBlocks.reset(Loop->getNumber()); 554 555 // Mark the last use as kill 556 for (auto &MI : reverse(Loop->instrs())) { 557 if (MI.readsRegister(NewReg, TRI)) { 558 MI.addRegisterKilled(NewReg, TRI); 559 NewVarInfo.Kills.push_back(&MI); 560 break; 561 } 562 } 563 assert(!NewVarInfo.Kills.empty() && 564 "Failed to find last usage of register in loop"); 565 } 566 567 char SIOptimizeVGPRLiveRange::ID = 0; 568 569 INITIALIZE_PASS_BEGIN(SIOptimizeVGPRLiveRange, DEBUG_TYPE, 570 "SI Optimize VGPR LiveRange", false, false) 571 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) 572 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) 573 INITIALIZE_PASS_DEPENDENCY(LiveVariables) 574 INITIALIZE_PASS_END(SIOptimizeVGPRLiveRange, DEBUG_TYPE, 575 "SI Optimize VGPR LiveRange", false, false) 576 577 char &llvm::SIOptimizeVGPRLiveRangeID = SIOptimizeVGPRLiveRange::ID; 578 579 FunctionPass *llvm::createSIOptimizeVGPRLiveRangePass() { 580 return new SIOptimizeVGPRLiveRange(); 581 } 582 583 bool SIOptimizeVGPRLiveRange::runOnMachineFunction(MachineFunction &MF) { 584 585 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>(); 586 TII = ST.getInstrInfo(); 587 TRI = &TII->getRegisterInfo(); 588 MDT = &getAnalysis<MachineDominatorTree>(); 589 Loops = &getAnalysis<MachineLoopInfo>(); 590 LV = &getAnalysis<LiveVariables>(); 591 MRI = &MF.getRegInfo(); 592 593 if (skipFunction(MF.getFunction())) 594 return false; 595 596 bool MadeChange = false; 597 598 // TODO: we need to think about the order of visiting the blocks to get 599 // optimal result for nesting if-else cases. 600 for (MachineBasicBlock &MBB : MF) { 601 for (auto &MI : MBB.terminators()) { 602 // Detect the if-else blocks 603 if (MI.getOpcode() == AMDGPU::SI_IF) { 604 MachineBasicBlock *IfTarget = MI.getOperand(2).getMBB(); 605 auto *Endif = getElseTarget(IfTarget); 606 if (!Endif) 607 continue; 608 609 SmallSetVector<MachineBasicBlock *, 16> ElseBlocks; 610 SmallVector<Register> CandidateRegs; 611 612 LLVM_DEBUG(dbgs() << "Checking IF-ELSE-ENDIF: " 613 << printMBBReference(MBB) << ' ' 614 << printMBBReference(*IfTarget) << ' ' 615 << printMBBReference(*Endif) << '\n'); 616 617 // Collect all the blocks in the ELSE region 618 collectElseRegionBlocks(IfTarget, Endif, ElseBlocks); 619 620 // Collect the registers can be optimized 621 collectCandidateRegisters(&MBB, IfTarget, Endif, ElseBlocks, 622 CandidateRegs); 623 MadeChange |= !CandidateRegs.empty(); 624 // Now we are safe to optimize. 625 for (auto Reg : CandidateRegs) 626 optimizeLiveRange(Reg, &MBB, IfTarget, Endif, ElseBlocks); 627 } else if (MI.getOpcode() == AMDGPU::SI_WATERFALL_LOOP) { 628 LLVM_DEBUG(dbgs() << "Checking Waterfall loop: " 629 << printMBBReference(MBB) << '\n'); 630 631 SmallSetVector<Register, 16> CandidateRegs; 632 collectWaterfallCandidateRegisters(&MBB, CandidateRegs); 633 MadeChange |= !CandidateRegs.empty(); 634 // Now we are safe to optimize. 635 for (auto Reg : CandidateRegs) 636 optimizeWaterfallLiveRange(Reg, &MBB); 637 } 638 } 639 } 640 641 return MadeChange; 642 } 643