LLVM  4.0.0
LowLevelType.h
Go to the documentation of this file.
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"
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 {
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  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  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  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  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  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  bool isValid() const { return Kind != Invalid; }
89 
90  bool isScalar() const { return Kind == Scalar; }
91 
92  bool isPointer() const { return Kind == Pointer; }
93 
94  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  if (isPointer() || isScalar())
106  return SizeInBits;
107  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  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  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  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>`.
138  assert(!isPointer() && "cannot change size of this type");
139  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  if (ElementsOrAddrSpace == 2)
150  return scalar(SizeInBits);
151 
152  return LLT{Vector, static_cast<uint16_t>(ElementsOrAddrSpace / 2),
153  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  return LLT{Vector, static_cast<uint16_t>(ElementsOrAddrSpace * 2),
163  SizeInBits};
164  }
165 
166  void print(raw_ostream &OS) const;
167 
168  bool operator==(const LLT &RHS) const {
169  return Kind == RHS.Kind && SizeInBits == RHS.SizeInBits &&
170  ElementsOrAddrSpace == RHS.ElementsOrAddrSpace;
171  }
172 
173  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  Ty.print(OS);
184  return OS;
185 }
186 
187 template<> struct DenseMapInfo<LLT> {
188  static inline LLT getEmptyKey() {
189  return LLT{LLT::Invalid, 0, -1u};
190  }
191  static inline LLT getTombstoneKey() {
192  return LLT{LLT::Invalid, 0, -2u};
193  }
194  static inline unsigned getHashValue(const LLT &Ty) {
195  uint64_t Val = ((uint64_t)Ty.SizeInBits << 32) |
196  ((uint64_t)Ty.ElementsOrAddrSpace << 16) | (uint64_t)Ty.Kind;
198  }
199  static bool isEqual(const LLT &LHS, const LLT &RHS) {
200  return LHS == RHS;
201  }
202 };
203 
204 }
205 
206 #endif
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:102
LLT doubleElements() const
Get a low-level type with twice the size of the original, by doubling the number of vector elements o...
Definition: LowLevelType.h:160
static LLT vector(uint16_t NumElements, LLT ScalarTy)
Get a low-level vector of some number of elements and element type.
Definition: LowLevelType.h:69
bool operator!=(const LLT &RHS) const
Definition: LowLevelType.h:173
bool isPointer() const
Definition: LowLevelType.h:92
unsigned getScalarSizeInBits() const
Definition: LowLevelType.h:110
unsigned getAddressSpace() const
Definition: LowLevelType.h:114
bool operator==(const LLT &RHS) const
Definition: LowLevelType.h:168
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:51
LLT doubleScalarSize() const
Get a low-level type with twice the size of the original, by doubling the size of the scalar type inv...
Definition: LowLevelType.h:137
LLT(TypeKind Kind, uint16_t NumElements, unsigned SizeInBits)
Definition: LowLevelType.h:75
MVT - Machine Value Type.
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
static bool isEqual(const LLT &LHS, const LLT &RHS)
Definition: LowLevelType.h:199
static LLT getTombstoneKey()
Definition: LowLevelType.h:191
uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
Definition: LowLevelType.h:98
AddressSpace
Definition: NVPTXBaseInfo.h:22
static unsigned getHashValue(const LLT &Ty)
Definition: LowLevelType.h:194
bool isScalar() const
Definition: LowLevelType.h:90
LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
Definition: LowLevelType.h:120
LLT halfScalarSize() const
Get a low-level type with half the size of the original, by halving the size of the scalar type invol...
Definition: LowLevelType.h:128
LLT halfElements() const
Get a low-level type with half the size of the original, by halving the number of vector elements of ...
Definition: LowLevelType.h:146
bool isValid() const
Definition: LowLevelType.h:88
void print(raw_ostream &OS) const
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
Definition: APInt.h:1726
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static LLT pointer(uint16_t AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space (defaulting to 0).
Definition: LowLevelType.h:57
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelType.h:104
static LLT vector(uint16_t NumElements, unsigned ScalarSizeInBits)
Get a low-level vector of some number of elements and element width.
Definition: LowLevelType.h:63
bool isVector() const
Definition: LowLevelType.h:94