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

Generated by: LCOV version 1.13