LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU - AMDGPURegisterBankInfo.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 55 83 66.3 %
Date: 2017-09-14 15:23:50 Functions: 7 9 77.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- AMDGPURegisterBankInfo.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 RegisterBankInfo class for
      11             : /// AMDGPU.
      12             : /// \todo This should be generated by TableGen.
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #include "AMDGPURegisterBankInfo.h"
      16             : #include "AMDGPUInstrInfo.h"
      17             : #include "SIRegisterInfo.h"
      18             : #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
      19             : #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
      20             : #include "llvm/IR/Constants.h"
      21             : #include "llvm/Target/TargetRegisterInfo.h"
      22             : #include "llvm/Target/TargetSubtargetInfo.h"
      23             : 
      24             : #define GET_TARGET_REGBANK_IMPL
      25             : #include "AMDGPUGenRegisterBank.inc"
      26             : 
      27             : // This file will be TableGen'ed at some point.
      28             : #include "AMDGPUGenRegisterBankInfo.def"
      29             : 
      30             : using namespace llvm;
      31             : 
      32        1796 : AMDGPURegisterBankInfo::AMDGPURegisterBankInfo(const TargetRegisterInfo &TRI)
      33             :     : AMDGPUGenRegisterBankInfo(),
      34        1796 :       TRI(static_cast<const SIRegisterInfo*>(&TRI)) {
      35             : 
      36             :   // HACK: Until this is fully tablegen'd
      37             :   static bool AlreadyInit = false;
      38        1796 :   if (AlreadyInit)
      39             :     return;
      40             : 
      41        1722 :   AlreadyInit = true;
      42             : 
      43        1722 :   const RegisterBank &RBSGPR = getRegBank(AMDGPU::SGPRRegBankID);
      44             :   (void)RBSGPR;
      45             :   assert(&RBSGPR == &AMDGPU::SGPRRegBank);
      46             : 
      47        1722 :   const RegisterBank &RBVGPR = getRegBank(AMDGPU::VGPRRegBankID);
      48             :   (void)RBVGPR;
      49             :   assert(&RBVGPR == &AMDGPU::VGPRRegBank);
      50             : 
      51             : }
      52             : 
      53           0 : unsigned AMDGPURegisterBankInfo::copyCost(const RegisterBank &A,
      54             :                                            const RegisterBank &B,
      55             :                                            unsigned Size) const {
      56           0 :   return RegisterBankInfo::copyCost(A, B, Size);
      57             : }
      58             : 
      59          51 : const RegisterBank &AMDGPURegisterBankInfo::getRegBankFromRegClass(
      60             :     const TargetRegisterClass &RC) const {
      61             : 
      62         102 :   if (TRI->isSGPRClass(&RC))
      63         102 :     return getRegBank(AMDGPU::SGPRRegBankID);
      64             : 
      65           0 :   return getRegBank(AMDGPU::VGPRRegBankID);
      66             : }
      67             : 
      68             : RegisterBankInfo::InstructionMappings
      69           0 : AMDGPURegisterBankInfo::getInstrAlternativeMappings(
      70             :     const MachineInstr &MI) const {
      71             : 
      72           0 :   const MachineFunction &MF = *MI.getParent()->getParent();
      73           0 :   const MachineRegisterInfo &MRI = MF.getRegInfo();
      74             : 
      75           0 :   unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
      76             : 
      77           0 :   InstructionMappings AltMappings;
      78           0 :   switch (MI.getOpcode()) {
      79           0 :   case TargetOpcode::G_LOAD: {
      80             :     // FIXME: Should we be hard coding the size for these mappings?
      81             :     const InstructionMapping &SSMapping = getInstructionMapping(
      82             :         1, 1, getOperandsMapping(
      83           0 :                   {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
      84           0 :                    AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
      85           0 :         2); // Num Operands
      86           0 :     AltMappings.push_back(&SSMapping);
      87             : 
      88             :     const InstructionMapping &VVMapping = getInstructionMapping(
      89             :         2, 1, getOperandsMapping(
      90           0 :                   {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
      91           0 :                    AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64)}),
      92           0 :         2); // Num Operands
      93           0 :     AltMappings.push_back(&VVMapping);
      94             : 
      95             :     // FIXME: Should this be the pointer-size (64-bits) or the size of the
      96             :     // register that will hold the bufffer resourc (128-bits).
      97             :     const InstructionMapping &VSMapping = getInstructionMapping(
      98             :         3, 1, getOperandsMapping(
      99           0 :                   {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
     100           0 :                    AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
     101           0 :         2); // Num Operands
     102           0 :     AltMappings.push_back(&VSMapping);
     103             : 
     104             :     return AltMappings;
     105             : 
     106             :   }
     107             :   default:
     108             :     break;
     109             :   }
     110           0 :   return RegisterBankInfo::getInstrAlternativeMappings(MI);
     111             : }
     112             : 
     113         123 : void AMDGPURegisterBankInfo::applyMappingImpl(
     114             :     const OperandsMapper &OpdMapper) const {
     115         123 :   return applyDefaultMapping(OpdMapper);
     116             : }
     117             : 
     118             : static bool isInstrUniform(const MachineInstr &MI) {
     119          39 :   if (!MI.hasOneMemOperand())
     120             :     return false;
     121             : 
     122          39 :   const MachineMemOperand *MMO = *MI.memoperands_begin();
     123          39 :   return AMDGPU::isUniformMMO(MMO);
     124             : }
     125             : 
     126             : const RegisterBankInfo::InstructionMapping &
     127          39 : AMDGPURegisterBankInfo::getInstrMappingForLoad(const MachineInstr &MI) const {
     128             : 
     129          39 :   const MachineFunction &MF = *MI.getParent()->getParent();
     130          39 :   const MachineRegisterInfo &MRI = MF.getRegInfo();
     131         117 :   SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands());
     132          39 :   unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
     133          39 :   unsigned PtrSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI);
     134             : 
     135             :   const ValueMapping *ValMapping;
     136             :   const ValueMapping *PtrMapping;
     137             : 
     138          39 :   if (isInstrUniform(MI)) {
     139             :     // We have a uniform instruction so we want to use an SMRD load
     140          38 :     ValMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
     141          38 :     PtrMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, PtrSize);
     142             :   } else {
     143           1 :     ValMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
     144             :     // FIXME: What would happen if we used SGPRRegBankID here?
     145           1 :     PtrMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, PtrSize);
     146             :   }
     147             : 
     148          39 :   OpdsMapping[0] = ValMapping;
     149          39 :   OpdsMapping[1] = PtrMapping;
     150             :   const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping(
     151          78 :       1, 1, getOperandsMapping(OpdsMapping), MI.getNumOperands());
     152          78 :   return Mapping;
     153             : 
     154             :   // FIXME: Do we want to add a mapping for FLAT load, or should we just
     155             :   // handle that during instruction selection?
     156             : }
     157             : 
     158             : const RegisterBankInfo::InstructionMapping &
     159         138 : AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
     160         138 :   const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI);
     161             : 
     162         123 :   if (Mapping.isValid())
     163             :     return Mapping;
     164             : 
     165         123 :   const MachineFunction &MF = *MI.getParent()->getParent();
     166         123 :   const MachineRegisterInfo &MRI = MF.getRegInfo();
     167         246 :   SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands());
     168             : 
     169         123 :   bool IsComplete = true;
     170         246 :   switch (MI.getOpcode()) {
     171             :   default:
     172             :     IsComplete = false;
     173             :     break;
     174          36 :   case AMDGPU::G_CONSTANT: {
     175          36 :     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
     176          36 :     OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
     177             :     break;
     178             :   }
     179          36 :   case AMDGPU::G_GEP: {
     180         144 :     for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
     181         324 :       if (!MI.getOperand(i).isReg())
     182           0 :         continue;
     183             : 
     184         108 :       unsigned Size = MRI.getType(MI.getOperand(i).getReg()).getSizeInBits();
     185         216 :       OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
     186             :     }
     187             :     break;
     188             :   }
     189          12 :   case AMDGPU::G_STORE: {
     190             :     assert(MI.getOperand(0).isReg());
     191          12 :     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
     192             :     // FIXME: We need to specify a different reg bank once scalar stores
     193             :     // are supported.
     194             :     const ValueMapping *ValMapping =
     195          12 :         AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size);
     196             :     // FIXME: Depending on the type of store, the pointer could be in
     197             :     // the SGPR Reg bank.
     198             :     // FIXME: Pointer size should be based on the address space.
     199             :     const ValueMapping *PtrMapping =
     200          12 :         AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64);
     201             : 
     202          12 :     OpdsMapping[0] = ValMapping;
     203          12 :     OpdsMapping[1] = PtrMapping;
     204             :     break;
     205             :   }
     206             : 
     207          39 :   case AMDGPU::G_LOAD:
     208          39 :     return getInstrMappingForLoad(MI);
     209             :   }
     210             : 
     211             :   if (!IsComplete) {
     212             :     unsigned BankID = AMDGPU::SGPRRegBankID;
     213             : 
     214             :     unsigned Size = 0;
     215           0 :     for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) {
     216             :       // If the operand is not a register default to the size of the previous
     217             :       // operand.
     218             :       // FIXME: Can't we pull the types from the MachineInstr rather than the
     219             :       // operands.
     220           0 :       if (MI.getOperand(Idx).isReg())
     221           0 :         Size = getSizeInBits(MI.getOperand(Idx).getReg(), MRI, *TRI);
     222           0 :       OpdsMapping.push_back(AMDGPU::getValueMapping(BankID, Size));
     223             :     }
     224             :   }
     225             :   return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping),
     226         168 :                                MI.getNumOperands());
     227      216918 : }

Generated by: LCOV version 1.13