LLVM 20.0.0git
Classes | Namespaces
Bitfields.h File Reference

This file implements methods to test, set and extract typed bits from packed unsigned integers. More...

#include <cassert>
#include <climits>
#include <cstddef>
#include <cstdint>
#include <limits>
#include <type_traits>

Go to the source code of this file.

Classes

struct  llvm::bitfields_details::BitPatterns< T, Bits >
 A struct defining useful bit patterns for n-bits integer types. More...
 
struct  llvm::bitfields_details::Compressor< T, Bits, bool >
 Compressor is used to manipulate the bits of a (possibly signed) integer type so it can be packed and unpacked into a bits sized integer, Compressor is specialized on signed-ness so no runtime cost is incurred. More...
 
struct  llvm::bitfields_details::Compressor< T, Bits, false >
 
struct  llvm::bitfields_details::Impl< Bitfield, StorageType >
 Impl is where Bifield description and Storage are put together to interact with values. More...
 
struct  llvm::bitfields_details::ResolveUnderlyingType< T, bool >
 Bitfield deals with the following type: More...
 
struct  llvm::bitfields_details::ResolveUnderlyingType< T, false >
 
struct  llvm::bitfields_details::ResolveUnderlyingType< bool, false >
 
struct  llvm::Bitfield
 Holds functions to get, set or test bitfields. More...
 
struct  llvm::Bitfield::Element< T, Offset, Size, MaxValue >
 Describes an element of a Bitfield. More...
 

Namespaces

namespace  llvm
 This is an optimization pass for GlobalISel generic memory operations.
 
namespace  llvm::bitfields_details
 

Detailed Description

This file implements methods to test, set and extract typed bits from packed unsigned integers.

Why not C++ bitfields?

C++ bitfields do not offer control over the bit layout nor consistent behavior when it comes to out of range values. For instance, the layout is implementation defined and adjacent bits may be packed together but are not required to. This is problematic when storage is sparse and data must be stored in a particular integer type.

The methods provided in this file ensure precise control over the layout/storage as well as protection against out of range values.

Usage example

uint8_t Storage = 0;
// Store and retrieve a single bit as bool.
using Bool = Bitfield::Element<bool, 0, 1>;
Bitfield::set<Bool>(Storage, true);
EXPECT_EQ(Storage, 0b00000001);
// ^
EXPECT_EQ(Bitfield::get<Bool>(Storage), true);
// Store and retrieve a 2 bit typed enum.
// Note: enum underlying type must be unsigned.
enum class SuitEnum : uint8_t { CLUBS, DIAMONDS, HEARTS, SPADES };
// Note: enum maximum value needs to be passed in as last parameter.
using Suit = Bitfield::Element<SuitEnum, 1, 2, SuitEnum::SPADES>;
Bitfield::set<Suit>(Storage, SuitEnum::HEARTS);
EXPECT_EQ(Storage, 0b00000101);
// ^^
EXPECT_EQ(Bitfield::get<Suit>(Storage), SuitEnum::HEARTS);
// Store and retrieve a 5 bit value as unsigned.
using Value = Bitfield::Element<unsigned, 3, 5>;
Bitfield::set<Value>(Storage, 10);
EXPECT_EQ(Storage, 0b01010101);
// ^^^^^
EXPECT_EQ(Bitfield::get<Value>(Storage), 10U);
// Interpret the same 5 bit value as signed.
using SignedValue = Bitfield::Element<int, 3, 5>;
Bitfield::set<SignedValue>(Storage, -2);
EXPECT_EQ(Storage, 0b11110101);
// ^^^^^
EXPECT_EQ(Bitfield::get<SignedValue>(Storage), -2);
// Ability to efficiently test if a field is non zero.
EXPECT_TRUE(Bitfield::test<Value>(Storage));
// Alter Storage changes value.
Storage = 0;
EXPECT_EQ(Bitfield::get<Bool>(Storage), false);
EXPECT_EQ(Bitfield::get<Suit>(Storage), SuitEnum::CLUBS);
EXPECT_EQ(Bitfield::get<Value>(Storage), 0U);
EXPECT_EQ(Bitfield::get<SignedValue>(Storage), 0);
Storage = 255;
EXPECT_EQ(Bitfield::get<Bool>(Storage), true);
EXPECT_EQ(Bitfield::get<Suit>(Storage), SuitEnum::SPADES);
EXPECT_EQ(Bitfield::get<Value>(Storage), 31U);
EXPECT_EQ(Bitfield::get<SignedValue>(Storage), -1);

Definition in file Bitfields.h.