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