LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU - AMDGPULegalizerInfo.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 93 99 93.9 %
Date: 2018-07-13 00:08:38 Functions: 7 9 77.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- AMDGPULegalizerInfo.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 Machinelegalizer class for
      11             : /// AMDGPU.
      12             : /// \todo This should be generated by TableGen.
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #include "AMDGPU.h"
      16             : #include "AMDGPULegalizerInfo.h"
      17             : #include "AMDGPUTargetMachine.h"
      18             : #include "llvm/CodeGen/TargetOpcodes.h"
      19             : #include "llvm/CodeGen/ValueTypes.h"
      20             : #include "llvm/IR/DerivedTypes.h"
      21             : #include "llvm/IR/Type.h"
      22             : #include "llvm/Support/Debug.h"
      23             : 
      24             : using namespace llvm;
      25             : using namespace LegalizeActions;
      26             : 
      27        2271 : AMDGPULegalizerInfo::AMDGPULegalizerInfo(const SISubtarget &ST,
      28        2271 :                                          const GCNTargetMachine &TM) {
      29             :   using namespace TargetOpcode;
      30             : 
      31        9084 :   auto GetAddrSpacePtr = [&TM](unsigned AS) {
      32        4542 :     return LLT::pointer(AS, TM.getPointerSizeInBits(AS));
      33        6813 :   };
      34             : 
      35             :   auto AMDGPUAS = ST.getAMDGPUAS();
      36             : 
      37        2271 :   const LLT S1 = LLT::scalar(1);
      38             :   const LLT V2S16 = LLT::vector(2, 16);
      39             : 
      40             :   const LLT S32 = LLT::scalar(32);
      41             :   const LLT S64 = LLT::scalar(64);
      42        2271 :   const LLT S512 = LLT::scalar(512);
      43             : 
      44             :   const LLT GlobalPtr = GetAddrSpacePtr(AMDGPUAS::GLOBAL_ADDRESS);
      45             :   const LLT ConstantPtr = GetAddrSpacePtr(AMDGPUAS::CONSTANT_ADDRESS);
      46             :   const LLT LocalPtr = GetAddrSpacePtr(AMDGPUAS::LOCAL_ADDRESS);
      47        2271 :   const LLT FlatPtr = GetAddrSpacePtr(AMDGPUAS.FLAT_ADDRESS);
      48        2271 :   const LLT PrivatePtr = GetAddrSpacePtr(AMDGPUAS.PRIVATE_ADDRESS);
      49             : 
      50             :   const LLT AddrSpaces[] = {
      51             :     GlobalPtr,
      52             :     ConstantPtr,
      53             :     LocalPtr,
      54             :     FlatPtr,
      55             :     PrivatePtr
      56        2271 :   };
      57             : 
      58        2271 :   setAction({G_ADD, S32}, Legal);
      59        2271 :   setAction({G_ASHR, S32}, Legal);
      60        2271 :   setAction({G_SUB, S32}, Legal);
      61        2271 :   setAction({G_MUL, S32}, Legal);
      62        2271 :   setAction({G_AND, S32}, Legal);
      63        2271 :   setAction({G_OR, S32}, Legal);
      64        2271 :   setAction({G_XOR, S32}, Legal);
      65             : 
      66        2271 :   setAction({G_BITCAST, V2S16}, Legal);
      67        2271 :   setAction({G_BITCAST, 1, S32}, Legal);
      68             : 
      69        2271 :   setAction({G_BITCAST, S32}, Legal);
      70        2271 :   setAction({G_BITCAST, 1, V2S16}, Legal);
      71             : 
      72        2271 :   getActionDefinitionsBuilder(G_FCONSTANT)
      73        4542 :     .legalFor({S32, S64});
      74             : 
      75             :   // G_IMPLICIT_DEF is a no-op so we can make it legal for any value type that
      76             :   // can fit in a register.
      77             :   // FIXME: We need to legalize several more operations before we can add
      78             :   // a test case for size > 512.
      79        2271 :   getActionDefinitionsBuilder(G_IMPLICIT_DEF)
      80             :     .legalIf([=](const LegalityQuery &Query) {
      81          13 :         return Query.Types[0].getSizeInBits() <= 512;
      82        4555 :     })
      83        2271 :     .clampScalar(0, S1, S512);
      84             : 
      85        2271 :   getActionDefinitionsBuilder(G_CONSTANT)
      86        4542 :     .legalFor({S1, S32, S64});
      87             : 
      88             :   // FIXME: i1 operands to intrinsics should always be legal, but other i1
      89             :   // values may not be legal.  We need to figure out how to distinguish
      90             :   // between these two scenarios.
      91        2271 :   setAction({G_CONSTANT, S1}, Legal);
      92             : 
      93        2271 :   setAction({G_FADD, S32}, Legal);
      94             : 
      95        2271 :   setAction({G_FCMP, S1}, Legal);
      96        2271 :   setAction({G_FCMP, 1, S32}, Legal);
      97        2271 :   setAction({G_FCMP, 1, S64}, Legal);
      98             : 
      99        2271 :   setAction({G_FMUL, S32}, Legal);
     100             : 
     101        2271 :   setAction({G_ZEXT, S64}, Legal);
     102        2271 :   setAction({G_ZEXT, 1, S32}, Legal);
     103             : 
     104        2271 :   setAction({G_FPTOSI, S32}, Legal);
     105        2271 :   setAction({G_FPTOSI, 1, S32}, Legal);
     106             : 
     107        2271 :   setAction({G_SITOFP, S32}, Legal);
     108             :   setAction({G_SITOFP, 1, S32}, Legal);
     109             : 
     110        2271 :   setAction({G_FPTOUI, S32}, Legal);
     111        2271 :   setAction({G_FPTOUI, 1, S32}, Legal);
     112             : 
     113       24981 :   for (LLT PtrTy : AddrSpaces) {
     114       11355 :     LLT IdxTy = LLT::scalar(PtrTy.getSizeInBits());
     115       11355 :     setAction({G_GEP, PtrTy}, Legal);
     116       11355 :     setAction({G_GEP, 1, IdxTy}, Legal);
     117             :   }
     118             : 
     119        2271 :   setAction({G_ICMP, S1}, Legal);
     120        2271 :   setAction({G_ICMP, 1, S32}, Legal);
     121             : 
     122             : 
     123        2271 :   getActionDefinitionsBuilder({G_LOAD, G_STORE})
     124        2325 :     .legalIf([=, &ST](const LegalityQuery &Query) {
     125          52 :         const LLT &Ty0 = Query.Types[0];
     126             : 
     127             :         // TODO: Decompose private loads into 4-byte components.
     128             :         // TODO: Illegal flat loads on SI
     129          52 :         switch (Ty0.getSizeInBits()) {
     130             :         case 32:
     131             :         case 64:
     132             :         case 128:
     133             :           return true;
     134             : 
     135           2 :         case 96:
     136             :           // XXX hasLoadX3
     137           2 :           return (ST.getGeneration() >= AMDGPUSubtarget::SEA_ISLANDS);
     138             : 
     139           0 :         case 256:
     140             :         case 512:
     141             :           // TODO: constant loads
     142             :         default:
     143           0 :           return false;
     144             :         }
     145        4542 :       });
     146             : 
     147             : 
     148             : 
     149        2271 :   setAction({G_SELECT, S32}, Legal);
     150        2271 :   setAction({G_SELECT, 1, S1}, Legal);
     151             : 
     152        2271 :   setAction({G_SHL, S32}, Legal);
     153             : 
     154             : 
     155             :   // FIXME: When RegBankSelect inserts copies, it will only create new
     156             :   // registers with scalar types.  This means we can end up with
     157             :   // G_LOAD/G_STORE/G_GEP instruction with scalar types for their pointer
     158             :   // operands.  In assert builds, the instruction selector will assert
     159             :   // if it sees a generic instruction which isn't legal, so we need to
     160             :   // tell it that scalar types are legal for pointer operands
     161        2271 :   setAction({G_GEP, S64}, Legal);
     162             : 
     163       11355 :   for (unsigned Op : {G_EXTRACT_VECTOR_ELT, G_INSERT_VECTOR_ELT}) {
     164        4542 :     getActionDefinitionsBuilder(Op)
     165        4553 :       .legalIf([=](const LegalityQuery &Query) {
     166          11 :           const LLT &VecTy = Query.Types[1];
     167             :           const LLT &IdxTy = Query.Types[2];
     168          22 :           return VecTy.getSizeInBits() % 32 == 0 &&
     169          22 :             VecTy.getSizeInBits() <= 512 &&
     170          22 :             IdxTy.getSizeInBits() == 32;
     171        4542 :         });
     172             :   }
     173             : 
     174             :   // FIXME: Doesn't handle extract of illegal sizes.
     175        2271 :   getActionDefinitionsBuilder(G_EXTRACT)
     176           8 :     .unsupportedIf([=](const LegalityQuery &Query) {
     177          16 :         return Query.Types[0].getSizeInBits() >= Query.Types[1].getSizeInBits();
     178        4550 :       })
     179        2279 :     .legalIf([=](const LegalityQuery &Query) {
     180           8 :         const LLT &Ty0 = Query.Types[0];
     181             :         const LLT &Ty1 = Query.Types[1];
     182          16 :         return (Ty0.getSizeInBits() % 32 == 0) &&
     183          16 :                (Ty1.getSizeInBits() % 32 == 0);
     184        2271 :       });
     185             : 
     186             :   // Merge/Unmerge
     187       11355 :   for (unsigned Op : {G_MERGE_VALUES, G_UNMERGE_VALUES}) {
     188        4542 :     unsigned BigTyIdx = Op == G_MERGE_VALUES ? 0 : 1;
     189        4542 :     unsigned LitTyIdx = Op == G_MERGE_VALUES ? 1 : 0;
     190             : 
     191        4542 :     getActionDefinitionsBuilder(Op)
     192          12 :       .legalIf([=](const LegalityQuery &Query) {
     193          12 :           const LLT &BigTy = Query.Types[BigTyIdx];
     194          12 :           const LLT &LitTy = Query.Types[LitTyIdx];
     195          24 :           return BigTy.getSizeInBits() % 32 == 0 &&
     196          24 :                  LitTy.getSizeInBits() % 32 == 0 &&
     197          12 :                  BigTy.getSizeInBits() <= 512;
     198        9084 :         })
     199             :       // Any vectors left are the wrong size. Scalarize them.
     200             :       .fewerElementsIf([](const LegalityQuery &Query) { return true; },
     201           0 :                        [](const LegalityQuery &Query) {
     202             :                          return std::make_pair(
     203           0 :                            0, Query.Types[0].getElementType());
     204       13626 :                        })
     205        4542 :       .fewerElementsIf([](const LegalityQuery &Query) { return true; },
     206           0 :                        [](const LegalityQuery &Query) {
     207             :                          return std::make_pair(
     208           0 :                            1, Query.Types[1].getElementType());
     209        9084 :                        });
     210             : 
     211             :   }
     212             : 
     213        2271 :   computeTables();
     214        2271 :   verify(*ST.getInstrInfo());
     215        2271 : }

Generated by: LCOV version 1.13