[llvm] r369847 - Use a bit of relaxed constexpr to make FeatureBitset costant intializable
Benjamin Kramer via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 24 08:02:44 PDT 2019
Author: d0k
Date: Sat Aug 24 08:02:44 2019
New Revision: 369847
URL: http://llvm.org/viewvc/llvm-project?rev=369847&view=rev
Log:
Use a bit of relaxed constexpr to make FeatureBitset costant intializable
This requires std::intializer_list to be a literal type, which it is
starting with C++14. The downside is that std::bitset is still not
constexpr-friendly so this change contains a re-implementation of most
of it.
Shrinks clang by ~60k.
Modified:
llvm/trunk/include/llvm/MC/SubtargetFeature.h
llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h
llvm/trunk/lib/Target/Hexagon/HexagonSubtarget.cpp
llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
llvm/trunk/test/TableGen/GlobalISelEmitter.td
llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
llvm/trunk/utils/TableGen/CodeEmitterGen.cpp
llvm/trunk/utils/TableGen/SearchableTableEmitter.cpp
llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp
Modified: llvm/trunk/include/llvm/MC/SubtargetFeature.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/SubtargetFeature.h?rev=369847&r1=369846&r2=369847&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/SubtargetFeature.h (original)
+++ llvm/trunk/include/llvm/MC/SubtargetFeature.h Sat Aug 24 08:02:44 2019
@@ -18,6 +18,7 @@
#define LLVM_MC_SUBTARGETFEATURE_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/MathExtras.h"
#include <array>
#include <bitset>
#include <initializer_list>
@@ -33,20 +34,117 @@ const unsigned MAX_SUBTARGET_WORDS = 3;
const unsigned MAX_SUBTARGET_FEATURES = MAX_SUBTARGET_WORDS * 64;
/// Container class for subtarget features.
-/// This is convenient because std::bitset does not have a constructor
-/// with an initializer list of set bits.
-class FeatureBitset : public std::bitset<MAX_SUBTARGET_FEATURES> {
+/// This is a constexpr reimplementation of a subset of std::bitset. It would be
+/// nice to use std::bitset directly, but it doesn't support constant
+/// initialization.
+class FeatureBitset {
+ static_assert((MAX_SUBTARGET_FEATURES % 64) == 0,
+ "Should be a multiple of 64!");
+ // This cannot be a std::array, operator[] is not constexpr until C++17.
+ uint64_t Bits[MAX_SUBTARGET_WORDS] = {};
+
+protected:
+ constexpr FeatureBitset(const std::array<uint64_t, MAX_SUBTARGET_WORDS> &B) {
+ for (unsigned I = 0; I != B.size(); ++I)
+ Bits[I] = B[I];
+ }
+
public:
- // Cannot inherit constructors because it's not supported by VC++..
FeatureBitset() = default;
-
- FeatureBitset(const bitset<MAX_SUBTARGET_FEATURES>& B) : bitset(B) {}
-
- FeatureBitset(std::initializer_list<unsigned> Init) {
+ constexpr FeatureBitset(std::initializer_list<unsigned> Init) {
for (auto I : Init)
set(I);
}
+ FeatureBitset &set() {
+ std::fill(std::begin(Bits), std::end(Bits), -1ULL);
+ return *this;
+ }
+
+ constexpr FeatureBitset &set(unsigned I) {
+ Bits[I / 64] |= uint64_t(1) << (I % 64);
+ return *this;
+ }
+
+ constexpr FeatureBitset &reset(unsigned I) {
+ Bits[I / 64] &= ~(uint64_t(1) << (I % 64));
+ return *this;
+ }
+
+ constexpr FeatureBitset &flip(unsigned I) {
+ Bits[I / 64] ^= uint64_t(1) << (I % 64);
+ return *this;
+ }
+
+ constexpr bool operator[](unsigned I) const {
+ uint64_t Mask = uint64_t(1) << (I % 64);
+ return (Bits[I / 64] & Mask) != 0;
+ }
+
+ constexpr bool test(unsigned I) const { return (*this)[I]; }
+
+ constexpr size_t size() const { return MAX_SUBTARGET_FEATURES; }
+
+ bool any() const {
+ return llvm::any_of(Bits, [](uint64_t I) { return I != 0; });
+ }
+ bool none() const { return !any(); }
+ size_t count() const {
+ size_t Count = 0;
+ for (auto B : Bits)
+ Count += countPopulation(B);
+ return Count;
+ }
+
+ constexpr FeatureBitset &operator^=(const FeatureBitset &RHS) {
+ for (unsigned I = 0, E = array_lengthof(Bits); I != E; ++I) {
+ Bits[I] ^= RHS.Bits[I];
+ }
+ return *this;
+ }
+ constexpr FeatureBitset operator^(const FeatureBitset &RHS) const {
+ FeatureBitset Result = *this;
+ Result ^= RHS;
+ return Result;
+ }
+
+ constexpr FeatureBitset &operator&=(const FeatureBitset &RHS) {
+ for (unsigned I = 0, E = array_lengthof(Bits); I != E; ++I) {
+ Bits[I] &= RHS.Bits[I];
+ }
+ return *this;
+ }
+ constexpr FeatureBitset operator&(const FeatureBitset &RHS) const {
+ FeatureBitset Result = *this;
+ Result &= RHS;
+ return Result;
+ }
+
+ constexpr FeatureBitset &operator|=(const FeatureBitset &RHS) {
+ for (unsigned I = 0, E = array_lengthof(Bits); I != E; ++I) {
+ Bits[I] |= RHS.Bits[I];
+ }
+ return *this;
+ }
+ constexpr FeatureBitset operator|(const FeatureBitset &RHS) const {
+ FeatureBitset Result = *this;
+ Result |= RHS;
+ return Result;
+ }
+
+ constexpr FeatureBitset operator~() const {
+ FeatureBitset Result = *this;
+ for (auto &B : Result.Bits)
+ B = ~B;
+ return Result;
+ }
+
+ bool operator==(const FeatureBitset &RHS) const {
+ return std::equal(std::begin(Bits), std::end(Bits), std::begin(RHS.Bits));
+ }
+
+ bool operator!=(const FeatureBitset &RHS) const { return !(*this == RHS); }
+
bool operator < (const FeatureBitset &Other) const {
for (unsigned I = 0, E = size(); I != E; ++I) {
bool LHS = test(I), RHS = Other.test(I);
@@ -58,23 +156,12 @@ public:
};
/// Class used to store the subtarget bits in the tables created by tablegen.
-/// The std::initializer_list constructor of FeatureBitset can't be done at
-/// compile time and requires a static constructor to run at startup.
-class FeatureBitArray {
- std::array<uint64_t, MAX_SUBTARGET_WORDS> Bits;
-
+class FeatureBitArray : public FeatureBitset {
public:
constexpr FeatureBitArray(const std::array<uint64_t, MAX_SUBTARGET_WORDS> &B)
- : Bits(B) {}
-
- FeatureBitset getAsBitset() const {
- FeatureBitset Result;
-
- for (unsigned i = 0, e = Bits.size(); i != e; ++i)
- Result |= FeatureBitset(Bits[i]) << (64 * i);
+ : FeatureBitset(B) {}
- return Result;
- }
+ const FeatureBitset &getAsBitset() const { return *this; }
};
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h?rev=369847&r1=369846&r2=369847&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h (original)
+++ llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h Sat Aug 24 08:02:44 2019
@@ -313,9 +313,9 @@ struct SysAlias {
uint16_t Encoding;
FeatureBitset FeaturesRequired;
- SysAlias (const char *N, uint16_t E) : Name(N), Encoding(E) {};
- SysAlias (const char *N, uint16_t E, FeatureBitset F) :
- Name(N), Encoding(E), FeaturesRequired(F) {};
+ constexpr SysAlias(const char *N, uint16_t E) : Name(N), Encoding(E) {}
+ constexpr SysAlias(const char *N, uint16_t E, FeatureBitset F)
+ : Name(N), Encoding(E), FeaturesRequired(F) {}
bool haveFeatures(FeatureBitset ActiveFeatures) const {
return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
@@ -326,9 +326,10 @@ struct SysAlias {
struct SysAliasReg : SysAlias {
bool NeedsReg;
- SysAliasReg(const char *N, uint16_t E, bool R) : SysAlias(N, E), NeedsReg(R) {};
- SysAliasReg(const char *N, uint16_t E, bool R, FeatureBitset F) : SysAlias(N, E, F),
- NeedsReg(R) {};
+ constexpr SysAliasReg(const char *N, uint16_t E, bool R)
+ : SysAlias(N, E), NeedsReg(R) {}
+ constexpr SysAliasReg(const char *N, uint16_t E, bool R, FeatureBitset F)
+ : SysAlias(N, E, F), NeedsReg(R) {}
};
namespace AArch64AT{
Modified: llvm/trunk/lib/Target/Hexagon/HexagonSubtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonSubtarget.cpp?rev=369847&r1=369846&r2=369847&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonSubtarget.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonSubtarget.cpp Sat Aug 24 08:02:44 2019
@@ -119,7 +119,7 @@ HexagonSubtarget::initializeSubtargetDep
FeatureBitset Features = getFeatureBits();
if (HexagonDisableDuplex)
- setFeatureBits(Features.set(Hexagon::FeatureDuplex, false));
+ setFeatureBits(Features.reset(Hexagon::FeatureDuplex));
setFeatureBits(Hexagon_MC::completeHVXFeatures(Features));
return *this;
Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp?rev=369847&r1=369846&r2=369847&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp Sat Aug 24 08:02:44 2019
@@ -264,14 +264,12 @@ createHexagonObjectTargetStreamer(MCStre
}
static void LLVM_ATTRIBUTE_UNUSED clearFeature(MCSubtargetInfo* STI, uint64_t F) {
- uint64_t FB = STI->getFeatureBits().to_ullong();
- if (FB & (1ULL << F))
+ if (STI->getFeatureBits()[F])
STI->ToggleFeature(F);
}
static bool LLVM_ATTRIBUTE_UNUSED checkFeature(MCSubtargetInfo* STI, uint64_t F) {
- uint64_t FB = STI->getFeatureBits().to_ullong();
- return (FB & (1ULL << F)) != 0;
+ return STI->getFeatureBits()[F];
}
namespace {
@@ -398,7 +396,7 @@ MCSubtargetInfo *Hexagon_MC::createHexag
MCSubtargetInfo *X = createHexagonMCSubtargetInfoImpl(TT, CPUName, ArchFS);
if (HexagonDisableDuplex) {
llvm::FeatureBitset Features = X->getFeatureBits();
- X->setFeatureBits(Features.set(Hexagon::FeatureDuplex, false));
+ X->setFeatureBits(Features.reset(Hexagon::FeatureDuplex));
}
X->setFeatureBits(completeHVXFeatures(X->getFeatureBits()));
Modified: llvm/trunk/test/TableGen/GlobalISelEmitter.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/GlobalISelEmitter.td?rev=369847&r1=369846&r2=369847&view=diff
==============================================================================
--- llvm/trunk/test/TableGen/GlobalISelEmitter.td (original)
+++ llvm/trunk/test/TableGen/GlobalISelEmitter.td Sat Aug 24 08:02:44 2019
@@ -96,9 +96,9 @@ def HasC : Predicate<"Subtarget->hasC()"
// CHECK-NEXT: computeAvailableModuleFeatures(const MyTargetSubtarget *Subtarget) const {
// CHECK-NEXT: PredicateBitset Features;
// CHECK-NEXT: if (Subtarget->hasA())
-// CHECK-NEXT: Features[Feature_HasABit] = 1;
+// CHECK-NEXT: Features.set(Feature_HasABit);
// CHECK-NEXT: if (Subtarget->hasB())
-// CHECK-NEXT: Features[Feature_HasBBit] = 1;
+// CHECK-NEXT: Features.set(Feature_HasBBit);
// CHECK-NEXT: return Features;
// CHECK-NEXT: }
@@ -106,7 +106,7 @@ def HasC : Predicate<"Subtarget->hasC()"
// CHECK-NEXT: computeAvailableFunctionFeatures(const MyTargetSubtarget *Subtarget, const MachineFunction *MF) const {
// CHECK-NEXT: PredicateBitset Features;
// CHECK-NEXT: if (Subtarget->hasC())
-// CHECK-NEXT: Features[Feature_HasCBit] = 1;
+// CHECK-NEXT: Features.set(Feature_HasCBit);
// CHECK-NEXT: return Features;
// CHECK-NEXT: }
Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=369847&r1=369846&r2=369847&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Sat Aug 24 08:02:44 2019
@@ -3366,7 +3366,7 @@ void AsmMatcherEmitter::run(raw_ostream
OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
}
OS << "};\n\n"
- << "const static FeatureBitset FeatureBitsets[] {\n"
+ << "static constexpr FeatureBitset FeatureBitsets[] = {\n"
<< " {}, // AMFBS_None\n";
for (const auto &FeatureBitset : FeatureBitsets) {
if (FeatureBitset.empty())
Modified: llvm/trunk/utils/TableGen/CodeEmitterGen.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeEmitterGen.cpp?rev=369847&r1=369846&r2=369847&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeEmitterGen.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeEmitterGen.cpp Sat Aug 24 08:02:44 2019
@@ -385,8 +385,8 @@ void CodeEmitterGen::run(raw_ostream &o)
o << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
}
o << "};\n\n"
- << "const static FeatureBitset FeatureBitsets[] {\n"
- << " {}, // CEFBS_None\n";
+ << "static constexpr FeatureBitset FeatureBitsets[] = {\n"
+ << " {}, // CEFBS_None\n";
for (const auto &FeatureBitset : FeatureBitsets) {
if (FeatureBitset.empty())
continue;
Modified: llvm/trunk/utils/TableGen/SearchableTableEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SearchableTableEmitter.cpp?rev=369847&r1=369846&r2=369847&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/SearchableTableEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/SearchableTableEmitter.cpp Sat Aug 24 08:02:44 2019
@@ -496,7 +496,7 @@ void SearchableTableEmitter::emitGeneric
emitIfdef((Twine("GET_") + Table.PreprocessorGuard + "_IMPL").str(), OS);
// The primary data table contains all the fields defined for this map.
- OS << "const " << Table.CppTypeName << " " << Table.Name << "[] = {\n";
+ OS << "constexpr " << Table.CppTypeName << " " << Table.Name << "[] = {\n";
for (unsigned i = 0; i < Table.Entries.size(); ++i) {
Record *Entry = Table.Entries[i];
OS << " { ";
Modified: llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp?rev=369847&r1=369846&r2=369847&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp (original)
+++ llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp Sat Aug 24 08:02:44 2019
@@ -103,7 +103,7 @@ void SubtargetFeatureInfo::emitComputeAv
assert(!CondStr.empty() && "true predicate should have been filtered");
OS << " if (" << CondStr << ")\n";
- OS << " Features[" << SFI.getEnumBitName() << "] = 1;\n";
+ OS << " Features.set(" << SFI.getEnumBitName() << ");\n";
}
OS << " return Features;\n";
OS << "}\n\n";
@@ -148,7 +148,7 @@ void SubtargetFeatureInfo::emitComputeAs
} while (true);
OS << ")\n";
- OS << " Features[" << SFI.getEnumBitName() << "] = 1;\n";
+ OS << " Features.set(" << SFI.getEnumBitName() << ");\n";
}
OS << " return Features;\n";
OS << "}\n\n";
More information about the llvm-commits
mailing list