File indexing completed on 2026-05-10 08:44:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef LLVM_TARGETPARSER_SUBTARGETFEATURE_H
0018 #define LLVM_TARGETPARSER_SUBTARGETFEATURE_H
0019
0020 #include "llvm/ADT/ArrayRef.h"
0021 #include "llvm/ADT/STLExtras.h"
0022 #include "llvm/ADT/StringRef.h"
0023 #include "llvm/Support/MathExtras.h"
0024 #include <array>
0025 #include <initializer_list>
0026 #include <string>
0027 #include <vector>
0028
0029 namespace llvm {
0030
0031 class raw_ostream;
0032 class Triple;
0033
0034 const unsigned MAX_SUBTARGET_WORDS = 5;
0035 const unsigned MAX_SUBTARGET_FEATURES = MAX_SUBTARGET_WORDS * 64;
0036
0037
0038
0039
0040
0041 class FeatureBitset {
0042 static_assert((MAX_SUBTARGET_FEATURES % 64) == 0,
0043 "Should be a multiple of 64!");
0044 std::array<uint64_t, MAX_SUBTARGET_WORDS> Bits{};
0045
0046 protected:
0047 constexpr FeatureBitset(const std::array<uint64_t, MAX_SUBTARGET_WORDS> &B)
0048 : Bits{B} {}
0049
0050 public:
0051 constexpr FeatureBitset() = default;
0052 constexpr FeatureBitset(std::initializer_list<unsigned> Init) {
0053 for (auto I : Init)
0054 set(I);
0055 }
0056
0057 FeatureBitset &set() {
0058 std::fill(std::begin(Bits), std::end(Bits), -1ULL);
0059 return *this;
0060 }
0061
0062 constexpr FeatureBitset &set(unsigned I) {
0063 Bits[I / 64] |= uint64_t(1) << (I % 64);
0064 return *this;
0065 }
0066
0067 constexpr FeatureBitset &reset(unsigned I) {
0068 Bits[I / 64] &= ~(uint64_t(1) << (I % 64));
0069 return *this;
0070 }
0071
0072 constexpr FeatureBitset &flip(unsigned I) {
0073 Bits[I / 64] ^= uint64_t(1) << (I % 64);
0074 return *this;
0075 }
0076
0077 constexpr bool operator[](unsigned I) const {
0078 uint64_t Mask = uint64_t(1) << (I % 64);
0079 return (Bits[I / 64] & Mask) != 0;
0080 }
0081
0082 constexpr bool test(unsigned I) const { return (*this)[I]; }
0083
0084 constexpr size_t size() const { return MAX_SUBTARGET_FEATURES; }
0085
0086 bool any() const {
0087 return llvm::any_of(Bits, [](uint64_t I) { return I != 0; });
0088 }
0089 bool none() const { return !any(); }
0090 size_t count() const {
0091 size_t Count = 0;
0092 for (auto B : Bits)
0093 Count += llvm::popcount(B);
0094 return Count;
0095 }
0096
0097 constexpr FeatureBitset &operator^=(const FeatureBitset &RHS) {
0098 for (unsigned I = 0, E = Bits.size(); I != E; ++I) {
0099 Bits[I] ^= RHS.Bits[I];
0100 }
0101 return *this;
0102 }
0103 constexpr FeatureBitset operator^(const FeatureBitset &RHS) const {
0104 FeatureBitset Result = *this;
0105 Result ^= RHS;
0106 return Result;
0107 }
0108
0109 constexpr FeatureBitset &operator&=(const FeatureBitset &RHS) {
0110 for (unsigned I = 0, E = Bits.size(); I != E; ++I)
0111 Bits[I] &= RHS.Bits[I];
0112 return *this;
0113 }
0114 constexpr FeatureBitset operator&(const FeatureBitset &RHS) const {
0115 FeatureBitset Result = *this;
0116 Result &= RHS;
0117 return Result;
0118 }
0119
0120 constexpr FeatureBitset &operator|=(const FeatureBitset &RHS) {
0121 for (unsigned I = 0, E = Bits.size(); I != E; ++I) {
0122 Bits[I] |= RHS.Bits[I];
0123 }
0124 return *this;
0125 }
0126 constexpr FeatureBitset operator|(const FeatureBitset &RHS) const {
0127 FeatureBitset Result = *this;
0128 Result |= RHS;
0129 return Result;
0130 }
0131
0132 constexpr FeatureBitset operator~() const {
0133 FeatureBitset Result = *this;
0134 for (auto &B : Result.Bits)
0135 B = ~B;
0136 return Result;
0137 }
0138
0139 bool operator==(const FeatureBitset &RHS) const {
0140 return std::equal(std::begin(Bits), std::end(Bits), std::begin(RHS.Bits));
0141 }
0142
0143 bool operator!=(const FeatureBitset &RHS) const { return !(*this == RHS); }
0144
0145 bool operator < (const FeatureBitset &Other) const {
0146 for (unsigned I = 0, E = size(); I != E; ++I) {
0147 bool LHS = test(I), RHS = Other.test(I);
0148 if (LHS != RHS)
0149 return LHS < RHS;
0150 }
0151 return false;
0152 }
0153 };
0154
0155
0156 class FeatureBitArray : public FeatureBitset {
0157 public:
0158 constexpr FeatureBitArray(const std::array<uint64_t, MAX_SUBTARGET_WORDS> &B)
0159 : FeatureBitset(B) {}
0160
0161 const FeatureBitset &getAsBitset() const { return *this; }
0162 };
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174 class SubtargetFeatures {
0175 std::vector<std::string> Features;
0176
0177 public:
0178 explicit SubtargetFeatures(StringRef Initial = "");
0179
0180
0181 std::string getString() const;
0182
0183
0184 void AddFeature(StringRef String, bool Enable = true);
0185
0186 void addFeaturesVector(const ArrayRef<std::string> OtherFeatures);
0187
0188
0189 const std::vector<std::string> &getFeatures() const { return Features; }
0190
0191
0192 void print(raw_ostream &OS) const;
0193
0194
0195 void dump() const;
0196
0197
0198 void getDefaultSubtargetFeatures(const Triple& Triple);
0199
0200
0201 static bool hasFlag(StringRef Feature) {
0202 assert(!Feature.empty() && "Empty string");
0203
0204 char Ch = Feature[0];
0205
0206 return Ch == '+' || Ch =='-';
0207 }
0208
0209
0210 static StringRef StripFlag(StringRef Feature) {
0211 return hasFlag(Feature) ? Feature.substr(1) : Feature;
0212 }
0213
0214
0215 static inline bool isEnabled(StringRef Feature) {
0216 assert(!Feature.empty() && "Empty string");
0217
0218 char Ch = Feature[0];
0219
0220 return Ch == '+';
0221 }
0222
0223
0224 static void Split(std::vector<std::string> &V, StringRef S);
0225 };
0226
0227 }
0228
0229 #endif