diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp | 351 |
1 files changed, 209 insertions, 142 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp index 0e4005627e02..ab3ce980c3f6 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp @@ -58,7 +58,7 @@ /// /// We avoid trying to solve this problem in RegBankSelect. Any VALU G_* /// operation should have its source operands all mapped to VGPRs (except for -/// VCC), inserting copies from any SGPR operands. This the most trival legal +/// VCC), inserting copies from any SGPR operands. This the most trivial legal /// mapping. Anything beyond the simplest 1:1 instruction selection would be too /// complicated to solve here. Every optimization pattern or instruction /// selected to multiple outputs would have to enforce this rule, and there @@ -118,7 +118,7 @@ public: Opc == AMDGPU::G_SEXT) { // LegalizerHelper wants to use the basic legalization artifacts when // widening etc. We don't handle selection with vcc in artifact sources, - // so we need to use a sslect instead to handle these properly. + // so we need to use a select instead to handle these properly. Register DstReg = MI.getOperand(0).getReg(); Register SrcReg = MI.getOperand(1).getReg(); const RegisterBank *SrcBank = RBI.getRegBank(SrcReg, MRI, *RBI.TRI); @@ -282,7 +282,7 @@ AMDGPURegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC, // VCC-like use. if (TRI->isSGPRClass(&RC)) { // FIXME: This probably came from a copy from a physical register, which - // should be inferrrable from the copied to-type. We don't have many boolean + // should be inferable from the copied to-type. We don't have many boolean // physical register constraints so just assume a normal SGPR for now. if (!Ty.isValid()) return AMDGPU::SGPRRegBank; @@ -734,23 +734,6 @@ bool AMDGPURegisterBankInfo::executeInWaterfallLoop( const int OrigRangeSize = std::distance(Range.begin(), Range.end()); #endif - for (MachineInstr &MI : Range) { - for (MachineOperand &Def : MI.defs()) { - if (MRI.use_nodbg_empty(Def.getReg())) - continue; - - LLT ResTy = MRI.getType(Def.getReg()); - const RegisterBank *DefBank = getRegBank(Def.getReg(), MRI, *TRI); - ResultRegs.push_back(Def.getReg()); - Register InitReg = B.buildUndef(ResTy).getReg(0); - Register PhiReg = MRI.createGenericVirtualRegister(ResTy); - InitResultRegs.push_back(InitReg); - PhiRegs.push_back(PhiReg); - MRI.setRegBank(PhiReg, *DefBank); - MRI.setRegBank(InitReg, *DefBank); - } - } - Register SaveExecReg = MRI.createVirtualRegister(WaveRC); Register InitSaveExecReg = MRI.createVirtualRegister(WaveRC); @@ -894,23 +877,26 @@ bool AMDGPURegisterBankInfo::executeInWaterfallLoop( bool Is64 = OpSize % 64 == 0; - LLT UnmergeTy = OpSize % 64 == 0 ? LLT::scalar(64) : LLT::scalar(32); - unsigned CmpOp = OpSize % 64 == 0 ? AMDGPU::V_CMP_EQ_U64_e64 - : AMDGPU::V_CMP_EQ_U32_e64; - - // The compares can be done as 64-bit, but the extract needs to be done - // in 32-bit pieces. + unsigned UnmergeTySize = Is64 ? 64 : 32; + unsigned CmpOp = + Is64 ? AMDGPU::V_CMP_EQ_U64_e64 : AMDGPU::V_CMP_EQ_U32_e64; // Insert the unmerge before the loop. B.setMBB(MBB); - auto Unmerge = B.buildUnmerge(UnmergeTy, OpReg); + unsigned NumPieces = OpSize / UnmergeTySize; + SmallVector<Register, 8> UnmergePieces; + if (NumPieces == 1) { + UnmergePieces.push_back(OpReg); + } else { + LLT UnmergeTy = LLT::scalar(UnmergeTySize); + MachineInstrBuilder Unmerge = B.buildUnmerge(UnmergeTy, OpReg); + for (unsigned PieceIdx = 0; PieceIdx != NumPieces; ++PieceIdx) + UnmergePieces.push_back(Unmerge.getReg(PieceIdx)); + } B.setInstr(*I); - unsigned NumPieces = Unmerge->getNumOperands() - 1; - for (unsigned PieceIdx = 0; PieceIdx != NumPieces; ++PieceIdx) { - Register UnmergePiece = Unmerge.getReg(PieceIdx); - + for (Register UnmergePiece : UnmergePieces) { Register CurrentLaneOpReg; if (Is64) { Register CurrentLaneOpRegLo = MRI.createGenericVirtualRegister(S32); @@ -985,12 +971,14 @@ bool AMDGPURegisterBankInfo::executeInWaterfallLoop( if (OpTy.isVector()) { auto Merge = B.buildBuildVector(OpTy, ReadlanePieces); Op.setReg(Merge.getReg(0)); - } else { + MRI.setRegBank(Op.getReg(), AMDGPU::SGPRRegBank); + } else if (ReadlanePieces.size() > 1) { auto Merge = B.buildMerge(OpTy, ReadlanePieces); Op.setReg(Merge.getReg(0)); + MRI.setRegBank(Op.getReg(), AMDGPU::SGPRRegBank); + } else { + Op.setReg(ReadlanePieces[0]); } - - MRI.setRegBank(Op.getReg(), AMDGPU::SGPRRegBank); } // Make sure we don't re-process this register again. @@ -998,8 +986,6 @@ bool AMDGPURegisterBankInfo::executeInWaterfallLoop( } } - B.setInsertPt(*LoopBB, LoopBB->end()); - // Update EXEC, save the original EXEC value to VCC. B.buildInstr(AndSaveExecOpc) .addDef(NewExec) @@ -1007,6 +993,8 @@ bool AMDGPURegisterBankInfo::executeInWaterfallLoop( MRI.setSimpleHint(NewExec, CondReg); + B.setInsertPt(*LoopBB, LoopBB->end()); + // Update EXEC, switch all done bits to 0 and all todo bits to 1. B.buildInstr(XorTermOpc) .addDef(ExecReg) @@ -1017,8 +1005,7 @@ bool AMDGPURegisterBankInfo::executeInWaterfallLoop( // s_cbranch_scc0? // Loop back to V_READFIRSTLANE_B32 if there are still variants to cover. - B.buildInstr(AMDGPU::S_CBRANCH_EXECNZ) - .addMBB(LoopBB); + B.buildInstr(AMDGPU::SI_WATERFALL_LOOP).addMBB(LoopBB); // Save the EXEC mask before the loop. BuildMI(MBB, MBB.end(), DL, TII->get(MovTermOpc), SaveExecReg) @@ -1336,7 +1323,7 @@ static unsigned setBufferOffsets(MachineIRBuilder &B, const LLT S32 = LLT::scalar(32); MachineRegisterInfo *MRI = B.getMRI(); - if (Optional<int64_t> Imm = getConstantVRegSExtVal(CombinedOffset, *MRI)) { + if (Optional<int64_t> Imm = getIConstantVRegSExtVal(CombinedOffset, *MRI)) { uint32_t SOffset, ImmOffset; if (AMDGPU::splitMUBUFOffset(*Imm, SOffset, ImmOffset, &RBI.Subtarget, Alignment)) { @@ -1430,7 +1417,7 @@ bool AMDGPURegisterBankInfo::applyMappingSBufferLoad( OffsetBank == &AMDGPU::SGPRRegBank) return true; // Legal mapping - // FIXME: 96-bit case was widened during legalize. We neeed to narrow it back + // FIXME: 96-bit case was widened during legalize. We need to narrow it back // here but don't have an MMO. unsigned LoadSize = Ty.getSizeInBits(); @@ -1455,7 +1442,7 @@ bool AMDGPURegisterBankInfo::applyMappingSBufferLoad( VOffset, SOffset, ImmOffset, Alignment); // TODO: 96-bit loads were widened to 128-bit results. Shrink the result if we - // can, but we neeed to track an MMO for that. + // can, but we need to track an MMO for that. const unsigned MemSize = (Ty.getSizeInBits() + 7) / 8; const Align MemAlign(4); // FIXME: ABI type alignment? MachineMemOperand *BaseMMO = MF.getMachineMemOperand( @@ -1569,7 +1556,7 @@ bool AMDGPURegisterBankInfo::applyMappingBFE(const OperandsMapper &OpdMapper, // A 64-bit bitfield extract uses the 32-bit bitfield extract instructions // if the width is a constant. - if (auto ConstWidth = getConstantVRegValWithLookThrough(WidthReg, MRI)) { + if (auto ConstWidth = getIConstantVRegValWithLookThrough(WidthReg, MRI)) { // Use the 32-bit bitfield extract instruction if the width is a constant. // Depending on the width size, use either the low or high 32-bits. auto Zero = B.buildConstant(S32, 0); @@ -1775,97 +1762,6 @@ AMDGPURegisterBankInfo::splitBufferOffsets(MachineIRBuilder &B, return {BaseReg, C1}; } -static bool isZero(Register Reg, MachineRegisterInfo &MRI) { - int64_t C; - return mi_match(Reg, MRI, m_ICst(C)) && C == 0; -} - -static unsigned extractCPol(unsigned CachePolicy) { - return CachePolicy & AMDGPU::CPol::ALL; -} - -static unsigned extractSWZ(unsigned CachePolicy) { - return (CachePolicy >> 3) & 1; -} - - -MachineInstr * -AMDGPURegisterBankInfo::selectStoreIntrinsic(MachineIRBuilder &B, - MachineInstr &MI) const { - MachineRegisterInfo &MRI = *B.getMRI(); - executeInWaterfallLoop(B, MI, MRI, {2, 4}); - - // FIXME: DAG lowering brokenly changes opcode based on FP vs. integer. - - Register VData = MI.getOperand(1).getReg(); - LLT Ty = MRI.getType(VData); - - int EltSize = Ty.getScalarSizeInBits(); - int Size = Ty.getSizeInBits(); - - // FIXME: Broken integer truncstore. - if (EltSize != 32) - report_fatal_error("unhandled intrinsic store"); - - // FIXME: Verifier should enforce 1 MMO for these intrinsics. - const int MemSize = (*MI.memoperands_begin())->getSize(); - - - Register RSrc = MI.getOperand(2).getReg(); - Register VOffset = MI.getOperand(3).getReg(); - Register SOffset = MI.getOperand(4).getReg(); - unsigned CachePolicy = MI.getOperand(5).getImm(); - - unsigned ImmOffset; - std::tie(VOffset, ImmOffset) = splitBufferOffsets(B, VOffset); - - const bool Offen = !isZero(VOffset, MRI); - - unsigned Opc = AMDGPU::BUFFER_STORE_DWORD_OFFEN_exact; - switch (8 * MemSize) { - case 8: - Opc = Offen ? AMDGPU::BUFFER_STORE_BYTE_OFFEN_exact : - AMDGPU::BUFFER_STORE_BYTE_OFFSET_exact; - break; - case 16: - Opc = Offen ? AMDGPU::BUFFER_STORE_SHORT_OFFEN_exact : - AMDGPU::BUFFER_STORE_SHORT_OFFSET_exact; - break; - default: - Opc = Offen ? AMDGPU::BUFFER_STORE_DWORD_OFFEN_exact : - AMDGPU::BUFFER_STORE_DWORD_OFFSET_exact; - if (Size > 32) - Opc = AMDGPU::getMUBUFOpcode(Opc, Size / 32); - break; - } - - - // Set the insertion point back to the instruction in case it was moved into a - // loop. - B.setInstr(MI); - - MachineInstrBuilder MIB = B.buildInstr(Opc) - .addUse(VData); - - if (Offen) - MIB.addUse(VOffset); - - MIB.addUse(RSrc) - .addUse(SOffset) - .addImm(ImmOffset) - .addImm(extractCPol(CachePolicy)) - .addImm(0) // tfe: FIXME: Remove from inst - .addImm(extractSWZ(CachePolicy)) - .cloneMemRefs(MI); - - // FIXME: We need a way to report failure from applyMappingImpl. - // Insert constrain copies before inserting the loop. - if (!constrainSelectedInstRegOperands(*MIB, *TII, *TRI, *this)) - report_fatal_error("failed to constrain selected store intrinsic"); - - return MIB; -} - bool AMDGPURegisterBankInfo::buildVCopy(MachineIRBuilder &B, Register DstReg, Register SrcReg) const { MachineRegisterInfo &MRI = *B.getMRI(); @@ -2153,7 +2049,7 @@ void AMDGPURegisterBankInfo::applyMappingImpl( // The standard handling only considers the result register bank for // phis. For VCC, blindly inserting a copy when the phi is lowered will // produce an invalid copy. We can only copy with some kind of compare to - // get a vector boolean result. Insert a regitser bank copy that will be + // get a vector boolean result. Insert a register bank copy that will be // correctly lowered to a compare. MachineIRBuilder B(*MI.getParent()->getParent()); @@ -2491,9 +2387,7 @@ void AMDGPURegisterBankInfo::applyMappingImpl( return; } case AMDGPU::G_CTPOP: - case AMDGPU::G_BITREVERSE: - case AMDGPU::G_CTLZ_ZERO_UNDEF: - case AMDGPU::G_CTTZ_ZERO_UNDEF: { + case AMDGPU::G_BITREVERSE: { const RegisterBank *DstBank = OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; if (DstBank == &AMDGPU::SGPRRegBank) @@ -2515,6 +2409,48 @@ void AMDGPURegisterBankInfo::applyMappingImpl( llvm_unreachable("narrowScalar should have succeeded"); return; } + case AMDGPU::G_AMDGPU_FFBH_U32: + case AMDGPU::G_AMDGPU_FFBL_B32: + case AMDGPU::G_CTLZ_ZERO_UNDEF: + case AMDGPU::G_CTTZ_ZERO_UNDEF: { + const RegisterBank *DstBank = + OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; + if (DstBank == &AMDGPU::SGPRRegBank) + break; + + Register SrcReg = MI.getOperand(1).getReg(); + const LLT S32 = LLT::scalar(32); + LLT Ty = MRI.getType(SrcReg); + if (Ty == S32) + break; + + // We can narrow this more efficiently than Helper can by using ffbh/ffbl + // which return -1 when the input is zero: + // (ctlz_zero_undef hi:lo) -> (umin (ffbh hi), (add (ffbh lo), 32)) + // (cttz_zero_undef hi:lo) -> (umin (add (ffbl hi), 32), (ffbl lo)) + // (ffbh hi:lo) -> (umin (ffbh hi), (uaddsat (ffbh lo), 32)) + // (ffbl hi:lo) -> (umin (uaddsat (ffbh hi), 32), (ffbh lo)) + ApplyRegBankMapping ApplyVALU(*this, MRI, &AMDGPU::VGPRRegBank); + MachineIRBuilder B(MI, ApplyVALU); + SmallVector<Register, 2> SrcRegs(OpdMapper.getVRegs(1)); + unsigned NewOpc = Opc == AMDGPU::G_CTLZ_ZERO_UNDEF + ? (unsigned)AMDGPU::G_AMDGPU_FFBH_U32 + : Opc == AMDGPU::G_CTTZ_ZERO_UNDEF + ? (unsigned)AMDGPU::G_AMDGPU_FFBL_B32 + : Opc; + unsigned Idx = NewOpc == AMDGPU::G_AMDGPU_FFBH_U32; + auto X = B.buildInstr(NewOpc, {S32}, {SrcRegs[Idx]}); + auto Y = B.buildInstr(NewOpc, {S32}, {SrcRegs[Idx ^ 1]}); + unsigned AddOpc = + Opc == AMDGPU::G_CTLZ_ZERO_UNDEF || Opc == AMDGPU::G_CTTZ_ZERO_UNDEF + ? AMDGPU::G_ADD + : AMDGPU::G_UADDSAT; + Y = B.buildInstr(AddOpc, {S32}, {Y, B.buildConstant(S32, 32)}); + Register DstReg = MI.getOperand(0).getReg(); + B.buildUMin(DstReg, X, Y); + MI.eraseFromParent(); + return; + } case AMDGPU::G_SEXT: case AMDGPU::G_ZEXT: case AMDGPU::G_ANYEXT: { @@ -3034,6 +2970,7 @@ void AMDGPURegisterBankInfo::applyMappingImpl( } case AMDGPU::G_AMDGPU_INTRIN_BVH_INTERSECT_RAY: { unsigned N = MI.getNumExplicitOperands() - 2; + applyDefaultMapping(OpdMapper); executeInWaterfallLoop(MI, MRI, { N }); return; } @@ -3095,6 +3032,101 @@ void AMDGPURegisterBankInfo::applyMappingImpl( } break; } + case AMDGPU::G_SI_CALL: { + // Use a set to avoid extra readfirstlanes in the case where multiple + // operands are the same register. + SmallSet<Register, 4> SGPROperandRegs; + + if (!collectWaterfallOperands(SGPROperandRegs, MI, MRI, {1})) + break; + + // Move all copies to physical SGPRs that are used by the call instruction + // into the loop block. Start searching for these copies until the + // ADJCALLSTACKUP. + unsigned FrameSetupOpcode = AMDGPU::ADJCALLSTACKUP; + unsigned FrameDestroyOpcode = AMDGPU::ADJCALLSTACKDOWN; + + // Move all non-copies before the copies, so that a complete range can be + // moved into the waterfall loop. + SmallVector<MachineInstr *, 4> NonCopyInstrs; + // Count of NonCopyInstrs found until the current LastCopy. + unsigned NonCopyInstrsLen = 0; + MachineBasicBlock::iterator Start(&MI); + MachineBasicBlock::iterator LastCopy = Start; + MachineBasicBlock *MBB = MI.getParent(); + const SIMachineFunctionInfo *Info = + MBB->getParent()->getInfo<SIMachineFunctionInfo>(); + while (Start->getOpcode() != FrameSetupOpcode) { + --Start; + bool IsCopy = false; + if (Start->getOpcode() == AMDGPU::COPY) { + auto &Dst = Start->getOperand(0); + if (Dst.isReg()) { + Register Reg = Dst.getReg(); + if (Reg.isPhysical() && MI.readsRegister(Reg, TRI)) { + IsCopy = true; + } else { + // Also move the copy from the scratch rsrc descriptor into the loop + // to allow it to be optimized away. + auto &Src = Start->getOperand(1); + if (Src.isReg()) { + Reg = Src.getReg(); + IsCopy = Info->getScratchRSrcReg() == Reg; + } + } + } + } + + if (IsCopy) { + LastCopy = Start; + NonCopyInstrsLen = NonCopyInstrs.size(); + } else { + NonCopyInstrs.push_back(&*Start); + } + } + NonCopyInstrs.resize(NonCopyInstrsLen); + + for (auto *NonCopy : reverse(NonCopyInstrs)) { + MBB->splice(LastCopy, MBB, NonCopy->getIterator()); + } + Start = LastCopy; + + // Do the same for copies after the loop + NonCopyInstrs.clear(); + NonCopyInstrsLen = 0; + MachineBasicBlock::iterator End(&MI); + LastCopy = End; + while (End->getOpcode() != FrameDestroyOpcode) { + ++End; + bool IsCopy = false; + if (End->getOpcode() == AMDGPU::COPY) { + auto &Src = End->getOperand(1); + if (Src.isReg()) { + Register Reg = Src.getReg(); + IsCopy = Reg.isPhysical() && MI.modifiesRegister(Reg, TRI); + } + } + + if (IsCopy) { + LastCopy = End; + NonCopyInstrsLen = NonCopyInstrs.size(); + } else { + NonCopyInstrs.push_back(&*End); + } + } + NonCopyInstrs.resize(NonCopyInstrsLen); + + End = LastCopy; + ++LastCopy; + for (auto *NonCopy : reverse(NonCopyInstrs)) { + MBB->splice(LastCopy, MBB, NonCopy->getIterator()); + } + + ++End; + MachineIRBuilder B(*Start); + executeInWaterfallLoop(B, make_range(Start, End), SGPROperandRegs, MRI); + break; + } case AMDGPU::G_LOAD: case AMDGPU::G_ZEXTLOAD: case AMDGPU::G_SEXTLOAD: { @@ -3290,7 +3322,7 @@ AMDGPURegisterBankInfo::getImageMapping(const MachineRegisterInfo &MRI, return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping), NumOps); } -/// Return the mapping for a pointer arugment. +/// Return the mapping for a pointer argument. const RegisterBankInfo::ValueMapping * AMDGPURegisterBankInfo::getValueMappingForPtr(const MachineRegisterInfo &MRI, Register PtrReg) const { @@ -3620,7 +3652,6 @@ AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { case AMDGPU::G_INTRINSIC_TRUNC: case AMDGPU::G_BSWAP: // TODO: Somehow expand for scalar? case AMDGPU::G_FSHR: // TODO: Expand for scalar - case AMDGPU::G_AMDGPU_FFBH_U32: case AMDGPU::G_AMDGPU_FMIN_LEGACY: case AMDGPU::G_AMDGPU_FMAX_LEGACY: case AMDGPU::G_AMDGPU_RCP_IFLAG: @@ -3726,8 +3757,16 @@ AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { OpdsMapping[0] = OpdsMapping[1] = AMDGPU::getValueMapping(BankID, Size); break; } + case AMDGPU::G_AMDGPU_FFBH_U32: + case AMDGPU::G_AMDGPU_FFBL_B32: case AMDGPU::G_CTLZ_ZERO_UNDEF: - case AMDGPU::G_CTTZ_ZERO_UNDEF: + case AMDGPU::G_CTTZ_ZERO_UNDEF: { + unsigned Size = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); + unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI); + OpdsMapping[0] = AMDGPU::getValueMapping(BankID, 32); + OpdsMapping[1] = AMDGPU::getValueMappingSGPR64Only(BankID, Size); + break; + } case AMDGPU::G_CTPOP: { unsigned Size = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI); @@ -4033,6 +4072,8 @@ AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { case Intrinsic::amdgcn_mbcnt_hi: case Intrinsic::amdgcn_mul_u24: case Intrinsic::amdgcn_mul_i24: + case Intrinsic::amdgcn_mulhi_u24: + case Intrinsic::amdgcn_mulhi_i24: case Intrinsic::amdgcn_lerp: case Intrinsic::amdgcn_sad_u8: case Intrinsic::amdgcn_msad_u8: @@ -4254,8 +4295,17 @@ AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { unsigned N = MI.getNumExplicitOperands() - 2; OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 128); OpdsMapping[N] = getSGPROpMapping(MI.getOperand(N).getReg(), MRI, *TRI); - for (unsigned I = 2; I < N; ++I) - OpdsMapping[I] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); + if (N == 3) { + // Sequential form: all operands combined into VGPR256/VGPR512 + unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); + if (Size > 256) + Size = 512; + OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); + } else { + // NSA form + for (unsigned I = 2; I < N; ++I) + OpdsMapping[I] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); + } break; } case AMDGPU::G_INTRINSIC_W_SIDE_EFFECTS: { @@ -4447,6 +4497,23 @@ AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { break; } + case AMDGPU::G_SI_CALL: { + OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64); + // Lie and claim everything is legal, even though some need to be + // SGPRs. applyMapping will have to deal with it as a waterfall loop. + OpdsMapping[1] = getSGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); + + // Allow anything for implicit arguments + for (unsigned I = 4; I < MI.getNumOperands(); ++I) { + if (MI.getOperand(I).isReg()) { + Register Reg = MI.getOperand(I).getReg(); + auto OpBank = getRegBankID(Reg, MRI); + unsigned Size = getSizeInBits(Reg, MRI, *TRI); + OpdsMapping[I] = AMDGPU::getValueMapping(OpBank, Size); + } + } + break; + } case AMDGPU::G_LOAD: case AMDGPU::G_ZEXTLOAD: case AMDGPU::G_SEXTLOAD: |
