Skip to content

Commit 7d0773b

Browse files
authored
Revert "Make STLExtras's (all|any|none)_of() Utility Functions Constexpr-Friendly" (#173163)
Reverts #172536. This is causing weird assertion failures in clang, per #172536 (comment). It might be a bug in GCC, but still makes sense to revert it in the interest of bootstrapping. --------- Signed-off-by: Michał Górny <[email protected]>
1 parent 5b606bd commit 7d0773b

File tree

4 files changed

+23
-306
lines changed

4 files changed

+23
-306
lines changed

llvm/include/llvm/ADT/Bitset.h

Lines changed: 15 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
#ifndef LLVM_ADT_BITSET_H
1717
#define LLVM_ADT_BITSET_H
1818

19-
#include "llvm/ADT/STLExtras.h"
2019
#include <array>
2120
#include <climits>
2221
#include <cstdint>
22+
#include <llvm/ADT/STLExtras.h>
2323

2424
namespace llvm {
2525

@@ -31,27 +31,16 @@ class Bitset {
3131
using BitWord = uintptr_t;
3232

3333
static constexpr unsigned BitwordBits = sizeof(BitWord) * CHAR_BIT;
34-
static constexpr unsigned RemainderNumBits = NumBits % BitwordBits;
35-
static constexpr BitWord RemainderMask =
36-
RemainderNumBits == 0 ? ~BitWord(0)
37-
: ((BitWord(1) << RemainderNumBits) - 1);
3834

3935
static_assert(BitwordBits == 64 || BitwordBits == 32,
4036
"Unsupported word size");
4137

4238
static constexpr unsigned NumWords =
4339
(NumBits + BitwordBits - 1) / BitwordBits;
4440

45-
// Returns the index of the last word (0-based). The last word may be
46-
// partially filled and requires masking to maintain the invariant that
47-
// unused high bits are always zero.
48-
static constexpr unsigned getLastWordIndex() { return NumWords - 1; }
49-
5041
using StorageType = std::array<BitWord, NumWords>;
5142
StorageType Bits{};
5243

53-
constexpr void maskLastWord() { Bits[getLastWordIndex()] &= RemainderMask; }
54-
5544
protected:
5645
constexpr Bitset(const std::array<uint64_t, (NumBits + 63) / 64> &B) {
5746
if constexpr (sizeof(BitWord) == sizeof(uint64_t)) {
@@ -63,13 +52,12 @@ class Bitset {
6352
uint64_t Elt = B[I];
6453
// On a 32-bit system the storage type will be 32-bit, so we may only
6554
// need half of a uint64_t.
66-
for (size_t Offset = 0; Offset != 2 && BitsToAssign; ++Offset) {
67-
Bits[2 * I + Offset] = static_cast<uint32_t>(Elt >> (32 * Offset));
55+
for (size_t offset = 0; offset != 2 && BitsToAssign; ++offset) {
56+
Bits[2 * I + offset] = static_cast<uint32_t>(Elt >> (32 * offset));
6857
BitsToAssign = BitsToAssign >= 32 ? BitsToAssign - 32 : 0;
6958
}
7059
}
7160
}
72-
maskLastWord();
7361
}
7462

7563
public:
@@ -79,11 +67,8 @@ class Bitset {
7967
set(I);
8068
}
8169

82-
constexpr Bitset &set() {
83-
constexpr const BitWord AllOnes = ~BitWord(0);
84-
for (BitWord &B : Bits)
85-
B = AllOnes;
86-
maskLastWord();
70+
Bitset &set() {
71+
llvm::fill(Bits, -BitWord(0));
8772
return *this;
8873
}
8974

@@ -111,24 +96,14 @@ class Bitset {
11196

11297
constexpr size_t size() const { return NumBits; }
11398

114-
constexpr bool any() const {
99+
bool any() const {
115100
return llvm::any_of(Bits, [](BitWord I) { return I != 0; });
116101
}
117-
118-
constexpr bool none() const { return !any(); }
119-
120-
constexpr bool all() const {
121-
constexpr const BitWord AllOnes = ~BitWord(0);
122-
for (unsigned I = 0; I < getLastWordIndex(); ++I)
123-
if (Bits[I] != AllOnes)
124-
return false;
125-
return Bits[getLastWordIndex()] == RemainderMask;
126-
}
127-
128-
constexpr size_t count() const {
102+
bool none() const { return !any(); }
103+
size_t count() const {
129104
size_t Count = 0;
130-
for (BitWord Word : Bits)
131-
Count += popcount(Word);
105+
for (auto B : Bits)
106+
Count += llvm::popcount(B);
132107
return Count;
133108
}
134109

@@ -169,22 +144,18 @@ class Bitset {
169144

170145
constexpr Bitset operator~() const {
171146
Bitset Result = *this;
172-
for (BitWord &B : Result.Bits)
147+
for (auto &B : Result.Bits)
173148
B = ~B;
174-
Result.maskLastWord();
175149
return Result;
176150
}
177151

178-
constexpr bool operator==(const Bitset &RHS) const {
179-
for (unsigned I = 0; I < NumWords; ++I)
180-
if (Bits[I] != RHS.Bits[I])
181-
return false;
182-
return true;
152+
bool operator==(const Bitset &RHS) const {
153+
return std::equal(std::begin(Bits), std::end(Bits), std::begin(RHS.Bits));
183154
}
184155

185-
constexpr bool operator!=(const Bitset &RHS) const { return !(*this == RHS); }
156+
bool operator!=(const Bitset &RHS) const { return !(*this == RHS); }
186157

187-
constexpr bool operator<(const Bitset &Other) const {
158+
bool operator<(const Bitset &Other) const {
188159
for (unsigned I = 0, E = size(); I != E; ++I) {
189160
bool LHS = test(I), RHS = Other.test(I);
190161
if (LHS != RHS)

llvm/include/llvm/ADT/STLExtras.h

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -638,10 +638,10 @@ make_early_inc_range(RangeT &&Range) {
638638

639639
// Forward declarations required by zip_shortest/zip_equal/zip_first/zip_longest
640640
template <typename R, typename UnaryPredicate>
641-
constexpr bool all_of(R &&range, UnaryPredicate P);
641+
bool all_of(R &&range, UnaryPredicate P);
642642

643643
template <typename R, typename UnaryPredicate>
644-
constexpr bool any_of(R &&range, UnaryPredicate P);
644+
bool any_of(R &&range, UnaryPredicate P);
645645

646646
template <typename T> bool all_equal(std::initializer_list<T> Values);
647647

@@ -1734,31 +1734,22 @@ UnaryFunction for_each(R &&Range, UnaryFunction F) {
17341734
/// Provide wrappers to std::all_of which take ranges instead of having to pass
17351735
/// begin/end explicitly.
17361736
template <typename R, typename UnaryPredicate>
1737-
constexpr bool all_of(R &&Range, UnaryPredicate P) {
1738-
// TODO: switch back to std::all_of() after it becomes constexpr in c++20.
1739-
for (auto I = adl_begin(Range), E = adl_end(Range); I != E; ++I)
1740-
if (!P(*I))
1741-
return false;
1742-
return true;
1737+
bool all_of(R &&Range, UnaryPredicate P) {
1738+
return std::all_of(adl_begin(Range), adl_end(Range), P);
17431739
}
17441740

17451741
/// Provide wrappers to std::any_of which take ranges instead of having to pass
17461742
/// begin/end explicitly.
17471743
template <typename R, typename UnaryPredicate>
1748-
constexpr bool any_of(R &&Range, UnaryPredicate P) {
1749-
// TODO: switch back to std::any_of() after it becomes constexpr in c++20.
1750-
for (auto I = adl_begin(Range), E = adl_end(Range); I != E; ++I)
1751-
if (P(*I))
1752-
return true;
1753-
return false;
1744+
bool any_of(R &&Range, UnaryPredicate P) {
1745+
return std::any_of(adl_begin(Range), adl_end(Range), P);
17541746
}
17551747

17561748
/// Provide wrappers to std::none_of which take ranges instead of having to pass
17571749
/// begin/end explicitly.
17581750
template <typename R, typename UnaryPredicate>
1759-
constexpr bool none_of(R &&Range, UnaryPredicate P) {
1760-
// TODO: switch back to std::none_of() after it becomes constexpr in c++20.
1761-
return !any_of(Range, P);
1751+
bool none_of(R &&Range, UnaryPredicate P) {
1752+
return std::none_of(adl_begin(Range), adl_end(Range), P);
17621753
}
17631754

17641755
/// Provide wrappers to std::fill which take ranges instead of having to pass

0 commit comments

Comments
 (0)