LLVM  10.0.0svn
TypeSize.h
Go to the documentation of this file.
1 //===- TypeSize.h - Wrapper around type sizes -------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file provides a struct that can be used to query the size of IR types
10 // which may be scalable vectors. It provides convenience operators so that
11 // it can be used in much the same way as a single scalar value.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_SUPPORT_TYPESIZE_H
16 #define LLVM_SUPPORT_TYPESIZE_H
17 
18 #include <cassert>
19 #include <tuple>
20 
21 namespace llvm {
22 
23 class ElementCount {
24 public:
25  unsigned Min; // Minimum number of vector elements.
26  bool Scalable; // If true, NumElements is a multiple of 'Min' determined
27  // at runtime rather than compile time.
28 
29  ElementCount(unsigned Min, bool Scalable)
30  : Min(Min), Scalable(Scalable) {}
31 
32  ElementCount operator*(unsigned RHS) {
33  return { Min * RHS, Scalable };
34  }
35  ElementCount operator/(unsigned RHS) {
36  return { Min / RHS, Scalable };
37  }
38 
39  bool operator==(const ElementCount& RHS) const {
40  return Min == RHS.Min && Scalable == RHS.Scalable;
41  }
42  bool operator!=(const ElementCount& RHS) const {
43  return !(*this == RHS);
44  }
45 };
46 
47 // This class is used to represent the size of types. If the type is of fixed
48 // size, it will represent the exact size. If the type is a scalable vector,
49 // it will represent the known minimum size.
50 class TypeSize {
51  uint64_t MinSize; // The known minimum size.
52  bool IsScalable; // If true, then the runtime size is an integer multiple
53  // of MinSize.
54 
55 public:
56  constexpr TypeSize(uint64_t MinSize, bool Scalable)
57  : MinSize(MinSize), IsScalable(Scalable) {}
58 
59  static constexpr TypeSize Fixed(uint64_t Size) {
60  return TypeSize(Size, /*IsScalable=*/false);
61  }
62 
63  static constexpr TypeSize Scalable(uint64_t MinSize) {
64  return TypeSize(MinSize, /*IsScalable=*/true);
65  }
66 
67  // Scalable vector types with the same minimum size as a fixed size type are
68  // not guaranteed to be the same size at runtime, so they are never
69  // considered to be equal.
70  friend bool operator==(const TypeSize &LHS, const TypeSize &RHS) {
71  return std::tie(LHS.MinSize, LHS.IsScalable) ==
72  std::tie(RHS.MinSize, RHS.IsScalable);
73  }
74 
75  friend bool operator!=(const TypeSize &LHS, const TypeSize &RHS) {
76  return !(LHS == RHS);
77  }
78 
79  // For many cases, size ordering between scalable and fixed size types cannot
80  // be determined at compile time, so such comparisons aren't allowed.
81  //
82  // e.g. <vscale x 2 x i16> could be bigger than <4 x i32> with a runtime
83  // vscale >= 5, equal sized with a vscale of 4, and smaller with
84  // a vscale <= 3.
85  //
86  // If the scalable flags match, just perform the requested comparison
87  // between the minimum sizes.
88  friend bool operator<(const TypeSize &LHS, const TypeSize &RHS) {
89  assert(LHS.IsScalable == RHS.IsScalable &&
90  "Ordering comparison of scalable and fixed types");
91 
92  return LHS.MinSize < RHS.MinSize;
93  }
94 
95  friend bool operator>(const TypeSize &LHS, const TypeSize &RHS) {
96  return RHS < LHS;
97  }
98 
99  friend bool operator<=(const TypeSize &LHS, const TypeSize &RHS) {
100  return !(RHS < LHS);
101  }
102 
103  friend bool operator>=(const TypeSize &LHS, const TypeSize& RHS) {
104  return !(LHS < RHS);
105  }
106 
107  // Convenience operators to obtain relative sizes independently of
108  // the scalable flag.
109  TypeSize operator*(unsigned RHS) const {
110  return { MinSize * RHS, IsScalable };
111  }
112 
113  friend TypeSize operator*(const unsigned LHS, const TypeSize &RHS) {
114  return { LHS * RHS.MinSize, RHS.IsScalable };
115  }
116 
117  TypeSize operator/(unsigned RHS) const {
118  return { MinSize / RHS, IsScalable };
119  }
120 
121  // Return the minimum size with the assumption that the size is exact.
122  // Use in places where a scalable size doesn't make sense (e.g. non-vector
123  // types, or vectors in backends which don't support scalable vectors).
124  uint64_t getFixedSize() const {
125  assert(!IsScalable && "Request for a fixed size on a scalable object");
126  return MinSize;
127  }
128 
129  // Return the known minimum size. Use in places where the scalable property
130  // doesn't matter (e.g. determining alignment) or in conjunction with the
131  // isScalable method below.
132  uint64_t getKnownMinSize() const {
133  return MinSize;
134  }
135 
136  // Return whether or not the size is scalable.
137  bool isScalable() const {
138  return IsScalable;
139  }
140 
141  // Casts to a uint64_t if this is a fixed-width size.
142  //
143  // NOTE: This interface is obsolete and will be removed in a future version
144  // of LLVM in favour of calling getFixedSize() directly.
145  operator uint64_t() const {
146  return getFixedSize();
147  }
148 
149  // Additional convenience operators needed to avoid ambiguous parses.
150  // TODO: Make uint64_t the default operator?
151  TypeSize operator*(uint64_t RHS) const {
152  return { MinSize * RHS, IsScalable };
153  }
154 
155  TypeSize operator*(int RHS) const {
156  return { MinSize * RHS, IsScalable };
157  }
158 
159  TypeSize operator*(int64_t RHS) const {
160  return { MinSize * RHS, IsScalable };
161  }
162 
163  friend TypeSize operator*(const uint64_t LHS, const TypeSize &RHS) {
164  return { LHS * RHS.MinSize, RHS.IsScalable };
165  }
166 
167  friend TypeSize operator*(const int LHS, const TypeSize &RHS) {
168  return { LHS * RHS.MinSize, RHS.IsScalable };
169  }
170 
171  friend TypeSize operator*(const int64_t LHS, const TypeSize &RHS) {
172  return { LHS * RHS.MinSize, RHS.IsScalable };
173  }
174 
175  TypeSize operator/(uint64_t RHS) const {
176  return { MinSize / RHS, IsScalable };
177  }
178 
179  TypeSize operator/(int RHS) const {
180  return { MinSize / RHS, IsScalable };
181  }
182 
183  TypeSize operator/(int64_t RHS) const {
184  return { MinSize / RHS, IsScalable };
185  }
186 };
187 
188 /// Returns a TypeSize with a known minimum size that is the next integer
189 /// (mod 2**64) that is greater than or equal to \p Value and is a multiple
190 /// of \p Align. \p Align must be non-zero.
191 ///
192 /// Similar to the alignTo functions in MathExtras.h
193 inline TypeSize alignTo(TypeSize Size, uint64_t Align) {
194  assert(Align != 0u && "Align must be non-zero");
195  return {(Size.getKnownMinSize() + Align - 1) / Align * Align,
196  Size.isScalable()};
197 }
198 
199 } // end namespace llvm
200 
201 #endif // LLVM_SUPPORT_TypeSize_H
bool isScalable() const
Definition: TypeSize.h:137
friend bool operator!=(const TypeSize &LHS, const TypeSize &RHS)
Definition: TypeSize.h:75
This class represents lattice values for constants.
Definition: AllocatorList.h:23
TypeSize operator/(uint64_t RHS) const
Definition: TypeSize.h:175
TypeSize operator*(int64_t RHS) const
Definition: TypeSize.h:159
TypeSize operator*(unsigned RHS) const
Definition: TypeSize.h:109
friend bool operator<=(const TypeSize &LHS, const TypeSize &RHS)
Definition: TypeSize.h:99
static constexpr TypeSize Scalable(uint64_t MinSize)
Definition: TypeSize.h:63
unsigned Min
Definition: TypeSize.h:25
bool operator!=(const ElementCount &RHS) const
Definition: TypeSize.h:42
friend TypeSize operator*(const unsigned LHS, const TypeSize &RHS)
Definition: TypeSize.h:113
friend bool operator<(const TypeSize &LHS, const TypeSize &RHS)
Definition: TypeSize.h:88
friend bool operator>=(const TypeSize &LHS, const TypeSize &RHS)
Definition: TypeSize.h:103
TypeSize operator*(uint64_t RHS) const
Definition: TypeSize.h:151
uint64_t getFixedSize() const
Definition: TypeSize.h:124
friend TypeSize operator*(const int LHS, const TypeSize &RHS)
Definition: TypeSize.h:167
friend TypeSize operator*(const uint64_t LHS, const TypeSize &RHS)
Definition: TypeSize.h:163
ElementCount operator*(unsigned RHS)
Definition: TypeSize.h:32
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:40
TypeSize operator*(int RHS) const
Definition: TypeSize.h:155
friend bool operator==(const TypeSize &LHS, const TypeSize &RHS)
Definition: TypeSize.h:70
ElementCount(unsigned Min, bool Scalable)
Definition: TypeSize.h:29
friend bool operator>(const TypeSize &LHS, const TypeSize &RHS)
Definition: TypeSize.h:95
static constexpr TypeSize Fixed(uint64_t Size)
Definition: TypeSize.h:59
TypeSize operator/(int RHS) const
Definition: TypeSize.h:179
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:163
uint64_t getKnownMinSize() const
Definition: TypeSize.h:132
bool operator==(const ElementCount &RHS) const
Definition: TypeSize.h:39
uint32_t Size
Definition: Profile.cpp:46
TypeSize operator/(int64_t RHS) const
Definition: TypeSize.h:183
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
TypeSize operator/(unsigned RHS) const
Definition: TypeSize.h:117
constexpr TypeSize(uint64_t MinSize, bool Scalable)
Definition: TypeSize.h:56
friend TypeSize operator*(const int64_t LHS, const TypeSize &RHS)
Definition: TypeSize.h:171
ElementCount operator/(unsigned RHS)
Definition: TypeSize.h:35