|
14 | 14 | #ifndef LLVM_ANALYSIS_CACHEDBITSVALUE_H
|
15 | 15 | #define LLVM_ANALYSIS_CACHEDBITSVALUE_H
|
16 | 16 |
|
| 17 | +#include "llvm/ADT/PointerIntPair.h" |
17 | 18 | #include "llvm/IR/Value.h"
|
18 | 19 | #include "llvm/Support/KnownBits.h"
|
19 | 20 | #include <type_traits>
|
@@ -45,75 +46,81 @@ template <bool ConstPointer = true> class ImplCachedBitsValue {
|
45 | 46 | constexpr static bool ValuePointerConvertible =
|
46 | 47 | std::is_convertible_v<T, ValuePointerType>;
|
47 | 48 |
|
48 |
| - ValuePointerType Pointer; |
49 |
| - mutable std::optional<KnownBits> Known; |
| 49 | + // Store the presence of the KnownBits information in one of the bits of |
| 50 | + // Pointer. |
| 51 | + // true -> present |
| 52 | + // false -> absent |
| 53 | + mutable PointerIntPair<ValuePointerType, 1, bool> Pointer; |
| 54 | + mutable KnownBits Known; |
50 | 55 |
|
51 | 56 | void calculateKnownBits(unsigned Depth, const SimplifyQuery &Q) const {
|
52 |
| - Known = computeKnownBits(Pointer, Depth, Q); |
| 57 | + Known = computeKnownBits(Pointer.getPointer(), Depth, Q); |
| 58 | + Pointer.setInt(true); |
53 | 59 | }
|
54 | 60 |
|
55 | 61 | void calculateKnownBits(const APInt &DemandedElts, unsigned Depth,
|
56 | 62 | const SimplifyQuery &Q) const {
|
57 |
| - Known = computeKnownBits(Pointer, DemandedElts, Depth, Q); |
| 63 | + Known = computeKnownBits(Pointer.getPointer(), DemandedElts, Depth, Q); |
| 64 | + Pointer.setInt(false); |
58 | 65 | }
|
59 | 66 |
|
60 | 67 | public:
|
61 | 68 | ImplCachedBitsValue() = default;
|
62 | 69 | ImplCachedBitsValue(ValuePointerType Pointer)
|
63 |
| - : Pointer(Pointer), Known(std::nullopt) {} |
| 70 | + : Pointer(Pointer, false) {} |
64 | 71 | ImplCachedBitsValue(ValuePointerType Pointer, const KnownBits &Known)
|
65 |
| - : Pointer(Pointer), Known(Known) {} |
| 72 | + : Pointer(Pointer, true), Known(Known) {} |
66 | 73 |
|
67 | 74 | template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
|
68 | 75 | ImplCachedBitsValue(const T &Value)
|
69 |
| - : Pointer(static_cast<ValuePointerType>(Value)), Known(std::nullopt) {} |
| 76 | + : Pointer(static_cast<ValuePointerType>(Value), false) {} |
70 | 77 |
|
71 | 78 | template <typename T, std::enable_if_t<ValuePointerConvertible<T>, int> = 0>
|
72 | 79 | ImplCachedBitsValue(const T &Value, const KnownBits &Known)
|
73 |
| - : Pointer(static_cast<ValuePointerType>(Value)), Known(Known) {} |
| 80 | + : Pointer(static_cast<ValuePointerType>(Value), true), Known(Known) {} |
74 | 81 |
|
75 |
| - [[nodiscard]] ValuePointerType getValue() { return Pointer; } |
76 |
| - [[nodiscard]] ValuePointerType getValue() const { return Pointer; } |
| 82 | + [[nodiscard]] ValuePointerType getValue() { return Pointer.getPointer(); } |
| 83 | + [[nodiscard]] ValuePointerType getValue() const { return Pointer.getPointer(); } |
77 | 84 |
|
78 | 85 | [[nodiscard]] const KnownBits &getKnownBits(unsigned Depth,
|
79 | 86 | const SimplifyQuery &Q) const {
|
80 | 87 | if (!hasKnownBits())
|
81 | 88 | calculateKnownBits(Depth, Q);
|
82 |
| - return Known.value(); |
| 89 | + return Known; |
83 | 90 | }
|
84 | 91 |
|
85 | 92 | [[nodiscard]] KnownBits &getKnownBits(unsigned Depth,
|
86 | 93 | const SimplifyQuery &Q) {
|
87 | 94 | if (!hasKnownBits())
|
88 | 95 | calculateKnownBits(Depth, Q);
|
89 |
| - return Known.value(); |
| 96 | + return Known; |
90 | 97 | }
|
91 | 98 |
|
92 | 99 | [[nodiscard]] const KnownBits &getKnownBits(const APInt &DemandedElts,
|
93 | 100 | unsigned Depth,
|
94 | 101 | const SimplifyQuery &Q) const {
|
95 | 102 | if (!hasKnownBits())
|
96 | 103 | calculateKnownBits(DemandedElts, Depth, Q);
|
97 |
| - return Known.value(); |
| 104 | + return Known; |
98 | 105 | }
|
99 | 106 |
|
100 | 107 | [[nodiscard]] KnownBits &getKnownBits(const APInt &DemandedElts,
|
101 | 108 | unsigned Depth,
|
102 | 109 | const SimplifyQuery &Q) {
|
103 | 110 | if (!hasKnownBits())
|
104 | 111 | calculateKnownBits(DemandedElts, Depth, Q);
|
105 |
| - return Known.value(); |
| 112 | + return Known; |
106 | 113 | }
|
107 | 114 |
|
108 |
| - [[nodiscard]] bool hasKnownBits() const { return Known.has_value(); } |
| 115 | + [[nodiscard]] bool hasKnownBits() const { return Pointer.getInt(); } |
109 | 116 |
|
110 |
| - operator ValuePointerType() { return Pointer; } |
111 |
| - ValuePointerType operator->() { return Pointer; } |
112 |
| - ValueReferenceType operator*() { return *Pointer; } |
| 117 | + operator ValuePointerType() { return Pointer.getPointer(); } |
| 118 | + ValuePointerType operator->() { return Pointer.getPointer(); } |
| 119 | + ValueReferenceType operator*() { return *Pointer.getPointer(); } |
113 | 120 |
|
114 |
| - operator ValuePointerType() const { return Pointer; } |
115 |
| - ValuePointerType operator->() const { return Pointer; } |
116 |
| - ValueReferenceType operator*() const { return *Pointer; } |
| 121 | + operator ValuePointerType() const { return Pointer.getPointer(); } |
| 122 | + ValuePointerType operator->() const { return Pointer.getPointer(); } |
| 123 | + ValueReferenceType operator*() const { return *Pointer.getPointer(); } |
117 | 124 | };
|
118 | 125 | } // namespace detail
|
119 | 126 |
|
@@ -151,7 +158,7 @@ class CachedBitsNonConstValue : public detail::ImplCachedBitsValue<false> {
|
151 | 158 |
|
152 | 159 | [[nodiscard]] CachedBitsConstValue toConst() const {
|
153 | 160 | if (hasKnownBits())
|
154 |
| - return CachedBitsConstValue(getValue(), Known.value()); |
| 161 | + return CachedBitsConstValue(getValue(), Known); |
155 | 162 | else
|
156 | 163 | return CachedBitsConstValue(getValue());
|
157 | 164 | }
|
|
0 commit comments