SIInstrInfo.cpp revision a2b4eb6d15a13de257319ac6231b5ab622cd02b1
1//===-- SIInstrInfo.cpp - SI Instruction Information ---------------------===// 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//===----------------------------------------------------------------------===// 9// 10/// \file 11/// \brief SI Implementation of TargetInstrInfo. 12// 13//===----------------------------------------------------------------------===// 14 15 16#include "SIInstrInfo.h" 17#include "AMDGPUTargetMachine.h" 18#include "SIDefines.h" 19#include "llvm/CodeGen/MachineInstrBuilder.h" 20#include "llvm/CodeGen/MachineRegisterInfo.h" 21#include "llvm/MC/MCInstrDesc.h" 22 23using namespace llvm; 24 25SIInstrInfo::SIInstrInfo(AMDGPUTargetMachine &tm) 26 : AMDGPUInstrInfo(tm), 27 RI(tm) 28 { } 29 30const SIRegisterInfo &SIInstrInfo::getRegisterInfo() const { 31 return RI; 32} 33 34//===----------------------------------------------------------------------===// 35// TargetInstrInfo callbacks 36//===----------------------------------------------------------------------===// 37 38void 39SIInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 40 MachineBasicBlock::iterator MI, DebugLoc DL, 41 unsigned DestReg, unsigned SrcReg, 42 bool KillSrc) const { 43 44 // If we are trying to copy to or from SCC, there is a bug somewhere else in 45 // the backend. While it may be theoretically possible to do this, it should 46 // never be necessary. 47 assert(DestReg != AMDGPU::SCC && SrcReg != AMDGPU::SCC); 48 49 static const int16_t Sub0_15[] = { 50 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3, 51 AMDGPU::sub4, AMDGPU::sub5, AMDGPU::sub6, AMDGPU::sub7, 52 AMDGPU::sub8, AMDGPU::sub9, AMDGPU::sub10, AMDGPU::sub11, 53 AMDGPU::sub12, AMDGPU::sub13, AMDGPU::sub14, AMDGPU::sub15, 0 54 }; 55 56 static const int16_t Sub0_7[] = { 57 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3, 58 AMDGPU::sub4, AMDGPU::sub5, AMDGPU::sub6, AMDGPU::sub7, 0 59 }; 60 61 static const int16_t Sub0_3[] = { 62 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3, 0 63 }; 64 65 static const int16_t Sub0_2[] = { 66 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, 0 67 }; 68 69 static const int16_t Sub0_1[] = { 70 AMDGPU::sub0, AMDGPU::sub1, 0 71 }; 72 73 unsigned Opcode; 74 const int16_t *SubIndices; 75 76 if (AMDGPU::M0 == DestReg) { 77 // Check if M0 isn't already set to this value 78 for (MachineBasicBlock::reverse_iterator E = MBB.rend(), 79 I = MachineBasicBlock::reverse_iterator(MI); I != E; ++I) { 80 81 if (!I->definesRegister(AMDGPU::M0)) 82 continue; 83 84 unsigned Opc = I->getOpcode(); 85 if (Opc != TargetOpcode::COPY && Opc != AMDGPU::S_MOV_B32) 86 break; 87 88 if (!I->readsRegister(SrcReg)) 89 break; 90 91 // The copy isn't necessary 92 return; 93 } 94 } 95 96 if (AMDGPU::SReg_32RegClass.contains(DestReg)) { 97 assert(AMDGPU::SReg_32RegClass.contains(SrcReg)); 98 BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B32), DestReg) 99 .addReg(SrcReg, getKillRegState(KillSrc)); 100 return; 101 102 } else if (AMDGPU::SReg_64RegClass.contains(DestReg)) { 103 assert(AMDGPU::SReg_64RegClass.contains(SrcReg)); 104 BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B64), DestReg) 105 .addReg(SrcReg, getKillRegState(KillSrc)); 106 return; 107 108 } else if (AMDGPU::SReg_128RegClass.contains(DestReg)) { 109 assert(AMDGPU::SReg_128RegClass.contains(SrcReg)); 110 Opcode = AMDGPU::S_MOV_B32; 111 SubIndices = Sub0_3; 112 113 } else if (AMDGPU::SReg_256RegClass.contains(DestReg)) { 114 assert(AMDGPU::SReg_256RegClass.contains(SrcReg)); 115 Opcode = AMDGPU::S_MOV_B32; 116 SubIndices = Sub0_7; 117 118 } else if (AMDGPU::SReg_512RegClass.contains(DestReg)) { 119 assert(AMDGPU::SReg_512RegClass.contains(SrcReg)); 120 Opcode = AMDGPU::S_MOV_B32; 121 SubIndices = Sub0_15; 122 123 } else if (AMDGPU::VReg_32RegClass.contains(DestReg)) { 124 assert(AMDGPU::VReg_32RegClass.contains(SrcReg) || 125 AMDGPU::SReg_32RegClass.contains(SrcReg)); 126 BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B32_e32), DestReg) 127 .addReg(SrcReg, getKillRegState(KillSrc)); 128 return; 129 130 } else if (AMDGPU::VReg_64RegClass.contains(DestReg)) { 131 assert(AMDGPU::VReg_64RegClass.contains(SrcReg) || 132 AMDGPU::SReg_64RegClass.contains(SrcReg)); 133 Opcode = AMDGPU::V_MOV_B32_e32; 134 SubIndices = Sub0_1; 135 136 } else if (AMDGPU::VReg_96RegClass.contains(DestReg)) { 137 assert(AMDGPU::VReg_96RegClass.contains(SrcReg)); 138 Opcode = AMDGPU::V_MOV_B32_e32; 139 SubIndices = Sub0_2; 140 141 } else if (AMDGPU::VReg_128RegClass.contains(DestReg)) { 142 assert(AMDGPU::VReg_128RegClass.contains(SrcReg) || 143 AMDGPU::SReg_128RegClass.contains(SrcReg)); 144 Opcode = AMDGPU::V_MOV_B32_e32; 145 SubIndices = Sub0_3; 146 147 } else if (AMDGPU::VReg_256RegClass.contains(DestReg)) { 148 assert(AMDGPU::VReg_256RegClass.contains(SrcReg) || 149 AMDGPU::SReg_256RegClass.contains(SrcReg)); 150 Opcode = AMDGPU::V_MOV_B32_e32; 151 SubIndices = Sub0_7; 152 153 } else if (AMDGPU::VReg_512RegClass.contains(DestReg)) { 154 assert(AMDGPU::VReg_512RegClass.contains(SrcReg) || 155 AMDGPU::SReg_512RegClass.contains(SrcReg)); 156 Opcode = AMDGPU::V_MOV_B32_e32; 157 SubIndices = Sub0_15; 158 159 } else { 160 llvm_unreachable("Can't copy register!"); 161 } 162 163 while (unsigned SubIdx = *SubIndices++) { 164 MachineInstrBuilder Builder = BuildMI(MBB, MI, DL, 165 get(Opcode), RI.getSubReg(DestReg, SubIdx)); 166 167 Builder.addReg(RI.getSubReg(SrcReg, SubIdx), getKillRegState(KillSrc)); 168 169 if (*SubIndices) 170 Builder.addReg(DestReg, RegState::Define | RegState::Implicit); 171 } 172} 173 174unsigned SIInstrInfo::commuteOpcode(unsigned Opcode) const { 175 176 int NewOpc; 177 178 // Try to map original to commuted opcode 179 if ((NewOpc = AMDGPU::getCommuteRev(Opcode)) != -1) 180 return NewOpc; 181 182 // Try to map commuted to original opcode 183 if ((NewOpc = AMDGPU::getCommuteOrig(Opcode)) != -1) 184 return NewOpc; 185 186 return Opcode; 187} 188 189MachineInstr *SIInstrInfo::commuteInstruction(MachineInstr *MI, 190 bool NewMI) const { 191 192 MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo(); 193 if (MI->getNumOperands() < 3 || !MI->getOperand(1).isReg()) 194 return 0; 195 196 // Cannot commute VOP2 if src0 is SGPR. 197 if (isVOP2(MI->getOpcode()) && MI->getOperand(1).isReg() && 198 RI.isSGPRClass(MRI.getRegClass(MI->getOperand(1).getReg()))) 199 return 0; 200 201 if (!MI->getOperand(2).isReg()) { 202 // XXX: Commute instructions with FPImm operands 203 if (NewMI || MI->getOperand(2).isFPImm() || 204 (!isVOP2(MI->getOpcode()) && !isVOP3(MI->getOpcode()))) { 205 return 0; 206 } 207 208 // XXX: Commute VOP3 instructions with abs and neg set. 209 if (isVOP3(MI->getOpcode()) && 210 (MI->getOperand(AMDGPU::getNamedOperandIdx(MI->getOpcode(), 211 AMDGPU::OpName::abs)).getImm() || 212 MI->getOperand(AMDGPU::getNamedOperandIdx(MI->getOpcode(), 213 AMDGPU::OpName::neg)).getImm())) 214 return 0; 215 216 unsigned Reg = MI->getOperand(1).getReg(); 217 MI->getOperand(1).ChangeToImmediate(MI->getOperand(2).getImm()); 218 MI->getOperand(2).ChangeToRegister(Reg, false); 219 } else { 220 MI = TargetInstrInfo::commuteInstruction(MI, NewMI); 221 } 222 223 if (MI) 224 MI->setDesc(get(commuteOpcode(MI->getOpcode()))); 225 226 return MI; 227} 228 229MachineInstr *SIInstrInfo::buildMovInstr(MachineBasicBlock *MBB, 230 MachineBasicBlock::iterator I, 231 unsigned DstReg, 232 unsigned SrcReg) const { 233 return BuildMI(*MBB, I, MBB->findDebugLoc(I), get(AMDGPU::V_MOV_B32_e32), 234 DstReg) .addReg(SrcReg); 235} 236 237bool SIInstrInfo::isMov(unsigned Opcode) const { 238 switch(Opcode) { 239 default: return false; 240 case AMDGPU::S_MOV_B32: 241 case AMDGPU::S_MOV_B64: 242 case AMDGPU::V_MOV_B32_e32: 243 case AMDGPU::V_MOV_B32_e64: 244 return true; 245 } 246} 247 248bool 249SIInstrInfo::isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const { 250 return RC != &AMDGPU::EXECRegRegClass; 251} 252 253int SIInstrInfo::isMIMG(uint16_t Opcode) const { 254 return get(Opcode).TSFlags & SIInstrFlags::MIMG; 255} 256 257int SIInstrInfo::isSMRD(uint16_t Opcode) const { 258 return get(Opcode).TSFlags & SIInstrFlags::SMRD; 259} 260 261bool SIInstrInfo::isVOP1(uint16_t Opcode) const { 262 return get(Opcode).TSFlags & SIInstrFlags::VOP1; 263} 264 265bool SIInstrInfo::isVOP2(uint16_t Opcode) const { 266 return get(Opcode).TSFlags & SIInstrFlags::VOP2; 267} 268 269bool SIInstrInfo::isVOP3(uint16_t Opcode) const { 270 return get(Opcode).TSFlags & SIInstrFlags::VOP3; 271} 272 273bool SIInstrInfo::isVOPC(uint16_t Opcode) const { 274 return get(Opcode).TSFlags & SIInstrFlags::VOPC; 275} 276 277bool SIInstrInfo::isSALUInstr(const MachineInstr &MI) const { 278 return get(MI.getOpcode()).TSFlags & SIInstrFlags::SALU; 279} 280 281bool SIInstrInfo::isInlineConstant(const MachineOperand &MO) const { 282 if(MO.isImm()) { 283 return MO.getImm() >= -16 && MO.getImm() <= 64; 284 } 285 if (MO.isFPImm()) { 286 return MO.getFPImm()->isExactlyValue(0.0) || 287 MO.getFPImm()->isExactlyValue(0.5) || 288 MO.getFPImm()->isExactlyValue(-0.5) || 289 MO.getFPImm()->isExactlyValue(1.0) || 290 MO.getFPImm()->isExactlyValue(-1.0) || 291 MO.getFPImm()->isExactlyValue(2.0) || 292 MO.getFPImm()->isExactlyValue(-2.0) || 293 MO.getFPImm()->isExactlyValue(4.0) || 294 MO.getFPImm()->isExactlyValue(-4.0); 295 } 296 return false; 297} 298 299bool SIInstrInfo::isLiteralConstant(const MachineOperand &MO) const { 300 return (MO.isImm() || MO.isFPImm()) && !isInlineConstant(MO); 301} 302 303bool SIInstrInfo::verifyInstruction(const MachineInstr *MI, 304 StringRef &ErrInfo) const { 305 uint16_t Opcode = MI->getOpcode(); 306 int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0); 307 int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1); 308 int Src2Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2); 309 310 // Verify VOP* 311 if (isVOP1(Opcode) || isVOP2(Opcode) || isVOP3(Opcode) || isVOPC(Opcode)) { 312 unsigned ConstantBusCount = 0; 313 unsigned SGPRUsed = AMDGPU::NoRegister; 314 for (int i = 0, e = MI->getNumOperands(); i != e; ++i) { 315 const MachineOperand &MO = MI->getOperand(i); 316 if (MO.isReg() && MO.isUse() && 317 !TargetRegisterInfo::isVirtualRegister(MO.getReg())) { 318 319 // EXEC register uses the constant bus. 320 if (!MO.isImplicit() && MO.getReg() == AMDGPU::EXEC) 321 ++ConstantBusCount; 322 323 // SGPRs use the constant bus 324 if (MO.getReg() == AMDGPU::M0 || MO.getReg() == AMDGPU::VCC || 325 (!MO.isImplicit() && 326 (AMDGPU::SGPR_32RegClass.contains(MO.getReg()) || 327 AMDGPU::SGPR_64RegClass.contains(MO.getReg())))) { 328 if (SGPRUsed != MO.getReg()) { 329 ++ConstantBusCount; 330 SGPRUsed = MO.getReg(); 331 } 332 } 333 } 334 // Literal constants use the constant bus. 335 if (isLiteralConstant(MO)) 336 ++ConstantBusCount; 337 } 338 if (ConstantBusCount > 1) { 339 ErrInfo = "VOP* instruction uses the constant bus more than once"; 340 return false; 341 } 342 } 343 344 // Verify SRC1 for VOP2 and VOPC 345 if (Src1Idx != -1 && (isVOP2(Opcode) || isVOPC(Opcode))) { 346 const MachineOperand &Src1 = MI->getOperand(Src1Idx); 347 if (Src1.isImm() || Src1.isFPImm()) { 348 ErrInfo = "VOP[2C] src1 cannot be an immediate."; 349 return false; 350 } 351 } 352 353 // Verify VOP3 354 if (isVOP3(Opcode)) { 355 if (Src0Idx != -1 && isLiteralConstant(MI->getOperand(Src0Idx))) { 356 ErrInfo = "VOP3 src0 cannot be a literal constant."; 357 return false; 358 } 359 if (Src1Idx != -1 && isLiteralConstant(MI->getOperand(Src1Idx))) { 360 ErrInfo = "VOP3 src1 cannot be a literal constant."; 361 return false; 362 } 363 if (Src2Idx != -1 && isLiteralConstant(MI->getOperand(Src2Idx))) { 364 ErrInfo = "VOP3 src2 cannot be a literal constant."; 365 return false; 366 } 367 } 368 return true; 369} 370 371unsigned SIInstrInfo::getVALUOp(const MachineInstr &MI) const { 372 switch (MI.getOpcode()) { 373 default: return AMDGPU::INSTRUCTION_LIST_END; 374 case AMDGPU::REG_SEQUENCE: return AMDGPU::REG_SEQUENCE; 375 case AMDGPU::COPY: return AMDGPU::COPY; 376 case AMDGPU::PHI: return AMDGPU::PHI; 377 case AMDGPU::S_ASHR_I32: return AMDGPU::V_ASHR_I32_e32; 378 case AMDGPU::S_ASHR_I64: return AMDGPU::V_ASHR_I64; 379 case AMDGPU::S_LSHL_B32: return AMDGPU::V_LSHL_B32_e32; 380 case AMDGPU::S_LSHL_B64: return AMDGPU::V_LSHL_B64; 381 case AMDGPU::S_LSHR_B32: return AMDGPU::V_LSHR_B32_e32; 382 case AMDGPU::S_LSHR_B64: return AMDGPU::V_LSHR_B64; 383 } 384} 385 386bool SIInstrInfo::isSALUOpSupportedOnVALU(const MachineInstr &MI) const { 387 return getVALUOp(MI) != AMDGPU::INSTRUCTION_LIST_END; 388} 389 390const TargetRegisterClass *SIInstrInfo::getOpRegClass(const MachineInstr &MI, 391 unsigned OpNo) const { 392 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo(); 393 const MCInstrDesc &Desc = get(MI.getOpcode()); 394 if (MI.isVariadic() || OpNo >= Desc.getNumOperands() || 395 Desc.OpInfo[OpNo].RegClass == -1) 396 return MRI.getRegClass(MI.getOperand(OpNo).getReg()); 397 398 unsigned RCID = Desc.OpInfo[OpNo].RegClass; 399 return RI.getRegClass(RCID); 400} 401 402bool SIInstrInfo::canReadVGPR(const MachineInstr &MI, unsigned OpNo) const { 403 switch (MI.getOpcode()) { 404 case AMDGPU::COPY: 405 case AMDGPU::REG_SEQUENCE: 406 return RI.hasVGPRs(getOpRegClass(MI, 0)); 407 default: 408 return RI.hasVGPRs(getOpRegClass(MI, OpNo)); 409 } 410} 411 412void SIInstrInfo::legalizeOpWithMove(MachineInstr *MI, unsigned OpIdx) const { 413 MachineBasicBlock::iterator I = MI; 414 MachineOperand &MO = MI->getOperand(OpIdx); 415 MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo(); 416 unsigned RCID = get(MI->getOpcode()).OpInfo[OpIdx].RegClass; 417 const TargetRegisterClass *RC = RI.getRegClass(RCID); 418 unsigned Opcode = AMDGPU::V_MOV_B32_e32; 419 if (MO.isReg()) { 420 Opcode = AMDGPU::COPY; 421 } else if (RI.isSGPRClass(RC)) { 422 Opcode = AMDGPU::S_MOV_B32; 423 } 424 425 unsigned Reg = MRI.createVirtualRegister(RI.getRegClass(RCID)); 426 BuildMI(*MI->getParent(), I, MI->getParent()->findDebugLoc(I), get(Opcode), 427 Reg).addOperand(MO); 428 MO.ChangeToRegister(Reg, false); 429} 430 431void SIInstrInfo::legalizeOperands(MachineInstr *MI) const { 432 MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo(); 433 int Src0Idx = AMDGPU::getNamedOperandIdx(MI->getOpcode(), 434 AMDGPU::OpName::src0); 435 int Src1Idx = AMDGPU::getNamedOperandIdx(MI->getOpcode(), 436 AMDGPU::OpName::src1); 437 int Src2Idx = AMDGPU::getNamedOperandIdx(MI->getOpcode(), 438 AMDGPU::OpName::src2); 439 440 // Legalize VOP2 441 if (isVOP2(MI->getOpcode()) && Src1Idx != -1) { 442 MachineOperand &Src1 = MI->getOperand(Src1Idx); 443 // Legalize VOP2 instructions where src1 is not a VGPR. 444 if (Src1.isImm() || Src1.isFPImm() || 445 (Src1.isReg() && RI.isSGPRClass(MRI.getRegClass(Src1.getReg())))) { 446 if (MI->isCommutable()) { 447 if (commuteInstruction(MI)) 448 return; 449 } 450 legalizeOpWithMove(MI, Src1Idx); 451 } 452 } 453 454 // Legalize VOP3 455 if (isVOP3(MI->getOpcode())) { 456 int VOP3Idx[3] = {Src0Idx, Src1Idx, Src2Idx}; 457 unsigned SGPRReg = AMDGPU::NoRegister; 458 for (unsigned i = 0; i < 3; ++i) { 459 int Idx = VOP3Idx[i]; 460 if (Idx == -1) 461 continue; 462 MachineOperand &MO = MI->getOperand(Idx); 463 464 if (MO.isReg()) { 465 if (!RI.isSGPRClass(MRI.getRegClass(MO.getReg()))) 466 continue; // VGPRs are legal 467 468 if (SGPRReg == AMDGPU::NoRegister || SGPRReg == MO.getReg()) { 469 SGPRReg = MO.getReg(); 470 // We can use one SGPR in each VOP3 instruction. 471 continue; 472 } 473 } else if (!isLiteralConstant(MO)) { 474 // If it is not a register and not a literal constant, then it must be 475 // an inline constant which is always legal. 476 continue; 477 } 478 // If we make it this far, then the operand is not legal and we must 479 // legalize it. 480 legalizeOpWithMove(MI, Idx); 481 } 482 } 483 484 // Legalize REG_SEQUENCE 485 // The register class of the operands much be the same type as the register 486 // class of the output. 487 if (MI->getOpcode() == AMDGPU::REG_SEQUENCE) { 488 const TargetRegisterClass *RC = NULL, *SRC = NULL, *VRC = NULL; 489 for (unsigned i = 1, e = MI->getNumOperands(); i != e; i+=2) { 490 if (!MI->getOperand(i).isReg() || 491 !TargetRegisterInfo::isVirtualRegister(MI->getOperand(i).getReg())) 492 continue; 493 const TargetRegisterClass *OpRC = 494 MRI.getRegClass(MI->getOperand(i).getReg()); 495 if (RI.hasVGPRs(OpRC)) { 496 VRC = OpRC; 497 } else { 498 SRC = OpRC; 499 } 500 } 501 502 // If any of the operands are VGPR registers, then they all most be 503 // otherwise we will create illegal VGPR->SGPR copies when legalizing 504 // them. 505 if (VRC || !RI.isSGPRClass(getOpRegClass(*MI, 0))) { 506 if (!VRC) { 507 assert(SRC); 508 VRC = RI.getEquivalentVGPRClass(SRC); 509 } 510 RC = VRC; 511 } else { 512 RC = SRC; 513 } 514 515 // Update all the operands so they have the same type. 516 for (unsigned i = 1, e = MI->getNumOperands(); i != e; i+=2) { 517 if (!MI->getOperand(i).isReg() || 518 !TargetRegisterInfo::isVirtualRegister(MI->getOperand(i).getReg())) 519 continue; 520 unsigned DstReg = MRI.createVirtualRegister(RC); 521 BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), 522 get(AMDGPU::COPY), DstReg) 523 .addOperand(MI->getOperand(i)); 524 MI->getOperand(i).setReg(DstReg); 525 } 526 } 527} 528 529void SIInstrInfo::moveToVALU(MachineInstr &TopInst) const { 530 SmallVector<MachineInstr *, 128> Worklist; 531 Worklist.push_back(&TopInst); 532 533 while (!Worklist.empty()) { 534 MachineInstr *Inst = Worklist.pop_back_val(); 535 unsigned NewOpcode = getVALUOp(*Inst); 536 if (NewOpcode == AMDGPU::INSTRUCTION_LIST_END) 537 continue; 538 539 MachineRegisterInfo &MRI = Inst->getParent()->getParent()->getRegInfo(); 540 541 // Use the new VALU Opcode. 542 const MCInstrDesc &NewDesc = get(NewOpcode); 543 Inst->setDesc(NewDesc); 544 545 // Add the implict and explicit register definitions. 546 if (NewDesc.ImplicitUses) { 547 for (unsigned i = 0; NewDesc.ImplicitUses[i]; ++i) { 548 Inst->addOperand(MachineOperand::CreateReg(NewDesc.ImplicitUses[i], 549 false, true)); 550 } 551 } 552 553 if (NewDesc.ImplicitDefs) { 554 for (unsigned i = 0; NewDesc.ImplicitDefs[i]; ++i) { 555 Inst->addOperand(MachineOperand::CreateReg(NewDesc.ImplicitDefs[i], 556 true, true)); 557 } 558 } 559 560 legalizeOperands(Inst); 561 562 // Update the destination register class. 563 const TargetRegisterClass *NewDstRC = getOpRegClass(*Inst, 0); 564 565 switch (Inst->getOpcode()) { 566 // For target instructions, getOpRegClass just returns the virtual 567 // register class associated with the operand, so we need to find an 568 // equivalent VGPR register class in order to move the instruction to the 569 // VALU. 570 case AMDGPU::COPY: 571 case AMDGPU::PHI: 572 case AMDGPU::REG_SEQUENCE: 573 if (RI.hasVGPRs(NewDstRC)) 574 continue; 575 NewDstRC = RI.getEquivalentVGPRClass(NewDstRC); 576 if (!NewDstRC) 577 continue; 578 break; 579 default: 580 break; 581 } 582 583 unsigned DstReg = Inst->getOperand(0).getReg(); 584 unsigned NewDstReg = MRI.createVirtualRegister(NewDstRC); 585 MRI.replaceRegWith(DstReg, NewDstReg); 586 587 for (MachineRegisterInfo::use_iterator I = MRI.use_begin(NewDstReg), 588 E = MRI.use_end(); I != E; ++I) { 589 MachineInstr &UseMI = *I; 590 if (!canReadVGPR(UseMI, I.getOperandNo())) { 591 Worklist.push_back(&UseMI); 592 } 593 } 594 } 595} 596 597//===----------------------------------------------------------------------===// 598// Indirect addressing callbacks 599//===----------------------------------------------------------------------===// 600 601unsigned SIInstrInfo::calculateIndirectAddress(unsigned RegIndex, 602 unsigned Channel) const { 603 assert(Channel == 0); 604 return RegIndex; 605} 606 607const TargetRegisterClass *SIInstrInfo::getIndirectAddrRegClass() const { 608 return &AMDGPU::VReg_32RegClass; 609} 610 611MachineInstrBuilder SIInstrInfo::buildIndirectWrite( 612 MachineBasicBlock *MBB, 613 MachineBasicBlock::iterator I, 614 unsigned ValueReg, 615 unsigned Address, unsigned OffsetReg) const { 616 const DebugLoc &DL = MBB->findDebugLoc(I); 617 unsigned IndirectBaseReg = AMDGPU::VReg_32RegClass.getRegister( 618 getIndirectIndexBegin(*MBB->getParent())); 619 620 return BuildMI(*MBB, I, DL, get(AMDGPU::SI_INDIRECT_DST_V1)) 621 .addReg(IndirectBaseReg, RegState::Define) 622 .addOperand(I->getOperand(0)) 623 .addReg(IndirectBaseReg) 624 .addReg(OffsetReg) 625 .addImm(0) 626 .addReg(ValueReg); 627} 628 629MachineInstrBuilder SIInstrInfo::buildIndirectRead( 630 MachineBasicBlock *MBB, 631 MachineBasicBlock::iterator I, 632 unsigned ValueReg, 633 unsigned Address, unsigned OffsetReg) const { 634 const DebugLoc &DL = MBB->findDebugLoc(I); 635 unsigned IndirectBaseReg = AMDGPU::VReg_32RegClass.getRegister( 636 getIndirectIndexBegin(*MBB->getParent())); 637 638 return BuildMI(*MBB, I, DL, get(AMDGPU::SI_INDIRECT_SRC)) 639 .addOperand(I->getOperand(0)) 640 .addOperand(I->getOperand(1)) 641 .addReg(IndirectBaseReg) 642 .addReg(OffsetReg) 643 .addImm(0); 644 645} 646 647void SIInstrInfo::reserveIndirectRegisters(BitVector &Reserved, 648 const MachineFunction &MF) const { 649 int End = getIndirectIndexEnd(MF); 650 int Begin = getIndirectIndexBegin(MF); 651 652 if (End == -1) 653 return; 654 655 656 for (int Index = Begin; Index <= End; ++Index) 657 Reserved.set(AMDGPU::VReg_32RegClass.getRegister(Index)); 658 659 for (int Index = std::max(0, Index - 1); Index <= End; ++Index) 660 Reserved.set(AMDGPU::VReg_64RegClass.getRegister(Index)); 661 662 for (int Index = std::max(0, Index - 2); Index <= End; ++Index) 663 Reserved.set(AMDGPU::VReg_96RegClass.getRegister(Index)); 664 665 for (int Index = std::max(0, Index - 3); Index <= End; ++Index) 666 Reserved.set(AMDGPU::VReg_128RegClass.getRegister(Index)); 667 668 for (int Index = std::max(0, Index - 7); Index <= End; ++Index) 669 Reserved.set(AMDGPU::VReg_256RegClass.getRegister(Index)); 670 671 for (int Index = std::max(0, Index - 15); Index <= End; ++Index) 672 Reserved.set(AMDGPU::VReg_512RegClass.getRegister(Index)); 673} 674