1//===-- SILowerControlFlow.cpp - Use predicates for control flow ----------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// --- 95 unchanged lines hidden (view full) --- 104} // End anonymous namespace 105 106char SILowerControlFlowPass::ID = 0; 107 108FunctionPass *llvm::createSILowerControlFlowPass(TargetMachine &tm) { 109 return new SILowerControlFlowPass(tm); 110} 111 |
112static bool isDS(unsigned Opcode) { 113 switch(Opcode) { 114 default: return false; 115 case AMDGPU::DS_ADD_U32_RTN: 116 case AMDGPU::DS_SUB_U32_RTN: 117 case AMDGPU::DS_WRITE_B32: 118 case AMDGPU::DS_WRITE_B8: 119 case AMDGPU::DS_WRITE_B16: 120 case AMDGPU::DS_READ_B32: 121 case AMDGPU::DS_READ_I8: 122 case AMDGPU::DS_READ_U8: 123 case AMDGPU::DS_READ_I16: 124 case AMDGPU::DS_READ_U16: 125 return true; 126 } 127} 128 |
129bool SILowerControlFlowPass::shouldSkip(MachineBasicBlock *From, 130 MachineBasicBlock *To) { 131 132 unsigned NumInstr = 0; 133 134 for (MachineBasicBlock *MBB = From; MBB != To && !MBB->succ_empty(); 135 MBB = *MBB->succ_begin()) { 136 --- 20 unchanged lines hidden (view full) --- 157 .addReg(AMDGPU::EXEC); 158} 159 160void SILowerControlFlowPass::SkipIfDead(MachineInstr &MI) { 161 162 MachineBasicBlock &MBB = *MI.getParent(); 163 DebugLoc DL = MI.getDebugLoc(); 164 |
165 if (MBB.getParent()->getInfo<SIMachineFunctionInfo>()->ShaderType != 166 ShaderType::PIXEL || 167 !shouldSkip(&MBB, &MBB.getParent()->back())) |
168 return; 169 170 MachineBasicBlock::iterator Insert = &MI; 171 ++Insert; 172 173 // If the exec mask is non-zero, skip the next two instructions 174 BuildMI(MBB, Insert, DL, TII->get(AMDGPU::S_CBRANCH_EXECNZ)) 175 .addImm(3) --- 134 unchanged lines hidden (view full) --- 310 assert(0); 311} 312 313void SILowerControlFlowPass::Kill(MachineInstr &MI) { 314 315 MachineBasicBlock &MBB = *MI.getParent(); 316 DebugLoc DL = MI.getDebugLoc(); 317 |
318 // Kill is only allowed in pixel / geometry shaders |
319 assert(MBB.getParent()->getInfo<SIMachineFunctionInfo>()->ShaderType == |
320 ShaderType::PIXEL || 321 MBB.getParent()->getInfo<SIMachineFunctionInfo>()->ShaderType == 322 ShaderType::GEOMETRY); |
323 324 // Clear this pixel from the exec mask if the operand is negative 325 BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_CMPX_LE_F32_e32), AMDGPU::VCC) 326 .addImm(0) 327 .addOperand(MI.getOperand(0)); 328 329 MI.eraseFromParent(); 330} --- 116 unchanged lines hidden (view full) --- 447 BI != BE; ++BI) { 448 449 MachineBasicBlock &MBB = *BI; 450 for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I); 451 I != MBB.end(); I = Next) { 452 453 Next = llvm::next(I); 454 MachineInstr &MI = *I; |
455 if (isDS(MI.getOpcode())) { 456 NeedM0 = true; 457 NeedWQM = true; 458 } 459 |
460 switch (MI.getOpcode()) { 461 default: break; 462 case AMDGPU::SI_IF: 463 ++Depth; 464 If(MI); 465 break; 466 467 case AMDGPU::SI_ELSE: --- 44 unchanged lines hidden (view full) --- 512 case AMDGPU::SI_INDIRECT_DST_V1: 513 case AMDGPU::SI_INDIRECT_DST_V2: 514 case AMDGPU::SI_INDIRECT_DST_V4: 515 case AMDGPU::SI_INDIRECT_DST_V8: 516 case AMDGPU::SI_INDIRECT_DST_V16: 517 IndirectDst(MI); 518 break; 519 |
520 case AMDGPU::V_INTERP_P1_F32: 521 case AMDGPU::V_INTERP_P2_F32: 522 case AMDGPU::V_INTERP_MOV_F32: 523 NeedWQM = true; 524 break; 525 526 } 527 } 528 } 529 530 if (NeedM0) { 531 MachineBasicBlock &MBB = MF.front(); 532 // Initialize M0 to a value that won't cause LDS access to be discarded 533 // due to offset clamping 534 BuildMI(MBB, MBB.getFirstNonPHI(), DebugLoc(), TII->get(AMDGPU::S_MOV_B32), 535 AMDGPU::M0).addImm(0xffffffff); 536 } 537 |
538 if (NeedWQM && MFI->ShaderType == ShaderType::PIXEL) { |
539 MachineBasicBlock &MBB = MF.front(); 540 BuildMI(MBB, MBB.getFirstNonPHI(), DebugLoc(), TII->get(AMDGPU::S_WQM_B64), 541 AMDGPU::EXEC).addReg(AMDGPU::EXEC); 542 } 543 544 return true; 545} |