Coverage Report

Created: 2017-03-08 01:53

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/CodeGen/LowLevelType.h
Line
Count
Source (jump to first uncovered line)
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
7.54M
  static LLT scalar(unsigned SizeInBits) {
52
7.54M
    assert(SizeInBits > 0 && "invalid scalar size");
53
7.54M
    return LLT{Scalar, 1, SizeInBits};
54
7.54M
  }
55
56
  /// Get a low-level pointer in the given address space (defaulting to 0).
57
2.15M
  static LLT pointer(uint16_t AddressSpace, unsigned SizeInBits) {
58
2.15M
    return LLT{Pointer, AddressSpace, SizeInBits};
59
2.15M
  }
60
61
  /// Get a low-level vector of some number of elements and element width.
62
  /// \p NumElements must be at least 2.
63
296k
  static LLT vector(uint16_t NumElements, unsigned ScalarSizeInBits) {
64
296k
    assert(NumElements > 1 && "invalid number of vector elements");
65
296k
    return LLT{Vector, NumElements, ScalarSizeInBits};
66
296k
  }
67
68
  /// Get a low-level vector of some number of elements and element type.
69
0
  static LLT vector(uint16_t NumElements, LLT ScalarTy) {
70
0
    assert(NumElements > 1 && "invalid number of vector elements");
71
0
    assert(ScalarTy.isScalar() && "invalid vector element type");
72
0
    return LLT{Vector, NumElements, ScalarTy.getSizeInBits()};
73
0
  }
74
75
  explicit LLT(TypeKind Kind, uint16_t NumElements, unsigned SizeInBits)
76
67.6M
    : SizeInBits(SizeInBits), ElementsOrAddrSpace(NumElements), Kind(Kind) {
77
67.6M
    assert((Kind != Vector || ElementsOrAddrSpace > 1) &&
78
67.6M
           "invalid number of vector elements");
79
67.6M
  }
80
81
21.7M
  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
7.80M
  bool isValid() const { return Kind != Invalid; }
89
90
31.4M
  bool isScalar() const { return Kind == Scalar; }
91
92
46.0M
  bool isPointer() const { return Kind == Pointer; }
93
94
17.8M
  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
601k
  uint16_t getNumElements() const {
99
601k
    assert(isVector() && "cannot get number of elements on scalar/aggregate");
100
601k
    return ElementsOrAddrSpace;
101
601k
  }
102
103
  /// Returns the total size of the type. Must only be called on sized types.
104
45.8M
  unsigned getSizeInBits() const {
105
45.8M
    if (
isPointer() || 45.8M
isScalar()31.2M
)
106
45.8M
      return SizeInBits;
107
4.83k
    return SizeInBits * ElementsOrAddrSpace;
108
45.8M
  }
109
110
11.6k
  unsigned getScalarSizeInBits() const {
111
11.6k
    return SizeInBits;
112
11.6k
  }
113
114
1.49M
  unsigned getAddressSpace() const {
115
1.49M
    assert(isPointer() && "cannot get address space of non-pointer type");
116
1.49M
    return ElementsOrAddrSpace;
117
1.49M
  }
118
119
  /// Returns the vector's element type. Only valid for vector types.
120
601k
  LLT getElementType() const {
121
601k
    assert(isVector() && "cannot get element type of scalar/aggregate");
122
601k
    return scalar(SizeInBits);
123
601k
  }
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
10.2k
  LLT halfScalarSize() const {
129
10.2k
    assert(!isPointer() && getScalarSizeInBits() > 1 &&
130
10.2k
           getScalarSizeInBits() % 2 == 0 && "cannot half size of this type");
131
10.2k
    return LLT{Kind, ElementsOrAddrSpace, SizeInBits / 2};
132
10.2k
  }
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
584k
  LLT doubleScalarSize() const {
138
584k
    assert(!isPointer() && "cannot change size of this type");
139
584k
    return LLT{Kind, ElementsOrAddrSpace, SizeInBits * 2};
140
584k
  }
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
25
  LLT halfElements() const {
147
25
    assert(isVector() && ElementsOrAddrSpace % 2 == 0 &&
148
25
           "cannot half odd vector");
149
25
    if (ElementsOrAddrSpace == 2)
150
5
      return scalar(SizeInBits);
151
25
152
20
    return LLT{Vector, static_cast<uint16_t>(ElementsOrAddrSpace / 2),
153
20
               SizeInBits};
154
25
  }
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
27
  LLT doubleElements() const {
161
27
    assert(!isPointer() && "cannot double elements in pointer");
162
27
    return LLT{Vector, static_cast<uint16_t>(ElementsOrAddrSpace * 2),
163
27
               SizeInBits};
164
27
  }
165
166
  void print(raw_ostream &OS) const;
167
168
182M
  bool operator==(const LLT &RHS) const {
169
131M
    return Kind == RHS.Kind && SizeInBits == RHS.SizeInBits &&
170
111M
           ElementsOrAddrSpace == RHS.ElementsOrAddrSpace;
171
182M
  }
172
173
3.74M
  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
13.1k
inline raw_ostream& operator<<(raw_ostream &OS, const LLT &Ty) {
183
13.1k
  Ty.print(OS);
184
13.1k
  return OS;
185
13.1k
}
186
187
template<> struct DenseMapInfo<LLT> {
188
31.3M
  static inline LLT getEmptyKey() {
189
31.3M
    return LLT{LLT::Invalid, 0, -1u};
190
31.3M
  }
191
25.6M
  static inline LLT getTombstoneKey() {
192
25.6M
    return LLT{LLT::Invalid, 0, -2u};
193
25.6M
  }
194
20.0M
  static inline unsigned getHashValue(const LLT &Ty) {
195
20.0M
    uint64_t Val = ((uint64_t)Ty.SizeInBits << 32) |
196
20.0M
                   ((uint64_t)Ty.ElementsOrAddrSpace << 16) | (uint64_t)Ty.Kind;
197
20.0M
    return DenseMapInfo<uint64_t>::getHashValue(Val);
198
20.0M
  }
199
175M
  static bool isEqual(const LLT &LHS, const LLT &RHS) {
200
175M
    return LHS == RHS;
201
175M
  }
202
};
203
204
}
205
206
#endif