Go to the documentation of this file.
79 #ifndef LLVM_ADT_BITFIELDS_H
80 #define LLVM_ADT_BITFIELDS_H
87 #include <type_traits>
91 namespace bitfields_details {
100 static_assert(
sizeof(
Unsigned) ==
sizeof(T),
"Types must have same size");
120 template <typename T, unsigned Bits, bool = std::is_unsigned<T>::value>
122 static_assert(std::is_unsigned<T>::value,
"T is unsigned");
125 static T pack(T UserValue, T UserMaxValue) {
126 assert(UserValue <= UserMaxValue &&
"value is too big");
131 static T unpack(T StorageValue) {
return StorageValue; }
135 static_assert(std::is_signed<T>::value,
"T is signed");
138 static T pack(T UserValue, T UserMaxValue) {
139 assert(UserValue <= UserMaxValue &&
"value is too big");
143 UserValue &= ~
BP::SignExtend;
156 template <
typename Bitfield,
typename StorageType>
struct Impl {
157 static_assert(std::is_unsigned<StorageType>::value,
158 "Storage must be unsigned");
163 static constexpr
size_t StorageBits =
sizeof(StorageType) * CHAR_BIT;
164 static_assert(Bitfield::FirstBit <=
StorageBits,
"Data must fit in mask");
165 static_assert(Bitfield::LastBit <=
StorageBits,
"Data must fit in mask");
171 const StorageType StorageValue =
C::pack(UserValue, Bitfield::UserMaxValue);
185 static StorageType
test(StorageType Packed) {
return Packed &
Mask; }
196 template <typename T, bool = std::is_enum<T>::value>
206 using type = std::conditional<
sizeof(bool) == 1, uint8_t,
void>::
type;
219 template <
typename T,
unsigned Offset,
unsigned Size,
220 T MaxValue = std::is_enum<T>::value
227 static constexpr
unsigned Shift = Offset;
228 static constexpr
unsigned Bits = Size;
236 static_assert(
Bits > 0,
"Bits must be non zero");
237 static constexpr
size_t TypeBits =
sizeof(
IntegerType) * CHAR_BIT;
238 static_assert(
Bits <= TypeBits,
"Bits may not be greater than T size");
239 static_assert(!std::is_enum<T>::value || MaxValue !=
T(0),
240 "Enum Bitfields must provide a MaxValue");
241 static_assert(!std::is_enum<T>::value ||
242 std::is_unsigned<IntegerType>::value,
243 "Enum must be unsigned");
244 static_assert(std::is_integral<IntegerType>::value &&
245 std::numeric_limits<IntegerType>::is_integer,
246 "IntegerType must be an integer type");
253 template <
typename Bitfield,
typename StorageType>
261 template <
typename Bitfield,
typename StorageType>
262 static StorageType
test(StorageType Packed) {
269 template <
typename Bitfield,
typename StorageType>
272 I::update(Packed,
static_cast<typename Bitfield::IntegerType
>(
Value));
277 return A::LastBit >= B::FirstBit && B::LastBit >= A::FirstBit;
280 template <
typename A>
static constexpr
bool areContiguous() {
return true; }
281 template <
typename A,
typename B,
typename... Others>
283 return A::NextBit == B::FirstBit &&
areContiguous<
B, Others...>();
289 #endif // LLVM_ADT_BITFIELDS_H
static constexpr unsigned LastBit
static T pack(T UserValue, T UserMaxValue)
This is an optimization pass for GlobalISel generic memory operations.
static void update(StorageType &Packed, IntegerType UserValue)
Checks UserValue is within bounds and packs it between FirstBit and LastBit of Packed leaving the res...
static T pack(T UserValue, T UserMaxValue)
typename bitfields_details::ResolveUnderlyingType< T >::type IntegerType
static constexpr Unsigned Umin
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
static constexpr unsigned Bits
static constexpr size_t StorageBits
Holds functions to get, set or test bitfields.
static constexpr unsigned FirstBit
static T unpack(T StorageValue)
static constexpr StorageType Mask
Compressor is used to manipulate the bits of a (possibly signed) integer type so it can be packed and...
static constexpr Unsigned Smax
static constexpr Unsigned Umax
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
std::conditional< sizeof(bool)==1, uint8_t, void >::type type
In case sizeof(bool) != 1, replace void by an additionnal std::conditional.
typename std::underlying_type< T >::type type
static constexpr Unsigned Smin
static constexpr bool areContiguous()
static T unpack(T StorageValue)
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx rax ret instead of xmm1 cvttss2siq rcx movaps xmm2 subss xmm2 cvttss2siq rax rdx xorq rax ucomiss xmm0 cmovb rax ret Seems like the jb branch has high likelihood of being taken It would have saved a few instructions It s not possible to reference and DH registers in an instruction requiring REX prefix divb and mulb both produce results in AH If isel emits a CopyFromReg which gets turned into a movb and that can be allocated a r8b r15b To get around isel emits a CopyFromReg from AX and then right shift it down by and truncate it It s not pretty but it works We need some register allocation magic to make the hack go which would often require a callee saved register Callees usually need to keep this value live for most of their body so it doesn t add a significant burden on them We currently implement this in however this is suboptimal because it means that it would be quite awkward to implement the optimization for callers A better implementation would be to relax the LLVM IR rules for sret arguments to allow a function with an sret argument to have a non void return type
static constexpr bool isOverlapping()
Returns whether the two bitfields share common bits.
static constexpr bool areContiguous()
static Bitfield::Type get(StorageType Packed)
Unpacks the field from the Packed value.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static StorageType test(StorageType Packed)
Return a non-zero value if the field is non-zero.
Impl is where Bifield description and Storage are put together to interact with values.
static constexpr unsigned Shift
static void set(StorageType &Packed, typename Bitfield::Type Value)
Sets the typed value in the provided Packed value.
static constexpr unsigned NextBit
typename Bitfield::IntegerType IntegerType
Bitfield deals with the following type:
typename std::make_unsigned< T >::type Unsigned
Bit patterns are forged using the equivalent Unsigned type because of undefined operations over signe...
static StorageType test(StorageType Packed)
Interprets bits between FirstBit and LastBit of Packed as anIntegerType.
A struct defining useful bit patterns for n-bits integer types.
Describes an element of a Bitfield.
static constexpr Unsigned SignBitMask
static constexpr Unsigned AllZeros
e.g. with TypeBits == 8 and Bits == 6.
Type
MessagePack types as defined in the standard, with the exception of Integer being divided into a sign...
static constexpr unsigned TypeBits
static constexpr Unsigned SignExtend
static constexpr Unsigned AllOnes
static IntegerType extract(StorageType Packed)
Interprets bits between FirstBit and LastBit of Packed as anIntegerType.
LLVM Value Representation.