LCOV - code coverage report
Current view: top level - include/llvm/CodeGen - LowLevelType.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 31 31 100.0 %
Date: 2017-03-08 17:05:39 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : //== llvm/CodeGen/GlobalISel/LowLevelType.h -------------------- -*- 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             : //
      10             : /// Implement a low-level type suitable for MachineInstr level instruction
      11             : /// selection.
      12             : ///
      13             : /// For a type attached to a MachineInstr, we only care about 2 details: total
      14             : /// size and the number of vector lanes (if any). Accordingly, there are 4
      15             : /// possible valid type-kinds:
      16             : ///
      17             : ///    * `sN` for scalars and aggregates
      18             : ///    * `<N x sM>` for vectors, which must have at least 2 elements.
      19             : ///    * `pN` for pointers
      20             : ///
      21             : /// Other information required for correct selection is expected to be carried
      22             : /// by the opcode, or non-type flags. For example the distinction between G_ADD
      23             : /// and G_FADD for int/float or fast-math flags.
      24             : //
      25             : //===----------------------------------------------------------------------===//
      26             : 
      27             : #ifndef LLVM_CODEGEN_GLOBALISEL_LOWLEVELTYPE_H
      28             : #define LLVM_CODEGEN_GLOBALISEL_LOWLEVELTYPE_H
      29             : 
      30             : #include <cassert>
      31             : #include "llvm/ADT/DenseMapInfo.h"
      32             : #include "llvm/CodeGen/ValueTypes.h"
      33             : 
      34             : namespace llvm {
      35             : 
      36             : class DataLayout;
      37             : class LLVMContext;
      38             : class Type;
      39             : class raw_ostream;
      40             : 
      41             : class LLT {
      42             : public:
      43             :   enum TypeKind : uint16_t {
      44             :     Invalid,
      45             :     Scalar,
      46             :     Pointer,
      47             :     Vector,
      48             :   };
      49             : 
      50             :   /// Get a low-level scalar or aggregate "bag of bits".
      51             :   static LLT scalar(unsigned SizeInBits) {
      52             :     assert(SizeInBits > 0 && "invalid scalar size");
      53      149458 :     return LLT{Scalar, 1, SizeInBits};
      54             :   }
      55             : 
      56             :   /// Get a low-level pointer in the given address space (defaulting to 0).
      57             :   static LLT pointer(uint16_t AddressSpace, unsigned SizeInBits) {
      58        7058 :     return LLT{Pointer, AddressSpace, SizeInBits};
      59             :   }
      60             : 
      61             :   /// Get a low-level vector of some number of elements and element width.
      62             :   /// \p NumElements must be at least 2.
      63             :   static LLT vector(uint16_t NumElements, unsigned ScalarSizeInBits) {
      64             :     assert(NumElements > 1 && "invalid number of vector elements");
      65       22274 :     return LLT{Vector, NumElements, ScalarSizeInBits};
      66             :   }
      67             : 
      68             :   /// Get a low-level vector of some number of elements and element type.
      69             :   static LLT vector(uint16_t NumElements, LLT ScalarTy) {
      70             :     assert(NumElements > 1 && "invalid number of vector elements");
      71             :     assert(ScalarTy.isScalar() && "invalid vector element type");
      72          50 :     return LLT{Vector, NumElements, ScalarTy.getSizeInBits()};
      73             :   }
      74             : 
      75             :   explicit LLT(TypeKind Kind, uint16_t NumElements, unsigned SizeInBits)
      76             :     : SizeInBits(SizeInBits), ElementsOrAddrSpace(NumElements), Kind(Kind) {
      77             :     assert((Kind != Vector || ElementsOrAddrSpace > 1) &&
      78             :            "invalid number of vector elements");
      79             :   }
      80             : 
      81       42428 :   explicit LLT() : SizeInBits(0), ElementsOrAddrSpace(0), Kind(Invalid) {}
      82             : 
      83             :   /// Construct a low-level type based on an LLVM type.
      84             :   explicit LLT(Type &Ty, const DataLayout &DL);
      85             : 
      86             :   explicit LLT(MVT VT);
      87             : 
      88         140 :   bool isValid() const { return Kind != Invalid; }
      89             : 
      90          15 :   bool isScalar() const { return Kind == Scalar; }
      91             : 
      92           4 :   bool isPointer() const { return Kind == Pointer; }
      93             : 
      94         120 :   bool isVector() const { return Kind == Vector; }
      95             : 
      96             :   /// Returns the number of elements in a vector LLT. Must only be called on
      97             :   /// vector types.
      98             :   uint16_t getNumElements() const {
      99             :     assert(isVector() && "cannot get number of elements on scalar/aggregate");
     100             :     return ElementsOrAddrSpace;
     101             :   }
     102             : 
     103             :   /// Returns the total size of the type. Must only be called on sized types.
     104             :   unsigned getSizeInBits() const {
     105        9591 :     if (isPointer() || isScalar())
     106        2454 :       return SizeInBits;
     107         824 :     return SizeInBits * ElementsOrAddrSpace;
     108             :   }
     109             : 
     110             :   unsigned getScalarSizeInBits() const {
     111             :     return SizeInBits;
     112             :   }
     113             : 
     114             :   unsigned getAddressSpace() const {
     115             :     assert(isPointer() && "cannot get address space of non-pointer type");
     116          23 :     return ElementsOrAddrSpace;
     117             :   }
     118             : 
     119             :   /// Returns the vector's element type. Only valid for vector types.
     120             :   LLT getElementType() const {
     121             :     assert(isVector() && "cannot get element type of scalar/aggregate");
     122      200734 :     return scalar(SizeInBits);
     123             :   }
     124             : 
     125             :   /// Get a low-level type with half the size of the original, by halving the
     126             :   /// size of the scalar type involved. For example `s32` will become `s16`,
     127             :   /// `<2 x s32>` will become `<2 x s16>`.
     128             :   LLT halfScalarSize() const {
     129             :     assert(!isPointer() && getScalarSizeInBits() > 1 &&
     130             :            getScalarSizeInBits() % 2 == 0 && "cannot half size of this type");
     131          33 :     return LLT{Kind, ElementsOrAddrSpace, SizeInBits / 2};
     132             :   }
     133             : 
     134             :   /// Get a low-level type with twice the size of the original, by doubling the
     135             :   /// size of the scalar type involved. For example `s32` will become `s64`,
     136             :   /// `<2 x s32>` will become `<2 x s64>`.
     137             :   LLT doubleScalarSize() const {
     138             :     assert(!isPointer() && "cannot change size of this type");
     139         101 :     return LLT{Kind, ElementsOrAddrSpace, SizeInBits * 2};
     140             :   }
     141             : 
     142             :   /// Get a low-level type with half the size of the original, by halving the
     143             :   /// number of vector elements of the scalar type involved. The source must be
     144             :   /// a vector type with an even number of elements. For example `<4 x s32>`
     145             :   /// will become `<2 x s32>`, `<2 x s32>` will become `s32`.
     146             :   LLT halfElements() const {
     147             :     assert(isVector() && ElementsOrAddrSpace % 2 == 0 &&
     148             :            "cannot half odd vector");
     149          17 :     if (ElementsOrAddrSpace == 2)
     150             :       return scalar(SizeInBits);
     151             : 
     152          24 :     return LLT{Vector, static_cast<uint16_t>(ElementsOrAddrSpace / 2),
     153          12 :                SizeInBits};
     154             :   }
     155             : 
     156             :   /// Get a low-level type with twice the size of the original, by doubling the
     157             :   /// number of vector elements of the scalar type involved. The source must be
     158             :   /// a vector type. For example `<2 x s32>` will become `<4 x s32>`. Doubling
     159             :   /// the number of elements in sN produces <2 x sN>.
     160             :   LLT doubleElements() const {
     161             :     assert(!isPointer() && "cannot double elements in pointer");
     162          54 :     return LLT{Vector, static_cast<uint16_t>(ElementsOrAddrSpace * 2),
     163          27 :                SizeInBits};
     164             :   }
     165             : 
     166             :   void print(raw_ostream &OS) const;
     167             : 
     168             :   bool operator==(const LLT &RHS) const {
     169    27108996 :     return Kind == RHS.Kind && SizeInBits == RHS.SizeInBits &&
     170    11612246 :            ElementsOrAddrSpace == RHS.ElementsOrAddrSpace;
     171             :   }
     172             : 
     173        1862 :   bool operator!=(const LLT &RHS) const { return !(*this == RHS); }
     174             : 
     175             :   friend struct DenseMapInfo<LLT>;
     176             : private:
     177             :   unsigned SizeInBits;
     178             :   uint16_t ElementsOrAddrSpace;
     179             :   TypeKind Kind;
     180             : };
     181             : 
     182             : inline raw_ostream& operator<<(raw_ostream &OS, const LLT &Ty) {
     183        3300 :   Ty.print(OS);
     184             :   return OS;
     185             : }
     186             : 
     187             : template<> struct DenseMapInfo<LLT> {
     188             :   static inline LLT getEmptyKey() {
     189     2224928 :     return LLT{LLT::Invalid, 0, -1u};
     190             :   }
     191             :   static inline LLT getTombstoneKey() {
     192     1403939 :     return LLT{LLT::Invalid, 0, -2u};
     193             :   }
     194             :   static inline unsigned getHashValue(const LLT &Ty) {
     195     1336178 :     uint64_t Val = ((uint64_t)Ty.SizeInBits << 32) |
     196     1336178 :                    ((uint64_t)Ty.ElementsOrAddrSpace << 16) | (uint64_t)Ty.Kind;
     197      668089 :     return DenseMapInfo<uint64_t>::getHashValue(Val);
     198             :   }
     199             :   static bool isEqual(const LLT &LHS, const LLT &RHS) {
     200    15494231 :     return LHS == RHS;
     201             :   }
     202             : };
     203             : 
     204             : }
     205             : 
     206             : #endif

Generated by: LCOV version 1.13