LLVM 22.0.0git
PackedVector.h
Go to the documentation of this file.
1//===- llvm/ADT/PackedVector.h - Packed values vector -----------*- 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/// \file
10/// This file implements the PackedVector class.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ADT_PACKEDVECTOR_H
15#define LLVM_ADT_PACKEDVECTOR_H
16
17#include "llvm/ADT/BitVector.h"
18#include <cassert>
19#include <limits>
20
21namespace llvm {
22
23/// Store a vector of values using a specific number of bits for each
24/// value. Both signed and unsigned types can be used, e.g
25/// @code
26/// PackedVector<signed, 2> vec;
27/// @endcode
28/// will create a vector accepting values -2, -1, 0, 1. Any other value will hit
29/// an assertion.
30template <typename T, unsigned BitNum, typename BitVectorTy = BitVector>
32 static_assert(BitNum > 0, "BitNum must be > 0");
33
34 BitVectorTy Bits;
35 // Keep track of the number of elements on our own.
36 // We always maintain Bits.size() == NumElements * BitNum.
37 // Used to avoid an integer division in size().
38 unsigned NumElements = 0;
39
40 static T getValue(const BitVectorTy &Bits, unsigned Idx) {
41 if constexpr (std::numeric_limits<T>::is_signed) {
42 T val = T();
43 for (unsigned i = 0; i != BitNum - 1; ++i)
44 val = T(val | ((Bits[(Idx * BitNum) + i] ? 1UL : 0UL) << i));
45 if (Bits[(Idx * BitNum) + BitNum - 1])
46 val = ~val;
47 return val;
48 } else {
49 T val = T();
50 for (unsigned i = 0; i != BitNum; ++i)
51 val = T(val | ((Bits[(Idx * BitNum) + i] ? 1UL : 0UL) << i));
52 return val;
53 }
54 }
55
56 static void setValue(BitVectorTy &Bits, unsigned Idx, T val) {
57 if constexpr (std::numeric_limits<T>::is_signed) {
58 if (val < 0) {
59 val = ~val;
60 Bits.set((Idx * BitNum) + BitNum - 1);
61 } else {
62 Bits.reset((Idx * BitNum) + BitNum - 1);
63 }
64 assert((val >> (BitNum - 1)) == 0 && "value is too big");
65 for (unsigned i = 0; i != BitNum - 1; ++i)
66 Bits[(Idx * BitNum) + i] = val & (T(1) << i);
67 } else {
68 assert((val >> BitNum) == 0 && "value is too big");
69 for (unsigned i = 0; i != BitNum; ++i)
70 Bits[(Idx * BitNum) + i] = val & (T(1) << i);
71 }
72 }
73
74public:
75 class reference {
76 PackedVector &Vec;
77 const unsigned Idx;
78
79 public:
80 reference() = delete;
81 reference(PackedVector &vec, unsigned idx) : Vec(vec), Idx(idx) {}
82
84 Vec.setValue(Vec.Bits, Idx, val);
85 return *this;
86 }
87
88 operator T() const { return Vec.getValue(Vec.Bits, Idx); }
89 };
90
91 PackedVector() = default;
92 explicit PackedVector(unsigned size)
93 : Bits(size * BitNum), NumElements(size) {}
94
95 bool empty() const { return NumElements == 0; }
96
97 unsigned size() const { return NumElements; }
98
99 void clear() {
100 Bits.clear();
101 NumElements = 0;
102 }
103
104 void resize(unsigned N) {
105 Bits.resize(N * BitNum);
106 NumElements = N;
107 }
108
109 void reserve(unsigned N) { Bits.reserve(N * BitNum); }
110
112 Bits.reset();
113 return *this;
114 }
115
116 void push_back(T val) {
117 resize(size() + 1);
118 (*this)[size() - 1] = val;
119 }
120
121 reference operator[](unsigned Idx) { return reference(*this, Idx); }
122
123 T operator[](unsigned Idx) const { return getValue(Bits, Idx); }
124
125 bool operator==(const PackedVector &RHS) const { return Bits == RHS.Bits; }
126
127 bool operator!=(const PackedVector &RHS) const { return Bits != RHS.Bits; }
128
130 Bits |= RHS.Bits;
131 return *this;
132 }
133
134 const BitVectorTy &raw_bits() const { return Bits; }
135 BitVectorTy &raw_bits() { return Bits; }
136};
137
138} // end namespace llvm
139
140#endif // LLVM_ADT_PACKEDVECTOR_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
#define T
Value * RHS
reference(PackedVector &vec, unsigned idx)
reference & operator=(T val)
void resize(unsigned N)
const BitVectorTy & raw_bits() const
PackedVector & reset()
bool empty() const
PackedVector()=default
T operator[](unsigned Idx) const
PackedVector(unsigned size)
void push_back(T val)
BitVectorTy & raw_bits()
PackedVector & operator|=(const PackedVector &RHS)
bool operator!=(const PackedVector &RHS) const
void reserve(unsigned N)
bool operator==(const PackedVector &RHS) const
reference operator[](unsigned Idx)
This is an optimization pass for GlobalISel generic memory operations.
#define N