LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU - AMDGPUInstructionSelector.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 259 291 89.0 %
Date: 2018-07-13 00:08:38 Functions: 22 23 95.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- AMDGPUInstructionSelector.cpp ----------------------------*- C++ -*-==//
       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             : /// \file
      10             : /// This file implements the targeting of the InstructionSelector class for
      11             : /// AMDGPU.
      12             : /// \todo This should be generated by TableGen.
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #include "AMDGPUInstructionSelector.h"
      16             : #include "AMDGPUInstrInfo.h"
      17             : #include "AMDGPURegisterBankInfo.h"
      18             : #include "AMDGPURegisterInfo.h"
      19             : #include "AMDGPUSubtarget.h"
      20             : #include "AMDGPUTargetMachine.h"
      21             : #include "SIMachineFunctionInfo.h"
      22             : #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
      23             : #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
      24             : #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
      25             : #include "llvm/CodeGen/GlobalISel/Utils.h"
      26             : #include "llvm/CodeGen/MachineBasicBlock.h"
      27             : #include "llvm/CodeGen/MachineFunction.h"
      28             : #include "llvm/CodeGen/MachineInstr.h"
      29             : #include "llvm/CodeGen/MachineInstrBuilder.h"
      30             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      31             : #include "llvm/IR/Type.h"
      32             : #include "llvm/Support/Debug.h"
      33             : #include "llvm/Support/raw_ostream.h"
      34             : 
      35             : #define DEBUG_TYPE "amdgpu-isel"
      36             : 
      37             : using namespace llvm;
      38             : 
      39             : #define GET_GLOBALISEL_IMPL
      40             : #include "AMDGPUGenGlobalISel.inc"
      41             : #undef GET_GLOBALISEL_IMPL
      42             : 
      43        2271 : AMDGPUInstructionSelector::AMDGPUInstructionSelector(
      44             :     const SISubtarget &STI, const AMDGPURegisterBankInfo &RBI,
      45        2271 :     const AMDGPUTargetMachine &TM)
      46             :     : InstructionSelector(), TII(*STI.getInstrInfo()),
      47             :       TRI(*STI.getRegisterInfo()), RBI(RBI), TM(TM),
      48             :       STI(STI),
      49             :       EnableLateStructurizeCFG(AMDGPUTargetMachine::EnableLateStructurizeCFG),
      50             : #define GET_GLOBALISEL_PREDICATES_INIT
      51             : #include "AMDGPUGenGlobalISel.inc"
      52             : #undef GET_GLOBALISEL_PREDICATES_INIT
      53             : #define GET_GLOBALISEL_TEMPORARIES_INIT
      54             : #include "AMDGPUGenGlobalISel.inc"
      55             : #undef GET_GLOBALISEL_TEMPORARIES_INIT
      56       13626 :       ,AMDGPUASI(STI.getAMDGPUAS())
      57             : {
      58        2271 : }
      59             : 
      60           0 : const char *AMDGPUInstructionSelector::getName() { return DEBUG_TYPE; }
      61             : 
      62         123 : bool AMDGPUInstructionSelector::selectCOPY(MachineInstr &I) const {
      63         123 :   MachineBasicBlock *BB = I.getParent();
      64         123 :   MachineFunction *MF = BB->getParent();
      65         123 :   MachineRegisterInfo &MRI = MF->getRegInfo();
      66         123 :   I.setDesc(TII.get(TargetOpcode::COPY));
      67         615 :   for (const MachineOperand &MO : I.operands()) {
      68         492 :     if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
      69          93 :       continue;
      70             : 
      71             :     const TargetRegisterClass *RC =
      72         153 :             TRI.getConstrainedRegClassForOperand(MO, MRI);
      73         153 :     if (!RC)
      74          82 :       continue;
      75          71 :     RBI.constrainGenericRegister(MO.getReg(), *RC, MRI);
      76             :   }
      77         123 :   return true;
      78             : }
      79             : 
      80             : MachineOperand
      81          36 : AMDGPUInstructionSelector::getSubOperand64(MachineOperand &MO,
      82             :                                            unsigned SubIdx) const {
      83             : 
      84          36 :   MachineInstr *MI = MO.getParent();
      85          36 :   MachineBasicBlock *BB = MO.getParent()->getParent();
      86          36 :   MachineFunction *MF = BB->getParent();
      87          36 :   MachineRegisterInfo &MRI = MF->getRegInfo();
      88          36 :   unsigned DstReg = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass);
      89             : 
      90          36 :   if (MO.isReg()) {
      91          36 :     unsigned ComposedSubIdx = TRI.composeSubRegIndices(MO.getSubReg(), SubIdx);
      92          36 :     unsigned Reg = MO.getReg();
      93         108 :     BuildMI(*BB, MI, MI->getDebugLoc(), TII.get(AMDGPU::COPY), DstReg)
      94          36 :             .addReg(Reg, 0, ComposedSubIdx);
      95             : 
      96             :     return MachineOperand::CreateReg(DstReg, MO.isDef(), MO.isImplicit(),
      97             :                                      MO.isKill(), MO.isDead(), MO.isUndef(),
      98             :                                      MO.isEarlyClobber(), 0, MO.isDebug(),
      99             :                                      MO.isInternalRead());
     100             :   }
     101             : 
     102             :   assert(MO.isImm());
     103             : 
     104           0 :   APInt Imm(64, MO.getImm());
     105             : 
     106           0 :   switch (SubIdx) {
     107           0 :   default:
     108           0 :     llvm_unreachable("do not know to split immediate with this sub index.");
     109           0 :   case AMDGPU::sub0:
     110           0 :     return MachineOperand::CreateImm(Imm.getLoBits(32).getSExtValue());
     111           0 :   case AMDGPU::sub1:
     112           0 :     return MachineOperand::CreateImm(Imm.getHiBits(32).getSExtValue());
     113             :   }
     114             : }
     115             : 
     116           9 : bool AMDGPUInstructionSelector::selectG_ADD(MachineInstr &I) const {
     117           9 :   MachineBasicBlock *BB = I.getParent();
     118           9 :   MachineFunction *MF = BB->getParent();
     119           9 :   MachineRegisterInfo &MRI = MF->getRegInfo();
     120           9 :   unsigned Size = RBI.getSizeInBits(I.getOperand(0).getReg(), MRI, TRI);
     121           9 :   unsigned DstLo = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
     122           9 :   unsigned DstHi = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
     123             : 
     124           9 :   if (Size != 64)
     125             :     return false;
     126             : 
     127             :   DebugLoc DL = I.getDebugLoc();
     128             : 
     129          18 :   MachineOperand Lo1(getSubOperand64(I.getOperand(1), AMDGPU::sub0));
     130          18 :   MachineOperand Lo2(getSubOperand64(I.getOperand(2), AMDGPU::sub0));
     131             : 
     132           9 :   BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_ADD_U32), DstLo)
     133             :           .add(Lo1)
     134             :           .add(Lo2);
     135             : 
     136          18 :   MachineOperand Hi1(getSubOperand64(I.getOperand(1), AMDGPU::sub1));
     137          18 :   MachineOperand Hi2(getSubOperand64(I.getOperand(2), AMDGPU::sub1));
     138             : 
     139           9 :   BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_ADDC_U32), DstHi)
     140             :           .add(Hi1)
     141             :           .add(Hi2);
     142             : 
     143          27 :   BuildMI(*BB, &I, DL, TII.get(AMDGPU::REG_SEQUENCE), I.getOperand(0).getReg())
     144           9 :           .addReg(DstLo)
     145             :           .addImm(AMDGPU::sub0)
     146           9 :           .addReg(DstHi)
     147             :           .addImm(AMDGPU::sub1);
     148             : 
     149          63 :   for (MachineOperand &MO : I.explicit_operands()) {
     150          54 :     if (!MO.isReg() || TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
     151           0 :       continue;
     152          27 :     RBI.constrainGenericRegister(MO.getReg(), AMDGPU::SReg_64RegClass, MRI);
     153             :   }
     154             : 
     155           9 :   I.eraseFromParent();
     156             :   return true;
     157             : }
     158             : 
     159           9 : bool AMDGPUInstructionSelector::selectG_GEP(MachineInstr &I) const {
     160           9 :   return selectG_ADD(I);
     161             : }
     162             : 
     163          20 : bool AMDGPUInstructionSelector::selectG_IMPLICIT_DEF(MachineInstr &I) const {
     164          20 :   MachineBasicBlock *BB = I.getParent();
     165          20 :   MachineFunction *MF = BB->getParent();
     166          20 :   MachineRegisterInfo &MRI = MF->getRegInfo();
     167          20 :   const MachineOperand &MO = I.getOperand(0);
     168             :   const TargetRegisterClass *RC =
     169          20 :       TRI.getConstrainedRegClassForOperand(MO, MRI);
     170          20 :   if (RC)
     171           0 :     RBI.constrainGenericRegister(MO.getReg(), *RC, MRI);
     172          20 :   I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
     173          20 :   return true;
     174             : }
     175             : 
     176          16 : bool AMDGPUInstructionSelector::selectG_INTRINSIC(MachineInstr &I,
     177             :                                           CodeGenCoverage &CoverageInfo) const {
     178          16 :   unsigned IntrinsicID =  I.getOperand(1).getIntrinsicID();
     179             : 
     180          16 :   switch (IntrinsicID) {
     181             :   default:
     182             :     break;
     183           3 :   case Intrinsic::amdgcn_cvt_pkrtz:
     184           3 :     return selectImpl(I, CoverageInfo);
     185             : 
     186          13 :   case Intrinsic::amdgcn_kernarg_segment_ptr: {
     187          13 :     MachineFunction *MF = I.getParent()->getParent();
     188          13 :     MachineRegisterInfo &MRI = MF->getRegInfo();
     189          13 :     const SIMachineFunctionInfo *MFI = MF->getInfo<SIMachineFunctionInfo>();
     190             :     const ArgDescriptor *InputPtrReg;
     191             :     const TargetRegisterClass *RC;
     192             :     const DebugLoc &DL = I.getDebugLoc();
     193             : 
     194             :     std::tie(InputPtrReg, RC)
     195             :       = MFI->getPreloadedValue(AMDGPUFunctionArgInfo::KERNARG_SEGMENT_PTR);
     196          13 :     if (!InputPtrReg)
     197           1 :       report_fatal_error("missing kernarg segment ptr");
     198             : 
     199          48 :     BuildMI(*I.getParent(), &I, DL, TII.get(AMDGPU::COPY))
     200          12 :       .add(I.getOperand(0))
     201          12 :       .addReg(MRI.getLiveInVirtReg(InputPtrReg->getRegister()));
     202          12 :     I.eraseFromParent();
     203             :     return true;
     204             :   }
     205             :   }
     206             :   return false;
     207             : }
     208             : 
     209          53 : bool AMDGPUInstructionSelector::selectG_STORE(MachineInstr &I) const {
     210          53 :   MachineBasicBlock *BB = I.getParent();
     211          53 :   MachineFunction *MF = BB->getParent();
     212          53 :   MachineRegisterInfo &MRI = MF->getRegInfo();
     213             :   DebugLoc DL = I.getDebugLoc();
     214          53 :   unsigned StoreSize = RBI.getSizeInBits(I.getOperand(0).getReg(), MRI, TRI);
     215             :   unsigned Opcode;
     216             : 
     217             :   // FIXME: Select store instruction based on address space
     218          53 :   switch (StoreSize) {
     219             :   default:
     220             :     return false;
     221             :   case 32:
     222             :     Opcode = AMDGPU::FLAT_STORE_DWORD;
     223             :     break;
     224           7 :   case 64:
     225             :     Opcode = AMDGPU::FLAT_STORE_DWORDX2;
     226           7 :     break;
     227           2 :   case 96:
     228             :     Opcode = AMDGPU::FLAT_STORE_DWORDX3;
     229           2 :     break;
     230           2 :   case 128:
     231             :     Opcode = AMDGPU::FLAT_STORE_DWORDX4;
     232           2 :     break;
     233             :   }
     234             : 
     235          53 :   MachineInstr *Flat = BuildMI(*BB, &I, DL, TII.get(Opcode))
     236          53 :           .add(I.getOperand(1))
     237          53 :           .add(I.getOperand(0))
     238             :           .addImm(0)  // offset
     239             :           .addImm(0)  // glc
     240             :           .addImm(0); // slc
     241             : 
     242             : 
     243             :   // Now that we selected an opcode, we need to constrain the register
     244             :   // operands to use appropriate classes.
     245          53 :   bool Ret = constrainSelectedInstRegOperands(*Flat, TII, TRI, RBI);
     246             : 
     247          53 :   I.eraseFromParent();
     248          53 :   return Ret;
     249             : }
     250             : 
     251          25 : bool AMDGPUInstructionSelector::selectG_CONSTANT(MachineInstr &I) const {
     252          25 :   MachineBasicBlock *BB = I.getParent();
     253          25 :   MachineFunction *MF = BB->getParent();
     254          25 :   MachineRegisterInfo &MRI = MF->getRegInfo();
     255          25 :   MachineOperand &ImmOp = I.getOperand(1);
     256             : 
     257             :   // The AMDGPU backend only supports Imm operands and not CImm or FPImm.
     258          25 :   if (ImmOp.isFPImm()) {
     259           8 :     const APInt &Imm = ImmOp.getFPImm()->getValueAPF().bitcastToAPInt();
     260           4 :     ImmOp.ChangeToImmediate(Imm.getZExtValue());
     261          21 :   } else if (ImmOp.isCImm()) {
     262          34 :     ImmOp.ChangeToImmediate(ImmOp.getCImm()->getZExtValue());
     263             :   }
     264             : 
     265          25 :   unsigned DstReg = I.getOperand(0).getReg();
     266             :   unsigned Size;
     267             :   bool IsSgpr;
     268             :   const RegisterBank *RB = MRI.getRegBankOrNull(I.getOperand(0).getReg());
     269           3 :   if (RB) {
     270           3 :     IsSgpr = RB->getID() == AMDGPU::SGPRRegBankID;
     271           3 :     Size = MRI.getType(DstReg).getSizeInBits();
     272             :   } else {
     273          22 :     const TargetRegisterClass *RC = TRI.getRegClassForReg(MRI, DstReg);
     274          22 :     IsSgpr = TRI.isSGPRClass(RC);
     275          22 :     Size = TRI.getRegSizeInBits(*RC);
     276             :   }
     277             : 
     278          25 :   if (Size != 32 && Size != 64)
     279             :     return false;
     280             : 
     281          25 :   unsigned Opcode = IsSgpr ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;
     282          25 :   if (Size == 32) {
     283          12 :     I.setDesc(TII.get(Opcode));
     284          12 :     I.addImplicitDefUseOperands(*MF);
     285          12 :     return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
     286             :   }
     287             : 
     288             :   DebugLoc DL = I.getDebugLoc();
     289          13 :   const TargetRegisterClass *RC = IsSgpr ? &AMDGPU::SReg_32_XM0RegClass :
     290             :                                            &AMDGPU::VGPR_32RegClass;
     291          13 :   unsigned LoReg = MRI.createVirtualRegister(RC);
     292          13 :   unsigned HiReg = MRI.createVirtualRegister(RC);
     293          13 :   const APInt &Imm = APInt(Size, I.getOperand(1).getImm());
     294             : 
     295          13 :   BuildMI(*BB, &I, DL, TII.get(Opcode), LoReg)
     296          39 :           .addImm(Imm.trunc(32).getZExtValue());
     297             : 
     298          13 :   BuildMI(*BB, &I, DL, TII.get(Opcode), HiReg)
     299          39 :           .addImm(Imm.ashr(32).getZExtValue());
     300             : 
     301             :   const MachineInstr *RS =
     302          39 :       BuildMI(*BB, &I, DL, TII.get(AMDGPU::REG_SEQUENCE), DstReg)
     303          13 :               .addReg(LoReg)
     304             :               .addImm(AMDGPU::sub0)
     305          13 :               .addReg(HiReg)
     306          13 :               .addImm(AMDGPU::sub1);
     307             : 
     308             :   // We can't call constrainSelectedInstRegOperands here, because it doesn't
     309             :   // work for target independent opcodes
     310          13 :   I.eraseFromParent();
     311             :   const TargetRegisterClass *DstRC =
     312          13 :       TRI.getConstrainedRegClassForOperand(RS->getOperand(0), MRI);
     313          13 :   if (!DstRC)
     314             :     return true;
     315           2 :   return RBI.constrainGenericRegister(DstReg, *DstRC, MRI);
     316             : }
     317             : 
     318             : static bool isConstant(const MachineInstr &MI) {
     319         102 :   return MI.getOpcode() == TargetOpcode::G_CONSTANT;
     320             : }
     321             : 
     322         105 : void AMDGPUInstructionSelector::getAddrModeInfo(const MachineInstr &Load,
     323             :     const MachineRegisterInfo &MRI, SmallVectorImpl<GEPInfo> &AddrInfo) const {
     324             : 
     325         105 :   const MachineInstr *PtrMI = MRI.getUniqueVRegDef(Load.getOperand(1).getReg());
     326             : 
     327             :   assert(PtrMI);
     328             : 
     329         210 :   if (PtrMI->getOpcode() != TargetOpcode::G_GEP)
     330          54 :     return;
     331             : 
     332          51 :   GEPInfo GEPInfo(*PtrMI);
     333             : 
     334         255 :   for (unsigned i = 1, e = 3; i < e; ++i) {
     335         102 :     const MachineOperand &GEPOp = PtrMI->getOperand(i);
     336         102 :     const MachineInstr *OpDef = MRI.getUniqueVRegDef(GEPOp.getReg());
     337             :     assert(OpDef);
     338         153 :     if (isConstant(*OpDef)) {
     339             :       // FIXME: Is it possible to have multiple Imm parts?  Maybe if we
     340             :       // are lacking other optimizations.
     341             :       assert(GEPInfo.Imm == 0);
     342         102 :       GEPInfo.Imm = OpDef->getOperand(1).getCImm()->getSExtValue();
     343          51 :       continue;
     344             :     }
     345          51 :     const RegisterBank *OpBank = RBI.getRegBank(GEPOp.getReg(), MRI, TRI);
     346          51 :     if (OpBank->getID() == AMDGPU::SGPRRegBankID)
     347          51 :       GEPInfo.SgprParts.push_back(GEPOp.getReg());
     348             :     else
     349           0 :       GEPInfo.VgprParts.push_back(GEPOp.getReg());
     350             :   }
     351             : 
     352          51 :   AddrInfo.push_back(GEPInfo);
     353          51 :   getAddrModeInfo(*PtrMI, MRI, AddrInfo);
     354             : }
     355             : 
     356          51 : static bool isInstrUniform(const MachineInstr &MI) {
     357          51 :   if (!MI.hasOneMemOperand())
     358             :     return false;
     359             : 
     360          51 :   const MachineMemOperand *MMO = *MI.memoperands_begin();
     361             :   const Value *Ptr = MMO->getValue();
     362             : 
     363             :   // UndefValue means this is a load of a kernel input.  These are uniform.
     364             :   // Sometimes LDS instructions have constant pointers.
     365             :   // If Ptr is null, then that means this mem operand contains a
     366             :   // PseudoSourceValue like GOT.
     367          51 :   if (!Ptr || isa<UndefValue>(Ptr) || isa<Argument>(Ptr) ||
     368          51 :       isa<Constant>(Ptr) || isa<GlobalValue>(Ptr))
     369             :     return true;
     370             : 
     371          24 :   if (MMO->getAddrSpace() == AMDGPUAS::CONSTANT_ADDRESS_32BIT)
     372             :     return true;
     373             : 
     374             :   const Instruction *I = dyn_cast<Instruction>(Ptr);
     375          24 :   return I && I->getMetadata("amdgpu.uniform");
     376             : }
     377             : 
     378             : static unsigned getSmrdOpcode(unsigned BaseOpcode, unsigned LoadSize) {
     379             : 
     380          51 :   if (LoadSize == 32)
     381             :     return BaseOpcode;
     382             : 
     383             :   switch (BaseOpcode) {
     384          12 :   case AMDGPU::S_LOAD_DWORD_IMM:
     385          12 :     switch (LoadSize) {
     386             :     case 64:
     387             :       return AMDGPU::S_LOAD_DWORDX2_IMM;
     388           0 :     case 128:
     389             :       return AMDGPU::S_LOAD_DWORDX4_IMM;
     390           0 :     case 256:
     391             :       return AMDGPU::S_LOAD_DWORDX8_IMM;
     392           0 :     case 512:
     393             :       return AMDGPU::S_LOAD_DWORDX16_IMM;
     394             :     }
     395             :     break;
     396           0 :   case AMDGPU::S_LOAD_DWORD_IMM_ci:
     397           0 :     switch (LoadSize) {
     398             :     case 64:
     399             :       return AMDGPU::S_LOAD_DWORDX2_IMM_ci;
     400           0 :     case 128:
     401             :       return AMDGPU::S_LOAD_DWORDX4_IMM_ci;
     402           0 :     case 256:
     403             :       return AMDGPU::S_LOAD_DWORDX8_IMM_ci;
     404           0 :     case 512:
     405             :       return AMDGPU::S_LOAD_DWORDX16_IMM_ci;
     406             :     }
     407             :     break;
     408           0 :   case AMDGPU::S_LOAD_DWORD_SGPR:
     409           0 :     switch (LoadSize) {
     410             :     case 64:
     411             :       return AMDGPU::S_LOAD_DWORDX2_SGPR;
     412           0 :     case 128:
     413             :       return AMDGPU::S_LOAD_DWORDX4_SGPR;
     414           0 :     case 256:
     415             :       return AMDGPU::S_LOAD_DWORDX8_SGPR;
     416           0 :     case 512:
     417             :       return AMDGPU::S_LOAD_DWORDX16_SGPR;
     418             :     }
     419             :     break;
     420             :   }
     421           0 :   llvm_unreachable("Invalid base smrd opcode or size");
     422             : }
     423             : 
     424          51 : bool AMDGPUInstructionSelector::hasVgprParts(ArrayRef<GEPInfo> AddrInfo) const {
     425         153 :   for (const GEPInfo &GEPInfo : AddrInfo) {
     426          51 :     if (!GEPInfo.VgprParts.empty())
     427             :       return true;
     428             :   }
     429             :   return false;
     430             : }
     431             : 
     432          54 : bool AMDGPUInstructionSelector::selectSMRD(MachineInstr &I,
     433             :                                            ArrayRef<GEPInfo> AddrInfo) const {
     434             : 
     435          54 :   if (!I.hasOneMemOperand())
     436             :     return false;
     437             : 
     438         111 :   if ((*I.memoperands_begin())->getAddrSpace() != AMDGPUASI.CONSTANT_ADDRESS &&
     439           3 :       (*I.memoperands_begin())->getAddrSpace() != AMDGPUASI.CONSTANT_ADDRESS_32BIT)
     440             :     return false;
     441             : 
     442          51 :   if (!isInstrUniform(I))
     443             :     return false;
     444             : 
     445          51 :   if (hasVgprParts(AddrInfo))
     446             :     return false;
     447             : 
     448          51 :   MachineBasicBlock *BB = I.getParent();
     449          51 :   MachineFunction *MF = BB->getParent();
     450          51 :   const SISubtarget &Subtarget = MF->getSubtarget<SISubtarget>();
     451          51 :   MachineRegisterInfo &MRI = MF->getRegInfo();
     452          51 :   unsigned DstReg = I.getOperand(0).getReg();
     453             :   const DebugLoc &DL = I.getDebugLoc();
     454             :   unsigned Opcode;
     455          51 :   unsigned LoadSize = RBI.getSizeInBits(DstReg, MRI, TRI);
     456             : 
     457         102 :   if (!AddrInfo.empty() && AddrInfo[0].SgprParts.size() == 1) {
     458             : 
     459             :     const GEPInfo &GEPInfo = AddrInfo[0];
     460             : 
     461          51 :     unsigned PtrReg = GEPInfo.SgprParts[0];
     462          51 :     int64_t EncodedImm = AMDGPU::getSMRDEncodedOffset(Subtarget, GEPInfo.Imm);
     463          51 :     if (AMDGPU::isLegalSMRDImmOffset(Subtarget, GEPInfo.Imm)) {
     464             :       Opcode = getSmrdOpcode(AMDGPU::S_LOAD_DWORD_IMM, LoadSize);
     465             : 
     466          78 :       MachineInstr *SMRD = BuildMI(*BB, &I, DL, TII.get(Opcode), DstReg)
     467          26 :                                  .addReg(PtrReg)
     468             :                                  .addImm(EncodedImm)
     469          26 :                                  .addImm(0); // glc
     470          26 :       return constrainSelectedInstRegOperands(*SMRD, TII, TRI, RBI);
     471             :     }
     472             : 
     473          36 :     if (Subtarget.getGeneration() == AMDGPUSubtarget::SEA_ISLANDS &&
     474          11 :         isUInt<32>(EncodedImm)) {
     475             :       Opcode = getSmrdOpcode(AMDGPU::S_LOAD_DWORD_IMM_ci, LoadSize);
     476          27 :       MachineInstr *SMRD = BuildMI(*BB, &I, DL, TII.get(Opcode), DstReg)
     477           9 :                                    .addReg(PtrReg)
     478             :                                    .addImm(EncodedImm)
     479           9 :                                    .addImm(0); // glc
     480           9 :       return constrainSelectedInstRegOperands(*SMRD, TII, TRI, RBI);
     481             :     }
     482             : 
     483          16 :     if (isUInt<32>(GEPInfo.Imm)) {
     484             :       Opcode = getSmrdOpcode(AMDGPU::S_LOAD_DWORD_SGPR, LoadSize);
     485           7 :       unsigned OffsetReg = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
     486           7 :       BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_MOV_B32), OffsetReg)
     487           7 :               .addImm(GEPInfo.Imm);
     488             : 
     489          21 :       MachineInstr *SMRD = BuildMI(*BB, &I, DL, TII.get(Opcode), DstReg)
     490           7 :                                    .addReg(PtrReg)
     491           7 :                                    .addReg(OffsetReg)
     492           7 :                                    .addImm(0); // glc
     493           7 :       return constrainSelectedInstRegOperands(*SMRD, TII, TRI, RBI);
     494             :     }
     495             :   }
     496             : 
     497           9 :   unsigned PtrReg = I.getOperand(1).getReg();
     498             :   Opcode = getSmrdOpcode(AMDGPU::S_LOAD_DWORD_IMM, LoadSize);
     499          27 :   MachineInstr *SMRD = BuildMI(*BB, &I, DL, TII.get(Opcode), DstReg)
     500           9 :                                .addReg(PtrReg)
     501             :                                .addImm(0)
     502           9 :                                .addImm(0); // glc
     503           9 :   return constrainSelectedInstRegOperands(*SMRD, TII, TRI, RBI);
     504             : }
     505             : 
     506             : 
     507          54 : bool AMDGPUInstructionSelector::selectG_LOAD(MachineInstr &I) const {
     508          54 :   MachineBasicBlock *BB = I.getParent();
     509          54 :   MachineFunction *MF = BB->getParent();
     510          54 :   MachineRegisterInfo &MRI = MF->getRegInfo();
     511             :   DebugLoc DL = I.getDebugLoc();
     512          54 :   unsigned DstReg = I.getOperand(0).getReg();
     513          54 :   unsigned PtrReg = I.getOperand(1).getReg();
     514          54 :   unsigned LoadSize = RBI.getSizeInBits(DstReg, MRI, TRI);
     515             :   unsigned Opcode;
     516             : 
     517          54 :   SmallVector<GEPInfo, 4> AddrInfo;
     518             : 
     519          54 :   getAddrModeInfo(I, MRI, AddrInfo);
     520             : 
     521          54 :   if (selectSMRD(I, AddrInfo)) {
     522          51 :     I.eraseFromParent();
     523          51 :     return true;
     524             :   }
     525             : 
     526           3 :   switch (LoadSize) {
     527           0 :   default:
     528           0 :     llvm_unreachable("Load size not supported\n");
     529             :   case 32:
     530             :     Opcode = AMDGPU::FLAT_LOAD_DWORD;
     531             :     break;
     532           0 :   case 64:
     533             :     Opcode = AMDGPU::FLAT_LOAD_DWORDX2;
     534           0 :     break;
     535             :   }
     536             : 
     537           9 :   MachineInstr *Flat = BuildMI(*BB, &I, DL, TII.get(Opcode))
     538           3 :                                .add(I.getOperand(0))
     539           3 :                                .addReg(PtrReg)
     540             :                                .addImm(0)  // offset
     541             :                                .addImm(0)  // glc
     542           3 :                                .addImm(0); // slc
     543             : 
     544           3 :   bool Ret = constrainSelectedInstRegOperands(*Flat, TII, TRI, RBI);
     545           3 :   I.eraseFromParent();
     546           3 :   return Ret;
     547             : }
     548             : 
     549         351 : bool AMDGPUInstructionSelector::select(MachineInstr &I,
     550             :                                        CodeGenCoverage &CoverageInfo) const {
     551             : 
     552         702 :   if (!isPreISelGenericOpcode(I.getOpcode())) {
     553         131 :     if (I.isCopy())
     554         118 :       return selectCOPY(I);
     555             :     return true;
     556             :   }
     557             : 
     558         220 :   switch (I.getOpcode()) {
     559          38 :   default:
     560          38 :     return selectImpl(I, CoverageInfo);
     561           0 :   case TargetOpcode::G_ADD:
     562           0 :     return selectG_ADD(I);
     563           5 :   case TargetOpcode::G_BITCAST:
     564           5 :     return selectCOPY(I);
     565          25 :   case TargetOpcode::G_CONSTANT:
     566             :   case TargetOpcode::G_FCONSTANT:
     567          25 :     return selectG_CONSTANT(I);
     568           9 :   case TargetOpcode::G_GEP:
     569           9 :     return selectG_GEP(I);
     570          20 :   case TargetOpcode::G_IMPLICIT_DEF:
     571          20 :     return selectG_IMPLICIT_DEF(I);
     572          16 :   case TargetOpcode::G_INTRINSIC:
     573          16 :     return selectG_INTRINSIC(I, CoverageInfo);
     574          54 :   case TargetOpcode::G_LOAD:
     575          54 :     return selectG_LOAD(I);
     576          53 :   case TargetOpcode::G_STORE:
     577          53 :     return selectG_STORE(I);
     578             :   }
     579             :   return false;
     580             : }
     581             : 
     582             : InstructionSelector::ComplexRendererFns
     583           6 : AMDGPUInstructionSelector::selectVCSRC(MachineOperand &Root) const {
     584             :   return {{
     585           6 :       [=](MachineInstrBuilder &MIB) { MIB.add(Root); }
     586          18 :   }};
     587             : 
     588             : }
     589             : 
     590             : ///
     591             : /// This will select either an SGPR or VGPR operand and will save us from
     592             : /// having to write an extra tablegen pattern.
     593             : InstructionSelector::ComplexRendererFns
     594          17 : AMDGPUInstructionSelector::selectVSRC0(MachineOperand &Root) const {
     595             :   return {{
     596          17 :       [=](MachineInstrBuilder &MIB) { MIB.add(Root); }
     597          51 :   }};
     598             : }
     599             : 
     600             : InstructionSelector::ComplexRendererFns
     601           8 : AMDGPUInstructionSelector::selectVOP3Mods0(MachineOperand &Root) const {
     602             :   return {{
     603           8 :       [=](MachineInstrBuilder &MIB) { MIB.add(Root); },
     604             :       [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }, // src0_mods
     605             :       [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }, // clamp
     606             :       [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }  // omod
     607          24 :   }};
     608             : }
     609             : InstructionSelector::ComplexRendererFns
     610           2 : AMDGPUInstructionSelector::selectVOP3OMods(MachineOperand &Root) const {
     611             :   return {{
     612           2 :       [=](MachineInstrBuilder &MIB) { MIB.add(Root); },
     613             :       [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }, // clamp
     614             :       [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }  // omod
     615           6 :   }};
     616             : }
     617             : 
     618             : InstructionSelector::ComplexRendererFns
     619           6 : AMDGPUInstructionSelector::selectVOP3Mods(MachineOperand &Root) const {
     620             :   return {{
     621           6 :       [=](MachineInstrBuilder &MIB) { MIB.add(Root); },
     622             :       [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }  // src_mods
     623          18 :   }};
     624      299229 : }

Generated by: LCOV version 1.13