1 //===-- SIWholeQuadMode.cpp - enter and suspend whole quad mode -----------===// 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 adds instructions to enable whole quad mode for pixel 11 /// shaders, and whole wavefront mode for all programs. 12 /// 13 /// Whole quad mode is required for derivative computations, but it interferes 14 /// with shader side effects (stores and atomics). It ensures that WQM is 15 /// enabled when necessary, but disabled around stores and atomics. 16 /// 17 /// When necessary, this pass creates a function prolog 18 /// 19 /// S_MOV_B64 LiveMask, EXEC 20 /// S_WQM_B64 EXEC, EXEC 21 /// 22 /// to enter WQM at the top of the function and surrounds blocks of Exact 23 /// instructions by 24 /// 25 /// S_AND_SAVEEXEC_B64 Tmp, LiveMask 26 /// ... 27 /// S_MOV_B64 EXEC, Tmp 28 /// 29 /// We also compute when a sequence of instructions requires Whole Wavefront 30 /// Mode (WWM) and insert instructions to save and restore it: 31 /// 32 /// S_OR_SAVEEXEC_B64 Tmp, -1 33 /// ... 34 /// S_MOV_B64 EXEC, Tmp 35 /// 36 /// In order to avoid excessive switching during sequences of Exact 37 /// instructions, the pass first analyzes which instructions must be run in WQM 38 /// (aka which instructions produce values that lead to derivative 39 /// computations). 40 /// 41 /// Basic blocks are always exited in WQM as long as some successor needs WQM. 42 /// 43 /// There is room for improvement given better control flow analysis: 44 /// 45 /// (1) at the top level (outside of control flow statements, and as long as 46 /// kill hasn't been used), one SGPR can be saved by recovering WQM from 47 /// the LiveMask (this is implemented for the entry block). 48 /// 49 /// (2) when entire regions (e.g. if-else blocks or entire loops) only 50 /// consist of exact and don't-care instructions, the switch only has to 51 /// be done at the entry and exit points rather than potentially in each 52 /// block of the region. 53 /// 54 //===----------------------------------------------------------------------===// 55 56 #include "AMDGPU.h" 57 #include "GCNSubtarget.h" 58 #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 59 #include "llvm/ADT/MapVector.h" 60 #include "llvm/ADT/PostOrderIterator.h" 61 #include "llvm/CodeGen/LiveIntervals.h" 62 #include "llvm/CodeGen/MachineBasicBlock.h" 63 #include "llvm/CodeGen/MachineDominators.h" 64 #include "llvm/CodeGen/MachineFunctionPass.h" 65 #include "llvm/CodeGen/MachineInstr.h" 66 #include "llvm/CodeGen/MachinePostDominators.h" 67 #include "llvm/IR/CallingConv.h" 68 #include "llvm/InitializePasses.h" 69 #include "llvm/Support/raw_ostream.h" 70 71 using namespace llvm; 72 73 #define DEBUG_TYPE "si-wqm" 74 75 namespace { 76 77 enum { 78 StateWQM = 0x1, 79 StateWWM = 0x2, 80 StateExact = 0x4, 81 }; 82 83 struct PrintState { 84 public: 85 int State; 86 87 explicit PrintState(int State) : State(State) {} 88 }; 89 90 #ifndef NDEBUG 91 static raw_ostream &operator<<(raw_ostream &OS, const PrintState &PS) { 92 if (PS.State & StateWQM) 93 OS << "WQM"; 94 if (PS.State & StateWWM) { 95 if (PS.State & StateWQM) 96 OS << '|'; 97 OS << "WWM"; 98 } 99 if (PS.State & StateExact) { 100 if (PS.State & (StateWQM | StateWWM)) 101 OS << '|'; 102 OS << "Exact"; 103 } 104 105 return OS; 106 } 107 #endif 108 109 struct InstrInfo { 110 char Needs = 0; 111 char Disabled = 0; 112 char OutNeeds = 0; 113 }; 114 115 struct BlockInfo { 116 char Needs = 0; 117 char InNeeds = 0; 118 char OutNeeds = 0; 119 char InitialState = 0; 120 bool NeedsLowering = false; 121 }; 122 123 struct WorkItem { 124 MachineBasicBlock *MBB = nullptr; 125 MachineInstr *MI = nullptr; 126 127 WorkItem() = default; 128 WorkItem(MachineBasicBlock *MBB) : MBB(MBB) {} 129 WorkItem(MachineInstr *MI) : MI(MI) {} 130 }; 131 132 class SIWholeQuadMode : public MachineFunctionPass { 133 private: 134 const SIInstrInfo *TII; 135 const SIRegisterInfo *TRI; 136 const GCNSubtarget *ST; 137 MachineRegisterInfo *MRI; 138 LiveIntervals *LIS; 139 MachineDominatorTree *MDT; 140 MachinePostDominatorTree *PDT; 141 142 unsigned AndOpc; 143 unsigned AndN2Opc; 144 unsigned XorOpc; 145 unsigned AndSaveExecOpc; 146 unsigned OrSaveExecOpc; 147 unsigned WQMOpc; 148 Register Exec; 149 Register LiveMaskReg; 150 151 DenseMap<const MachineInstr *, InstrInfo> Instructions; 152 MapVector<MachineBasicBlock *, BlockInfo> Blocks; 153 154 // Tracks state (WQM/WWM/Exact) after a given instruction 155 DenseMap<const MachineInstr *, char> StateTransition; 156 157 SmallVector<MachineInstr *, 2> LiveMaskQueries; 158 SmallVector<MachineInstr *, 4> LowerToMovInstrs; 159 SmallVector<MachineInstr *, 4> LowerToCopyInstrs; 160 SmallVector<MachineInstr *, 4> KillInstrs; 161 162 void printInfo(); 163 164 void markInstruction(MachineInstr &MI, char Flag, 165 std::vector<WorkItem> &Worklist); 166 void markDefs(const MachineInstr &UseMI, LiveRange &LR, Register Reg, 167 unsigned SubReg, char Flag, std::vector<WorkItem> &Worklist); 168 void markInstructionUses(const MachineInstr &MI, char Flag, 169 std::vector<WorkItem> &Worklist); 170 char scanInstructions(MachineFunction &MF, std::vector<WorkItem> &Worklist); 171 void propagateInstruction(MachineInstr &MI, std::vector<WorkItem> &Worklist); 172 void propagateBlock(MachineBasicBlock &MBB, std::vector<WorkItem> &Worklist); 173 char analyzeFunction(MachineFunction &MF); 174 175 MachineBasicBlock::iterator saveSCC(MachineBasicBlock &MBB, 176 MachineBasicBlock::iterator Before); 177 MachineBasicBlock::iterator 178 prepareInsertion(MachineBasicBlock &MBB, MachineBasicBlock::iterator First, 179 MachineBasicBlock::iterator Last, bool PreferLast, 180 bool SaveSCC); 181 void toExact(MachineBasicBlock &MBB, MachineBasicBlock::iterator Before, 182 Register SaveWQM); 183 void toWQM(MachineBasicBlock &MBB, MachineBasicBlock::iterator Before, 184 Register SavedWQM); 185 void toWWM(MachineBasicBlock &MBB, MachineBasicBlock::iterator Before, 186 Register SaveOrig); 187 void fromWWM(MachineBasicBlock &MBB, MachineBasicBlock::iterator Before, 188 Register SavedOrig, char NonWWMState); 189 190 MachineBasicBlock *splitBlock(MachineBasicBlock *BB, MachineInstr *TermMI); 191 192 MachineInstr *lowerKillI1(MachineBasicBlock &MBB, MachineInstr &MI, 193 bool IsWQM); 194 MachineInstr *lowerKillF32(MachineBasicBlock &MBB, MachineInstr &MI); 195 196 void lowerBlock(MachineBasicBlock &MBB); 197 void processBlock(MachineBasicBlock &MBB, bool IsEntry); 198 199 void lowerLiveMaskQueries(); 200 void lowerCopyInstrs(); 201 void lowerKillInstrs(bool IsWQM); 202 203 public: 204 static char ID; 205 206 SIWholeQuadMode() : 207 MachineFunctionPass(ID) { } 208 209 bool runOnMachineFunction(MachineFunction &MF) override; 210 211 StringRef getPassName() const override { return "SI Whole Quad Mode"; } 212 213 void getAnalysisUsage(AnalysisUsage &AU) const override { 214 AU.addRequired<LiveIntervals>(); 215 AU.addPreserved<SlotIndexes>(); 216 AU.addPreserved<LiveIntervals>(); 217 AU.addRequired<MachineDominatorTree>(); 218 AU.addPreserved<MachineDominatorTree>(); 219 AU.addRequired<MachinePostDominatorTree>(); 220 AU.addPreserved<MachinePostDominatorTree>(); 221 MachineFunctionPass::getAnalysisUsage(AU); 222 } 223 224 MachineFunctionProperties getClearedProperties() const override { 225 return MachineFunctionProperties().set( 226 MachineFunctionProperties::Property::IsSSA); 227 } 228 }; 229 230 } // end anonymous namespace 231 232 char SIWholeQuadMode::ID = 0; 233 234 INITIALIZE_PASS_BEGIN(SIWholeQuadMode, DEBUG_TYPE, "SI Whole Quad Mode", false, 235 false) 236 INITIALIZE_PASS_DEPENDENCY(LiveIntervals) 237 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) 238 INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree) 239 INITIALIZE_PASS_END(SIWholeQuadMode, DEBUG_TYPE, "SI Whole Quad Mode", false, 240 false) 241 242 char &llvm::SIWholeQuadModeID = SIWholeQuadMode::ID; 243 244 FunctionPass *llvm::createSIWholeQuadModePass() { 245 return new SIWholeQuadMode; 246 } 247 248 #ifndef NDEBUG 249 LLVM_DUMP_METHOD void SIWholeQuadMode::printInfo() { 250 for (const auto &BII : Blocks) { 251 dbgs() << "\n" 252 << printMBBReference(*BII.first) << ":\n" 253 << " InNeeds = " << PrintState(BII.second.InNeeds) 254 << ", Needs = " << PrintState(BII.second.Needs) 255 << ", OutNeeds = " << PrintState(BII.second.OutNeeds) << "\n\n"; 256 257 for (const MachineInstr &MI : *BII.first) { 258 auto III = Instructions.find(&MI); 259 if (III == Instructions.end()) 260 continue; 261 262 dbgs() << " " << MI << " Needs = " << PrintState(III->second.Needs) 263 << ", OutNeeds = " << PrintState(III->second.OutNeeds) << '\n'; 264 } 265 } 266 } 267 #endif 268 269 void SIWholeQuadMode::markInstruction(MachineInstr &MI, char Flag, 270 std::vector<WorkItem> &Worklist) { 271 InstrInfo &II = Instructions[&MI]; 272 273 assert(!(Flag & StateExact) && Flag != 0); 274 275 LLVM_DEBUG(dbgs() << "markInstruction " << PrintState(Flag) << ": " << MI); 276 277 // Remove any disabled states from the flag. The user that required it gets 278 // an undefined value in the helper lanes. For example, this can happen if 279 // the result of an atomic is used by instruction that requires WQM, where 280 // ignoring the request for WQM is correct as per the relevant specs. 281 Flag &= ~II.Disabled; 282 283 // Ignore if the flag is already encompassed by the existing needs, or we 284 // just disabled everything. 285 if ((II.Needs & Flag) == Flag) 286 return; 287 288 II.Needs |= Flag; 289 Worklist.push_back(&MI); 290 } 291 292 /// Mark all relevant definitions of register \p Reg in usage \p UseMI. 293 void SIWholeQuadMode::markDefs(const MachineInstr &UseMI, LiveRange &LR, 294 Register Reg, unsigned SubReg, char Flag, 295 std::vector<WorkItem> &Worklist) { 296 LLVM_DEBUG(dbgs() << "markDefs " << PrintState(Flag) << ": " << UseMI); 297 298 LiveQueryResult UseLRQ = LR.Query(LIS->getInstructionIndex(UseMI)); 299 if (!UseLRQ.valueIn()) 300 return; 301 302 SmallPtrSet<const VNInfo *, 4> Visited; 303 SmallVector<const VNInfo *, 4> ToProcess; 304 ToProcess.push_back(UseLRQ.valueIn()); 305 do { 306 const VNInfo *Value = ToProcess.pop_back_val(); 307 Visited.insert(Value); 308 309 if (Value->isPHIDef()) { 310 // Need to mark all defs used in the PHI node 311 const MachineBasicBlock *MBB = LIS->getMBBFromIndex(Value->def); 312 assert(MBB && "Phi-def has no defining MBB"); 313 for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), 314 PE = MBB->pred_end(); 315 PI != PE; ++PI) { 316 if (const VNInfo *VN = LR.getVNInfoBefore(LIS->getMBBEndIdx(*PI))) { 317 if (!Visited.count(VN)) 318 ToProcess.push_back(VN); 319 } 320 } 321 } else { 322 MachineInstr *MI = LIS->getInstructionFromIndex(Value->def); 323 assert(MI && "Def has no defining instruction"); 324 markInstruction(*MI, Flag, Worklist); 325 326 // Iterate over all operands to find relevant definitions 327 for (const MachineOperand &Op : MI->operands()) { 328 if (!(Op.isReg() && Op.getReg() == Reg)) 329 continue; 330 331 // Does this def cover whole register? 332 bool DefinesFullReg = 333 Op.isUndef() || !Op.getSubReg() || Op.getSubReg() == SubReg; 334 if (!DefinesFullReg) { 335 // Partial definition; need to follow and mark input value 336 LiveQueryResult LRQ = LR.Query(LIS->getInstructionIndex(*MI)); 337 if (const VNInfo *VN = LRQ.valueIn()) { 338 if (!Visited.count(VN)) 339 ToProcess.push_back(VN); 340 } 341 } 342 } 343 } 344 } while (!ToProcess.empty()); 345 } 346 347 /// Mark all instructions defining the uses in \p MI with \p Flag. 348 void SIWholeQuadMode::markInstructionUses(const MachineInstr &MI, char Flag, 349 std::vector<WorkItem> &Worklist) { 350 351 LLVM_DEBUG(dbgs() << "markInstructionUses " << PrintState(Flag) << ": " 352 << MI); 353 354 for (const MachineOperand &Use : MI.uses()) { 355 if (!Use.isReg() || !Use.isUse()) 356 continue; 357 358 Register Reg = Use.getReg(); 359 360 // Handle physical registers that we need to track; this is mostly relevant 361 // for VCC, which can appear as the (implicit) input of a uniform branch, 362 // e.g. when a loop counter is stored in a VGPR. 363 if (!Reg.isVirtual()) { 364 if (Reg == AMDGPU::EXEC || Reg == AMDGPU::EXEC_LO) 365 continue; 366 367 for (MCRegUnitIterator RegUnit(Reg.asMCReg(), TRI); RegUnit.isValid(); 368 ++RegUnit) { 369 LiveRange &LR = LIS->getRegUnit(*RegUnit); 370 const VNInfo *Value = LR.Query(LIS->getInstructionIndex(MI)).valueIn(); 371 if (!Value) 372 continue; 373 374 markDefs(MI, LR, *RegUnit, AMDGPU::NoSubRegister, Flag, Worklist); 375 } 376 377 continue; 378 } 379 380 LiveRange &LR = LIS->getInterval(Reg); 381 markDefs(MI, LR, Reg, Use.getSubReg(), Flag, Worklist); 382 } 383 } 384 385 // Scan instructions to determine which ones require an Exact execmask and 386 // which ones seed WQM requirements. 387 char SIWholeQuadMode::scanInstructions(MachineFunction &MF, 388 std::vector<WorkItem> &Worklist) { 389 char GlobalFlags = 0; 390 bool WQMOutputs = MF.getFunction().hasFnAttribute("amdgpu-ps-wqm-outputs"); 391 SmallVector<MachineInstr *, 4> SetInactiveInstrs; 392 SmallVector<MachineInstr *, 4> SoftWQMInstrs; 393 394 // We need to visit the basic blocks in reverse post-order so that we visit 395 // defs before uses, in particular so that we don't accidentally mark an 396 // instruction as needing e.g. WQM before visiting it and realizing it needs 397 // WQM disabled. 398 ReversePostOrderTraversal<MachineFunction *> RPOT(&MF); 399 for (auto BI = RPOT.begin(), BE = RPOT.end(); BI != BE; ++BI) { 400 MachineBasicBlock &MBB = **BI; 401 BlockInfo &BBI = Blocks[&MBB]; 402 403 for (auto II = MBB.begin(), IE = MBB.end(); II != IE; ++II) { 404 MachineInstr &MI = *II; 405 InstrInfo &III = Instructions[&MI]; 406 unsigned Opcode = MI.getOpcode(); 407 char Flags = 0; 408 409 if (TII->isWQM(Opcode)) { 410 // If LOD is not supported WQM is not needed. 411 if (!ST->hasExtendedImageInsts()) 412 continue; 413 // Sampling instructions don't need to produce results for all pixels 414 // in a quad, they just require all inputs of a quad to have been 415 // computed for derivatives. 416 markInstructionUses(MI, StateWQM, Worklist); 417 GlobalFlags |= StateWQM; 418 continue; 419 } else if (Opcode == AMDGPU::WQM) { 420 // The WQM intrinsic requires its output to have all the helper lanes 421 // correct, so we need it to be in WQM. 422 Flags = StateWQM; 423 LowerToCopyInstrs.push_back(&MI); 424 } else if (Opcode == AMDGPU::SOFT_WQM) { 425 LowerToCopyInstrs.push_back(&MI); 426 SoftWQMInstrs.push_back(&MI); 427 continue; 428 } else if (Opcode == AMDGPU::WWM) { 429 // The WWM intrinsic doesn't make the same guarantee, and plus it needs 430 // to be executed in WQM or Exact so that its copy doesn't clobber 431 // inactive lanes. 432 markInstructionUses(MI, StateWWM, Worklist); 433 GlobalFlags |= StateWWM; 434 LowerToMovInstrs.push_back(&MI); 435 continue; 436 } else if (Opcode == AMDGPU::V_SET_INACTIVE_B32 || 437 Opcode == AMDGPU::V_SET_INACTIVE_B64) { 438 III.Disabled = StateWWM; 439 MachineOperand &Inactive = MI.getOperand(2); 440 if (Inactive.isReg()) { 441 if (Inactive.isUndef()) { 442 LowerToCopyInstrs.push_back(&MI); 443 } else { 444 Register Reg = Inactive.getReg(); 445 if (Reg.isVirtual()) { 446 for (MachineInstr &DefMI : MRI->def_instructions(Reg)) 447 markInstruction(DefMI, StateWWM, Worklist); 448 } 449 } 450 } 451 SetInactiveInstrs.push_back(&MI); 452 continue; 453 } else if (TII->isDisableWQM(MI)) { 454 BBI.Needs |= StateExact; 455 if (!(BBI.InNeeds & StateExact)) { 456 BBI.InNeeds |= StateExact; 457 Worklist.push_back(&MBB); 458 } 459 GlobalFlags |= StateExact; 460 III.Disabled = StateWQM | StateWWM; 461 continue; 462 } else { 463 if (Opcode == AMDGPU::SI_PS_LIVE || Opcode == AMDGPU::SI_LIVE_MASK) { 464 LiveMaskQueries.push_back(&MI); 465 } else if (Opcode == AMDGPU::SI_KILL_I1_TERMINATOR || 466 Opcode == AMDGPU::SI_KILL_F32_COND_IMM_TERMINATOR || 467 Opcode == AMDGPU::SI_DEMOTE_I1) { 468 KillInstrs.push_back(&MI); 469 BBI.NeedsLowering = true; 470 } else if (WQMOutputs) { 471 // The function is in machine SSA form, which means that physical 472 // VGPRs correspond to shader inputs and outputs. Inputs are 473 // only used, outputs are only defined. 474 // FIXME: is this still valid? 475 for (const MachineOperand &MO : MI.defs()) { 476 if (!MO.isReg()) 477 continue; 478 479 Register Reg = MO.getReg(); 480 481 if (!Reg.isVirtual() && 482 TRI->hasVectorRegisters(TRI->getPhysRegClass(Reg))) { 483 Flags = StateWQM; 484 break; 485 } 486 } 487 } 488 489 if (!Flags) 490 continue; 491 } 492 493 markInstruction(MI, Flags, Worklist); 494 GlobalFlags |= Flags; 495 } 496 } 497 498 // Mark sure that any SET_INACTIVE instructions are computed in WQM if WQM is 499 // ever used anywhere in the function. This implements the corresponding 500 // semantics of @llvm.amdgcn.set.inactive. 501 // Similarly for SOFT_WQM instructions, implementing @llvm.amdgcn.softwqm. 502 if (GlobalFlags & StateWQM) { 503 for (MachineInstr *MI : SetInactiveInstrs) 504 markInstruction(*MI, StateWQM, Worklist); 505 for (MachineInstr *MI : SoftWQMInstrs) 506 markInstruction(*MI, StateWQM, Worklist); 507 } 508 509 return GlobalFlags; 510 } 511 512 void SIWholeQuadMode::propagateInstruction(MachineInstr &MI, 513 std::vector<WorkItem>& Worklist) { 514 MachineBasicBlock *MBB = MI.getParent(); 515 InstrInfo II = Instructions[&MI]; // take a copy to prevent dangling references 516 BlockInfo &BI = Blocks[MBB]; 517 518 // Control flow-type instructions and stores to temporary memory that are 519 // followed by WQM computations must themselves be in WQM. 520 if ((II.OutNeeds & StateWQM) && !(II.Disabled & StateWQM) && 521 (MI.isTerminator() || (TII->usesVM_CNT(MI) && MI.mayStore()))) { 522 Instructions[&MI].Needs = StateWQM; 523 II.Needs = StateWQM; 524 } 525 526 // Propagate to block level 527 if (II.Needs & StateWQM) { 528 BI.Needs |= StateWQM; 529 if (!(BI.InNeeds & StateWQM)) { 530 BI.InNeeds |= StateWQM; 531 Worklist.push_back(MBB); 532 } 533 } 534 535 // Propagate backwards within block 536 if (MachineInstr *PrevMI = MI.getPrevNode()) { 537 char InNeeds = (II.Needs & ~StateWWM) | II.OutNeeds; 538 if (!PrevMI->isPHI()) { 539 InstrInfo &PrevII = Instructions[PrevMI]; 540 if ((PrevII.OutNeeds | InNeeds) != PrevII.OutNeeds) { 541 PrevII.OutNeeds |= InNeeds; 542 Worklist.push_back(PrevMI); 543 } 544 } 545 } 546 547 // Propagate WQM flag to instruction inputs 548 assert(!(II.Needs & StateExact)); 549 550 if (II.Needs != 0) 551 markInstructionUses(MI, II.Needs, Worklist); 552 553 // Ensure we process a block containing WWM, even if it does not require any 554 // WQM transitions. 555 if (II.Needs & StateWWM) 556 BI.Needs |= StateWWM; 557 } 558 559 void SIWholeQuadMode::propagateBlock(MachineBasicBlock &MBB, 560 std::vector<WorkItem>& Worklist) { 561 BlockInfo BI = Blocks[&MBB]; // Make a copy to prevent dangling references. 562 563 // Propagate through instructions 564 if (!MBB.empty()) { 565 MachineInstr *LastMI = &*MBB.rbegin(); 566 InstrInfo &LastII = Instructions[LastMI]; 567 if ((LastII.OutNeeds | BI.OutNeeds) != LastII.OutNeeds) { 568 LastII.OutNeeds |= BI.OutNeeds; 569 Worklist.push_back(LastMI); 570 } 571 } 572 573 // Predecessor blocks must provide for our WQM/Exact needs. 574 for (MachineBasicBlock *Pred : MBB.predecessors()) { 575 BlockInfo &PredBI = Blocks[Pred]; 576 if ((PredBI.OutNeeds | BI.InNeeds) == PredBI.OutNeeds) 577 continue; 578 579 PredBI.OutNeeds |= BI.InNeeds; 580 PredBI.InNeeds |= BI.InNeeds; 581 Worklist.push_back(Pred); 582 } 583 584 // All successors must be prepared to accept the same set of WQM/Exact data. 585 for (MachineBasicBlock *Succ : MBB.successors()) { 586 BlockInfo &SuccBI = Blocks[Succ]; 587 if ((SuccBI.InNeeds | BI.OutNeeds) == SuccBI.InNeeds) 588 continue; 589 590 SuccBI.InNeeds |= BI.OutNeeds; 591 Worklist.push_back(Succ); 592 } 593 } 594 595 char SIWholeQuadMode::analyzeFunction(MachineFunction &MF) { 596 std::vector<WorkItem> Worklist; 597 char GlobalFlags = scanInstructions(MF, Worklist); 598 599 while (!Worklist.empty()) { 600 WorkItem WI = Worklist.back(); 601 Worklist.pop_back(); 602 603 if (WI.MI) 604 propagateInstruction(*WI.MI, Worklist); 605 else 606 propagateBlock(*WI.MBB, Worklist); 607 } 608 609 return GlobalFlags; 610 } 611 612 MachineBasicBlock::iterator 613 SIWholeQuadMode::saveSCC(MachineBasicBlock &MBB, 614 MachineBasicBlock::iterator Before) { 615 Register SaveReg = MRI->createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass); 616 617 MachineInstr *Save = 618 BuildMI(MBB, Before, DebugLoc(), TII->get(AMDGPU::COPY), SaveReg) 619 .addReg(AMDGPU::SCC); 620 MachineInstr *Restore = 621 BuildMI(MBB, Before, DebugLoc(), TII->get(AMDGPU::COPY), AMDGPU::SCC) 622 .addReg(SaveReg); 623 624 LIS->InsertMachineInstrInMaps(*Save); 625 LIS->InsertMachineInstrInMaps(*Restore); 626 LIS->createAndComputeVirtRegInterval(SaveReg); 627 628 return Restore; 629 } 630 631 MachineBasicBlock *SIWholeQuadMode::splitBlock(MachineBasicBlock *BB, 632 MachineInstr *TermMI) { 633 LLVM_DEBUG(dbgs() << "Split block " << printMBBReference(*BB) << " @ " 634 << *TermMI << "\n"); 635 636 MachineBasicBlock *SplitBB = 637 BB->splitAt(*TermMI, /*UpdateLiveIns*/ true, LIS); 638 639 // Convert last instruction in block to a terminator. 640 // Note: this only covers the expected patterns 641 unsigned NewOpcode = 0; 642 switch (TermMI->getOpcode()) { 643 case AMDGPU::S_AND_B32: 644 NewOpcode = AMDGPU::S_AND_B32_term; 645 break; 646 case AMDGPU::S_AND_B64: 647 NewOpcode = AMDGPU::S_AND_B64_term; 648 break; 649 case AMDGPU::S_MOV_B32: 650 NewOpcode = AMDGPU::S_MOV_B32_term; 651 break; 652 case AMDGPU::S_MOV_B64: 653 NewOpcode = AMDGPU::S_MOV_B64_term; 654 break; 655 default: 656 break; 657 } 658 if (NewOpcode) 659 TermMI->setDesc(TII->get(NewOpcode)); 660 661 if (SplitBB != BB) { 662 // Update dominator trees 663 using DomTreeT = DomTreeBase<MachineBasicBlock>; 664 SmallVector<DomTreeT::UpdateType, 16> DTUpdates; 665 for (MachineBasicBlock *Succ : SplitBB->successors()) { 666 DTUpdates.push_back({DomTreeT::Insert, SplitBB, Succ}); 667 DTUpdates.push_back({DomTreeT::Delete, BB, Succ}); 668 } 669 DTUpdates.push_back({DomTreeT::Insert, BB, SplitBB}); 670 if (MDT) 671 MDT->getBase().applyUpdates(DTUpdates); 672 if (PDT) 673 PDT->getBase().applyUpdates(DTUpdates); 674 675 // Link blocks 676 MachineInstr *MI = 677 BuildMI(*BB, BB->end(), DebugLoc(), TII->get(AMDGPU::S_BRANCH)) 678 .addMBB(SplitBB); 679 LIS->InsertMachineInstrInMaps(*MI); 680 } 681 682 return SplitBB; 683 } 684 685 MachineInstr *SIWholeQuadMode::lowerKillF32(MachineBasicBlock &MBB, 686 MachineInstr &MI) { 687 const DebugLoc &DL = MI.getDebugLoc(); 688 unsigned Opcode = 0; 689 690 assert(MI.getOperand(0).isReg()); 691 692 // Comparison is for live lanes; however here we compute the inverse 693 // (killed lanes). This is because VCMP will always generate 0 bits 694 // for inactive lanes so a mask of live lanes would not be correct 695 // inside control flow. 696 // Invert the comparison by swapping the operands and adjusting 697 // the comparison codes. 698 699 switch (MI.getOperand(2).getImm()) { 700 case ISD::SETUEQ: 701 Opcode = AMDGPU::V_CMP_LG_F32_e64; 702 break; 703 case ISD::SETUGT: 704 Opcode = AMDGPU::V_CMP_GE_F32_e64; 705 break; 706 case ISD::SETUGE: 707 Opcode = AMDGPU::V_CMP_GT_F32_e64; 708 break; 709 case ISD::SETULT: 710 Opcode = AMDGPU::V_CMP_LE_F32_e64; 711 break; 712 case ISD::SETULE: 713 Opcode = AMDGPU::V_CMP_LT_F32_e64; 714 break; 715 case ISD::SETUNE: 716 Opcode = AMDGPU::V_CMP_EQ_F32_e64; 717 break; 718 case ISD::SETO: 719 Opcode = AMDGPU::V_CMP_O_F32_e64; 720 break; 721 case ISD::SETUO: 722 Opcode = AMDGPU::V_CMP_U_F32_e64; 723 break; 724 case ISD::SETOEQ: 725 case ISD::SETEQ: 726 Opcode = AMDGPU::V_CMP_NEQ_F32_e64; 727 break; 728 case ISD::SETOGT: 729 case ISD::SETGT: 730 Opcode = AMDGPU::V_CMP_NLT_F32_e64; 731 break; 732 case ISD::SETOGE: 733 case ISD::SETGE: 734 Opcode = AMDGPU::V_CMP_NLE_F32_e64; 735 break; 736 case ISD::SETOLT: 737 case ISD::SETLT: 738 Opcode = AMDGPU::V_CMP_NGT_F32_e64; 739 break; 740 case ISD::SETOLE: 741 case ISD::SETLE: 742 Opcode = AMDGPU::V_CMP_NGE_F32_e64; 743 break; 744 case ISD::SETONE: 745 case ISD::SETNE: 746 Opcode = AMDGPU::V_CMP_NLG_F32_e64; 747 break; 748 default: 749 llvm_unreachable("invalid ISD:SET cond code"); 750 } 751 752 // Pick opcode based on comparison type. 753 MachineInstr *VcmpMI; 754 const MachineOperand &Op0 = MI.getOperand(0); 755 const MachineOperand &Op1 = MI.getOperand(1); 756 if (TRI->isVGPR(*MRI, Op0.getReg())) { 757 Opcode = AMDGPU::getVOPe32(Opcode); 758 VcmpMI = BuildMI(MBB, &MI, DL, TII->get(Opcode)).add(Op1).add(Op0); 759 } else { 760 VcmpMI = BuildMI(MBB, &MI, DL, TII->get(Opcode)) 761 .addReg(AMDGPU::VCC, RegState::Define) 762 .addImm(0) // src0 modifiers 763 .add(Op1) 764 .addImm(0) // src1 modifiers 765 .add(Op0) 766 .addImm(0); // omod 767 } 768 769 // VCC represents lanes killed. 770 Register VCC = ST->isWave32() ? AMDGPU::VCC_LO : AMDGPU::VCC; 771 772 MachineInstr *MaskUpdateMI = 773 BuildMI(MBB, MI, DL, TII->get(AndN2Opc), LiveMaskReg) 774 .addReg(LiveMaskReg) 775 .addReg(VCC); 776 777 // State of SCC represents whether any lanes are live in mask, 778 // if SCC is 0 then no lanes will be alive anymore. 779 MachineInstr *EarlyTermMI = 780 BuildMI(MBB, MI, DL, TII->get(AMDGPU::SI_EARLY_TERMINATE_SCC0)); 781 782 MachineInstr *ExecMaskMI = 783 BuildMI(MBB, MI, DL, TII->get(AndN2Opc), Exec).addReg(Exec).addReg(VCC); 784 785 assert(MBB.succ_size() == 1); 786 MachineInstr *NewTerm = BuildMI(MBB, MI, DL, TII->get(AMDGPU::S_BRANCH)) 787 .addMBB(*MBB.succ_begin()); 788 789 // Update live intervals 790 LIS->ReplaceMachineInstrInMaps(MI, *VcmpMI); 791 MBB.remove(&MI); 792 793 LIS->InsertMachineInstrInMaps(*MaskUpdateMI); 794 LIS->InsertMachineInstrInMaps(*ExecMaskMI); 795 LIS->InsertMachineInstrInMaps(*EarlyTermMI); 796 LIS->InsertMachineInstrInMaps(*NewTerm); 797 798 return NewTerm; 799 } 800 801 MachineInstr *SIWholeQuadMode::lowerKillI1(MachineBasicBlock &MBB, 802 MachineInstr &MI, bool IsWQM) { 803 const DebugLoc &DL = MI.getDebugLoc(); 804 MachineInstr *MaskUpdateMI = nullptr; 805 806 const bool IsDemote = IsWQM && (MI.getOpcode() == AMDGPU::SI_DEMOTE_I1); 807 const MachineOperand &Op = MI.getOperand(0); 808 int64_t KillVal = MI.getOperand(1).getImm(); 809 MachineInstr *ComputeKilledMaskMI = nullptr; 810 Register CndReg = !Op.isImm() ? Op.getReg() : Register(); 811 Register TmpReg; 812 813 // Is this a static or dynamic kill? 814 if (Op.isImm()) { 815 if (Op.getImm() == KillVal) { 816 // Static: all active lanes are killed 817 MaskUpdateMI = BuildMI(MBB, MI, DL, TII->get(AndN2Opc), LiveMaskReg) 818 .addReg(LiveMaskReg) 819 .addReg(Exec); 820 } else { 821 // Static: kill does nothing 822 MachineInstr *NewTerm = nullptr; 823 if (IsDemote) { 824 LIS->RemoveMachineInstrFromMaps(MI); 825 } else { 826 assert(MBB.succ_size() == 1); 827 NewTerm = BuildMI(MBB, MI, DL, TII->get(AMDGPU::S_BRANCH)) 828 .addMBB(*MBB.succ_begin()); 829 LIS->ReplaceMachineInstrInMaps(MI, *NewTerm); 830 } 831 MBB.remove(&MI); 832 return NewTerm; 833 } 834 } else { 835 if (!KillVal) { 836 // Op represents live lanes after kill, 837 // so exec mask needs to be factored in. 838 TmpReg = MRI->createVirtualRegister(TRI->getBoolRC()); 839 ComputeKilledMaskMI = 840 BuildMI(MBB, MI, DL, TII->get(XorOpc), TmpReg).add(Op).addReg(Exec); 841 MaskUpdateMI = BuildMI(MBB, MI, DL, TII->get(AndN2Opc), LiveMaskReg) 842 .addReg(LiveMaskReg) 843 .addReg(TmpReg); 844 } else { 845 // Op represents lanes to kill 846 MaskUpdateMI = BuildMI(MBB, MI, DL, TII->get(AndN2Opc), LiveMaskReg) 847 .addReg(LiveMaskReg) 848 .add(Op); 849 } 850 } 851 852 // State of SCC represents whether any lanes are live in mask, 853 // if SCC is 0 then no lanes will be alive anymore. 854 MachineInstr *EarlyTermMI = 855 BuildMI(MBB, MI, DL, TII->get(AMDGPU::SI_EARLY_TERMINATE_SCC0)); 856 857 // In the case we got this far some lanes are still live, 858 // update EXEC to deactivate lanes as appropriate. 859 MachineInstr *NewTerm; 860 MachineInstr *WQMMaskMI = nullptr; 861 Register LiveMaskWQM; 862 if (IsDemote) { 863 // Demotes deactive quads with only helper lanes 864 LiveMaskWQM = MRI->createVirtualRegister(TRI->getBoolRC()); 865 WQMMaskMI = 866 BuildMI(MBB, MI, DL, TII->get(WQMOpc), LiveMaskWQM).addReg(LiveMaskReg); 867 NewTerm = BuildMI(MBB, MI, DL, TII->get(AndOpc), Exec) 868 .addReg(Exec) 869 .addReg(LiveMaskWQM); 870 } else { 871 // Kills deactivate lanes 872 if (Op.isImm()) { 873 unsigned MovOpc = ST->isWave32() ? AMDGPU::S_MOV_B32 : AMDGPU::S_MOV_B64; 874 NewTerm = BuildMI(MBB, &MI, DL, TII->get(MovOpc), Exec).addImm(0); 875 } else if (!IsWQM) { 876 NewTerm = BuildMI(MBB, &MI, DL, TII->get(AndOpc), Exec) 877 .addReg(Exec) 878 .addReg(LiveMaskReg); 879 } else { 880 unsigned Opcode = KillVal ? AndN2Opc : AndOpc; 881 NewTerm = 882 BuildMI(MBB, &MI, DL, TII->get(Opcode), Exec).addReg(Exec).add(Op); 883 } 884 } 885 886 // Update live intervals 887 LIS->RemoveMachineInstrFromMaps(MI); 888 MBB.remove(&MI); 889 assert(EarlyTermMI); 890 assert(MaskUpdateMI); 891 assert(NewTerm); 892 if (ComputeKilledMaskMI) 893 LIS->InsertMachineInstrInMaps(*ComputeKilledMaskMI); 894 LIS->InsertMachineInstrInMaps(*MaskUpdateMI); 895 LIS->InsertMachineInstrInMaps(*EarlyTermMI); 896 if (WQMMaskMI) 897 LIS->InsertMachineInstrInMaps(*WQMMaskMI); 898 LIS->InsertMachineInstrInMaps(*NewTerm); 899 900 if (CndReg) { 901 LIS->removeInterval(CndReg); 902 LIS->createAndComputeVirtRegInterval(CndReg); 903 } 904 if (TmpReg) 905 LIS->createAndComputeVirtRegInterval(TmpReg); 906 if (LiveMaskWQM) 907 LIS->createAndComputeVirtRegInterval(LiveMaskWQM); 908 909 return NewTerm; 910 } 911 912 // Replace (or supplement) instructions accessing live mask. 913 // This can only happen once all the live mask registers have been created 914 // and the execute state (WQM/WWM/Exact) of instructions is known. 915 void SIWholeQuadMode::lowerBlock(MachineBasicBlock &MBB) { 916 auto BII = Blocks.find(&MBB); 917 if (BII == Blocks.end()) 918 return; 919 920 const BlockInfo &BI = BII->second; 921 if (!BI.NeedsLowering) 922 return; 923 924 LLVM_DEBUG(dbgs() << "\nLowering block " << printMBBReference(MBB) << ":\n"); 925 926 SmallVector<MachineInstr *, 4> SplitPoints; 927 char State = BI.InitialState; 928 929 auto II = MBB.getFirstNonPHI(), IE = MBB.end(); 930 while (II != IE) { 931 auto Next = std::next(II); 932 MachineInstr &MI = *II; 933 934 if (StateTransition.count(&MI)) 935 State = StateTransition[&MI]; 936 937 MachineInstr *SplitPoint = nullptr; 938 switch (MI.getOpcode()) { 939 case AMDGPU::SI_DEMOTE_I1: 940 case AMDGPU::SI_KILL_I1_TERMINATOR: 941 SplitPoint = lowerKillI1(MBB, MI, State == StateWQM); 942 break; 943 case AMDGPU::SI_KILL_F32_COND_IMM_TERMINATOR: 944 SplitPoint = lowerKillF32(MBB, MI); 945 break; 946 default: 947 break; 948 } 949 if (SplitPoint) 950 SplitPoints.push_back(SplitPoint); 951 952 II = Next; 953 } 954 955 // Perform splitting after instruction scan to simplify iteration. 956 if (!SplitPoints.empty()) { 957 MachineBasicBlock *BB = &MBB; 958 for (MachineInstr *MI : SplitPoints) { 959 BB = splitBlock(BB, MI); 960 } 961 } 962 } 963 964 // Return an iterator in the (inclusive) range [First, Last] at which 965 // instructions can be safely inserted, keeping in mind that some of the 966 // instructions we want to add necessarily clobber SCC. 967 MachineBasicBlock::iterator SIWholeQuadMode::prepareInsertion( 968 MachineBasicBlock &MBB, MachineBasicBlock::iterator First, 969 MachineBasicBlock::iterator Last, bool PreferLast, bool SaveSCC) { 970 if (!SaveSCC) 971 return PreferLast ? Last : First; 972 973 LiveRange &LR = 974 LIS->getRegUnit(*MCRegUnitIterator(MCRegister::from(AMDGPU::SCC), TRI)); 975 auto MBBE = MBB.end(); 976 SlotIndex FirstIdx = First != MBBE ? LIS->getInstructionIndex(*First) 977 : LIS->getMBBEndIdx(&MBB); 978 SlotIndex LastIdx = 979 Last != MBBE ? LIS->getInstructionIndex(*Last) : LIS->getMBBEndIdx(&MBB); 980 SlotIndex Idx = PreferLast ? LastIdx : FirstIdx; 981 const LiveRange::Segment *S; 982 983 for (;;) { 984 S = LR.getSegmentContaining(Idx); 985 if (!S) 986 break; 987 988 if (PreferLast) { 989 SlotIndex Next = S->start.getBaseIndex(); 990 if (Next < FirstIdx) 991 break; 992 Idx = Next; 993 } else { 994 MachineInstr *EndMI = LIS->getInstructionFromIndex(S->end.getBaseIndex()); 995 assert(EndMI && "Segment does not end on valid instruction"); 996 auto NextI = std::next(EndMI->getIterator()); 997 if (NextI == MBB.end()) 998 break; 999 SlotIndex Next = LIS->getInstructionIndex(*NextI); 1000 if (Next > LastIdx) 1001 break; 1002 Idx = Next; 1003 } 1004 } 1005 1006 MachineBasicBlock::iterator MBBI; 1007 1008 if (MachineInstr *MI = LIS->getInstructionFromIndex(Idx)) 1009 MBBI = MI; 1010 else { 1011 assert(Idx == LIS->getMBBEndIdx(&MBB)); 1012 MBBI = MBB.end(); 1013 } 1014 1015 // Move insertion point past any operations modifying EXEC. 1016 // This assumes that the value of SCC defined by any of these operations 1017 // does not need to be preserved. 1018 while (MBBI != Last) { 1019 bool IsExecDef = false; 1020 for (const MachineOperand &MO : MBBI->operands()) { 1021 if (MO.isReg() && MO.isDef()) { 1022 IsExecDef |= 1023 MO.getReg() == AMDGPU::EXEC_LO || MO.getReg() == AMDGPU::EXEC; 1024 } 1025 } 1026 if (!IsExecDef) 1027 break; 1028 MBBI++; 1029 S = nullptr; 1030 } 1031 1032 if (S) 1033 MBBI = saveSCC(MBB, MBBI); 1034 1035 return MBBI; 1036 } 1037 1038 void SIWholeQuadMode::toExact(MachineBasicBlock &MBB, 1039 MachineBasicBlock::iterator Before, 1040 Register SaveWQM) { 1041 MachineInstr *MI; 1042 1043 if (SaveWQM) { 1044 MI = BuildMI(MBB, Before, DebugLoc(), TII->get(AndSaveExecOpc), SaveWQM) 1045 .addReg(LiveMaskReg); 1046 } else { 1047 MI = BuildMI(MBB, Before, DebugLoc(), TII->get(AndOpc), Exec) 1048 .addReg(Exec) 1049 .addReg(LiveMaskReg); 1050 } 1051 1052 LIS->InsertMachineInstrInMaps(*MI); 1053 StateTransition[MI] = StateExact; 1054 } 1055 1056 void SIWholeQuadMode::toWQM(MachineBasicBlock &MBB, 1057 MachineBasicBlock::iterator Before, 1058 Register SavedWQM) { 1059 MachineInstr *MI; 1060 1061 if (SavedWQM) { 1062 MI = BuildMI(MBB, Before, DebugLoc(), TII->get(AMDGPU::COPY), Exec) 1063 .addReg(SavedWQM); 1064 } else { 1065 MI = BuildMI(MBB, Before, DebugLoc(), TII->get(WQMOpc), Exec).addReg(Exec); 1066 } 1067 1068 LIS->InsertMachineInstrInMaps(*MI); 1069 StateTransition[MI] = StateWQM; 1070 } 1071 1072 void SIWholeQuadMode::toWWM(MachineBasicBlock &MBB, 1073 MachineBasicBlock::iterator Before, 1074 Register SaveOrig) { 1075 MachineInstr *MI; 1076 1077 assert(SaveOrig); 1078 MI = BuildMI(MBB, Before, DebugLoc(), TII->get(AMDGPU::ENTER_WWM), SaveOrig) 1079 .addImm(-1); 1080 LIS->InsertMachineInstrInMaps(*MI); 1081 StateTransition[MI] = StateWWM; 1082 } 1083 1084 void SIWholeQuadMode::fromWWM(MachineBasicBlock &MBB, 1085 MachineBasicBlock::iterator Before, 1086 Register SavedOrig, char NonWWMState) { 1087 MachineInstr *MI; 1088 1089 assert(SavedOrig); 1090 MI = BuildMI(MBB, Before, DebugLoc(), TII->get(AMDGPU::EXIT_WWM), Exec) 1091 .addReg(SavedOrig); 1092 LIS->InsertMachineInstrInMaps(*MI); 1093 StateTransition[MI] = NonWWMState; 1094 } 1095 1096 void SIWholeQuadMode::processBlock(MachineBasicBlock &MBB, bool IsEntry) { 1097 auto BII = Blocks.find(&MBB); 1098 if (BII == Blocks.end()) 1099 return; 1100 1101 BlockInfo &BI = BII->second; 1102 1103 // This is a non-entry block that is WQM throughout, so no need to do 1104 // anything. 1105 if (!IsEntry && BI.Needs == StateWQM && BI.OutNeeds != StateExact) { 1106 BI.InitialState = StateWQM; 1107 return; 1108 } 1109 1110 LLVM_DEBUG(dbgs() << "\nProcessing block " << printMBBReference(MBB) 1111 << ":\n"); 1112 1113 Register SavedWQMReg; 1114 Register SavedNonWWMReg; 1115 bool WQMFromExec = IsEntry; 1116 char State = (IsEntry || !(BI.InNeeds & StateWQM)) ? StateExact : StateWQM; 1117 char NonWWMState = 0; 1118 const TargetRegisterClass *BoolRC = TRI->getBoolRC(); 1119 1120 auto II = MBB.getFirstNonPHI(), IE = MBB.end(); 1121 if (IsEntry) { 1122 // Skip the instruction that saves LiveMask 1123 if (II != IE && II->getOpcode() == AMDGPU::COPY) 1124 ++II; 1125 } 1126 1127 // This stores the first instruction where it's safe to switch from WQM to 1128 // Exact or vice versa. 1129 MachineBasicBlock::iterator FirstWQM = IE; 1130 1131 // This stores the first instruction where it's safe to switch from WWM to 1132 // Exact/WQM or to switch to WWM. It must always be the same as, or after, 1133 // FirstWQM since if it's safe to switch to/from WWM, it must be safe to 1134 // switch to/from WQM as well. 1135 MachineBasicBlock::iterator FirstWWM = IE; 1136 1137 // Record initial state is block information. 1138 BI.InitialState = State; 1139 1140 for (;;) { 1141 MachineBasicBlock::iterator Next = II; 1142 char Needs = StateExact | StateWQM; // WWM is disabled by default 1143 char OutNeeds = 0; 1144 1145 if (FirstWQM == IE) 1146 FirstWQM = II; 1147 1148 if (FirstWWM == IE) 1149 FirstWWM = II; 1150 1151 // First, figure out the allowed states (Needs) based on the propagated 1152 // flags. 1153 if (II != IE) { 1154 MachineInstr &MI = *II; 1155 1156 if (MI.isTerminator() || TII->mayReadEXEC(*MRI, MI)) { 1157 auto III = Instructions.find(&MI); 1158 if (III != Instructions.end()) { 1159 if (III->second.Needs & StateWWM) 1160 Needs = StateWWM; 1161 else if (III->second.Needs & StateWQM) 1162 Needs = StateWQM; 1163 else 1164 Needs &= ~III->second.Disabled; 1165 OutNeeds = III->second.OutNeeds; 1166 } 1167 } else { 1168 // If the instruction doesn't actually need a correct EXEC, then we can 1169 // safely leave WWM enabled. 1170 Needs = StateExact | StateWQM | StateWWM; 1171 } 1172 1173 if (MI.isTerminator() && OutNeeds == StateExact) 1174 Needs = StateExact; 1175 1176 ++Next; 1177 } else { 1178 // End of basic block 1179 if (BI.OutNeeds & StateWQM) 1180 Needs = StateWQM; 1181 else if (BI.OutNeeds == StateExact) 1182 Needs = StateExact; 1183 else 1184 Needs = StateWQM | StateExact; 1185 } 1186 1187 // Now, transition if necessary. 1188 if (!(Needs & State)) { 1189 MachineBasicBlock::iterator First; 1190 if (State == StateWWM || Needs == StateWWM) { 1191 // We must switch to or from WWM 1192 First = FirstWWM; 1193 } else { 1194 // We only need to switch to/from WQM, so we can use FirstWQM 1195 First = FirstWQM; 1196 } 1197 1198 // Whether we need to save SCC depends on start and end states 1199 bool SaveSCC = false; 1200 switch (State) { 1201 case StateExact: 1202 case StateWWM: 1203 // Exact/WWM -> WWM: save SCC 1204 // Exact/WWM -> WQM: save SCC if WQM mask is generated from exec 1205 // Exact/WWM -> Exact: no save 1206 SaveSCC = (Needs & StateWWM) || ((Needs & StateWQM) && WQMFromExec); 1207 break; 1208 case StateWQM: 1209 // WQM -> Exact/WMM: save SCC 1210 SaveSCC = !(Needs & StateWQM); 1211 break; 1212 default: 1213 llvm_unreachable("Unknown state"); 1214 break; 1215 } 1216 MachineBasicBlock::iterator Before = 1217 prepareInsertion(MBB, First, II, Needs == StateWQM, SaveSCC); 1218 1219 if (State == StateWWM) { 1220 assert(SavedNonWWMReg); 1221 fromWWM(MBB, Before, SavedNonWWMReg, NonWWMState); 1222 LIS->createAndComputeVirtRegInterval(SavedNonWWMReg); 1223 SavedNonWWMReg = 0; 1224 State = NonWWMState; 1225 } 1226 1227 if (Needs == StateWWM) { 1228 NonWWMState = State; 1229 assert(!SavedNonWWMReg); 1230 SavedNonWWMReg = MRI->createVirtualRegister(BoolRC); 1231 toWWM(MBB, Before, SavedNonWWMReg); 1232 State = StateWWM; 1233 } else { 1234 if (State == StateWQM && (Needs & StateExact) && !(Needs & StateWQM)) { 1235 if (!WQMFromExec && (OutNeeds & StateWQM)) { 1236 assert(!SavedWQMReg); 1237 SavedWQMReg = MRI->createVirtualRegister(BoolRC); 1238 } 1239 1240 toExact(MBB, Before, SavedWQMReg); 1241 State = StateExact; 1242 } else if (State == StateExact && (Needs & StateWQM) && 1243 !(Needs & StateExact)) { 1244 assert(WQMFromExec == (SavedWQMReg == 0)); 1245 1246 toWQM(MBB, Before, SavedWQMReg); 1247 1248 if (SavedWQMReg) { 1249 LIS->createAndComputeVirtRegInterval(SavedWQMReg); 1250 SavedWQMReg = 0; 1251 } 1252 State = StateWQM; 1253 } else { 1254 // We can get here if we transitioned from WWM to a non-WWM state that 1255 // already matches our needs, but we shouldn't need to do anything. 1256 assert(Needs & State); 1257 } 1258 } 1259 } 1260 1261 if (Needs != (StateExact | StateWQM | StateWWM)) { 1262 if (Needs != (StateExact | StateWQM)) 1263 FirstWQM = IE; 1264 FirstWWM = IE; 1265 } 1266 1267 if (II == IE) 1268 break; 1269 1270 II = Next; 1271 } 1272 assert(!SavedWQMReg); 1273 assert(!SavedNonWWMReg); 1274 } 1275 1276 void SIWholeQuadMode::lowerLiveMaskQueries() { 1277 for (MachineInstr *MI : LiveMaskQueries) { 1278 const DebugLoc &DL = MI->getDebugLoc(); 1279 Register Dest = MI->getOperand(0).getReg(); 1280 1281 MachineInstr *Copy = 1282 BuildMI(*MI->getParent(), MI, DL, TII->get(AMDGPU::COPY), Dest) 1283 .addReg(LiveMaskReg); 1284 1285 LIS->ReplaceMachineInstrInMaps(*MI, *Copy); 1286 MI->eraseFromParent(); 1287 } 1288 } 1289 1290 void SIWholeQuadMode::lowerCopyInstrs() { 1291 for (MachineInstr *MI : LowerToMovInstrs) { 1292 assert(MI->getNumExplicitOperands() == 2); 1293 1294 const Register Reg = MI->getOperand(0).getReg(); 1295 const unsigned SubReg = MI->getOperand(0).getSubReg(); 1296 1297 if (TRI->isVGPR(*MRI, Reg)) { 1298 const TargetRegisterClass *regClass = 1299 Reg.isVirtual() ? MRI->getRegClass(Reg) : TRI->getPhysRegClass(Reg); 1300 if (SubReg) 1301 regClass = TRI->getSubRegClass(regClass, SubReg); 1302 1303 const unsigned MovOp = TII->getMovOpcode(regClass); 1304 MI->setDesc(TII->get(MovOp)); 1305 1306 // And make it implicitly depend on exec (like all VALU movs should do). 1307 MI->addOperand(MachineOperand::CreateReg(AMDGPU::EXEC, false, true)); 1308 } else { 1309 // Remove early-clobber and exec dependency from simple SGPR copies. 1310 // This allows some to be eliminated during/post RA. 1311 LLVM_DEBUG(dbgs() << "simplify SGPR copy: " << *MI); 1312 if (MI->getOperand(0).isEarlyClobber()) { 1313 LIS->removeInterval(Reg); 1314 MI->getOperand(0).setIsEarlyClobber(false); 1315 LIS->createAndComputeVirtRegInterval(Reg); 1316 } 1317 int Index = MI->findRegisterUseOperandIdx(AMDGPU::EXEC); 1318 while (Index >= 0) { 1319 MI->RemoveOperand(Index); 1320 Index = MI->findRegisterUseOperandIdx(AMDGPU::EXEC); 1321 } 1322 MI->setDesc(TII->get(AMDGPU::COPY)); 1323 LLVM_DEBUG(dbgs() << " -> " << *MI); 1324 } 1325 } 1326 for (MachineInstr *MI : LowerToCopyInstrs) { 1327 if (MI->getOpcode() == AMDGPU::V_SET_INACTIVE_B32 || 1328 MI->getOpcode() == AMDGPU::V_SET_INACTIVE_B64) { 1329 assert(MI->getNumExplicitOperands() == 3); 1330 // the only reason we should be here is V_SET_INACTIVE has 1331 // an undef input so it is being replaced by a simple copy. 1332 // There should be a second undef source that we should remove. 1333 assert(MI->getOperand(2).isUndef()); 1334 MI->RemoveOperand(2); 1335 MI->untieRegOperand(1); 1336 } else { 1337 assert(MI->getNumExplicitOperands() == 2); 1338 } 1339 1340 MI->setDesc(TII->get(AMDGPU::COPY)); 1341 } 1342 } 1343 1344 void SIWholeQuadMode::lowerKillInstrs(bool IsWQM) { 1345 for (MachineInstr *MI : KillInstrs) { 1346 MachineBasicBlock *MBB = MI->getParent(); 1347 MachineInstr *SplitPoint = nullptr; 1348 switch (MI->getOpcode()) { 1349 case AMDGPU::SI_DEMOTE_I1: 1350 case AMDGPU::SI_KILL_I1_TERMINATOR: 1351 SplitPoint = lowerKillI1(*MBB, *MI, IsWQM); 1352 break; 1353 case AMDGPU::SI_KILL_F32_COND_IMM_TERMINATOR: 1354 SplitPoint = lowerKillF32(*MBB, *MI); 1355 break; 1356 default: 1357 continue; 1358 } 1359 if (SplitPoint) 1360 splitBlock(MBB, SplitPoint); 1361 } 1362 } 1363 1364 bool SIWholeQuadMode::runOnMachineFunction(MachineFunction &MF) { 1365 Instructions.clear(); 1366 Blocks.clear(); 1367 LiveMaskQueries.clear(); 1368 LowerToCopyInstrs.clear(); 1369 LowerToMovInstrs.clear(); 1370 KillInstrs.clear(); 1371 StateTransition.clear(); 1372 1373 ST = &MF.getSubtarget<GCNSubtarget>(); 1374 1375 TII = ST->getInstrInfo(); 1376 TRI = &TII->getRegisterInfo(); 1377 MRI = &MF.getRegInfo(); 1378 LIS = &getAnalysis<LiveIntervals>(); 1379 MDT = &getAnalysis<MachineDominatorTree>(); 1380 PDT = &getAnalysis<MachinePostDominatorTree>(); 1381 1382 if (ST->isWave32()) { 1383 AndOpc = AMDGPU::S_AND_B32; 1384 AndN2Opc = AMDGPU::S_ANDN2_B32; 1385 XorOpc = AMDGPU::S_XOR_B32; 1386 AndSaveExecOpc = AMDGPU::S_AND_SAVEEXEC_B32; 1387 OrSaveExecOpc = AMDGPU::S_OR_SAVEEXEC_B32; 1388 WQMOpc = AMDGPU::S_WQM_B32; 1389 Exec = AMDGPU::EXEC_LO; 1390 } else { 1391 AndOpc = AMDGPU::S_AND_B64; 1392 AndN2Opc = AMDGPU::S_ANDN2_B64; 1393 XorOpc = AMDGPU::S_XOR_B64; 1394 AndSaveExecOpc = AMDGPU::S_AND_SAVEEXEC_B64; 1395 OrSaveExecOpc = AMDGPU::S_OR_SAVEEXEC_B64; 1396 WQMOpc = AMDGPU::S_WQM_B64; 1397 Exec = AMDGPU::EXEC; 1398 } 1399 1400 const char GlobalFlags = analyzeFunction(MF); 1401 const bool NeedsLiveMask = !(KillInstrs.empty() && LiveMaskQueries.empty()); 1402 1403 LiveMaskReg = Exec; 1404 1405 // Shader is simple does not need WQM/WWM or any complex lowering 1406 if (!(GlobalFlags & (StateWQM | StateWWM)) && LowerToCopyInstrs.empty() && 1407 LowerToMovInstrs.empty() && KillInstrs.empty()) { 1408 lowerLiveMaskQueries(); 1409 return !LiveMaskQueries.empty(); 1410 } 1411 1412 MachineBasicBlock &Entry = MF.front(); 1413 MachineBasicBlock::iterator EntryMI = Entry.getFirstNonPHI(); 1414 1415 // Store a copy of the original live mask when required 1416 if (NeedsLiveMask || (GlobalFlags & StateWQM)) { 1417 LiveMaskReg = MRI->createVirtualRegister(TRI->getBoolRC()); 1418 MachineInstr *MI = 1419 BuildMI(Entry, EntryMI, DebugLoc(), TII->get(AMDGPU::COPY), LiveMaskReg) 1420 .addReg(Exec); 1421 LIS->InsertMachineInstrInMaps(*MI); 1422 } 1423 1424 LLVM_DEBUG(printInfo()); 1425 1426 lowerLiveMaskQueries(); 1427 lowerCopyInstrs(); 1428 1429 // Shader only needs WQM 1430 if (GlobalFlags == StateWQM) { 1431 auto MI = BuildMI(Entry, EntryMI, DebugLoc(), TII->get(WQMOpc), Exec) 1432 .addReg(Exec); 1433 LIS->InsertMachineInstrInMaps(*MI); 1434 lowerKillInstrs(true); 1435 } else { 1436 for (auto BII : Blocks) 1437 processBlock(*BII.first, BII.first == &Entry); 1438 // Lowering blocks causes block splitting so perform as a second pass. 1439 for (auto BII : Blocks) 1440 lowerBlock(*BII.first); 1441 } 1442 1443 // Compute live range for live mask 1444 if (LiveMaskReg != Exec) 1445 LIS->createAndComputeVirtRegInterval(LiveMaskReg); 1446 1447 // Physical registers like SCC aren't tracked by default anyway, so just 1448 // removing the ranges we computed is the simplest option for maintaining 1449 // the analysis results. 1450 LIS->removeRegUnit(*MCRegUnitIterator(MCRegister::from(AMDGPU::SCC), TRI)); 1451 1452 // If we performed any kills then recompute EXEC 1453 if (!KillInstrs.empty()) 1454 LIS->removeRegUnit(*MCRegUnitIterator(AMDGPU::EXEC, TRI)); 1455 1456 return true; 1457 } 1458