xref: /freebsd/contrib/llvm-project/llvm/include/llvm/TargetParser/SubtargetFeature.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //=== llvm/TargetParser/SubtargetFeature.h - CPU characteristics-*- 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 Defines and manages user or tool specified CPU characteristics.
10 /// The intent is to be able to package specific features that should or should
11 /// not be used on a specific target processor.  A tool, such as llc, could, as
12 /// as example, gather chip info from the command line, a long with features
13 /// that should be used on that chip.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #ifndef LLVM_TARGETPARSER_SUBTARGETFEATURE_H
18 #define LLVM_TARGETPARSER_SUBTARGETFEATURE_H
19 
20 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/Support/Compiler.h"
24 #include "llvm/Support/MathExtras.h"
25 #include <array>
26 #include <initializer_list>
27 #include <string>
28 #include <vector>
29 
30 namespace llvm {
31 
32 class raw_ostream;
33 class Triple;
34 
35 const unsigned MAX_SUBTARGET_WORDS = 6;
36 const unsigned MAX_SUBTARGET_FEATURES = MAX_SUBTARGET_WORDS * 64;
37 
38 /// Container class for subtarget features.
39 /// This is a constexpr reimplementation of a subset of std::bitset. It would be
40 /// nice to use std::bitset directly, but it doesn't support constant
41 /// initialization.
42 class FeatureBitset {
43   static_assert((MAX_SUBTARGET_FEATURES % 64) == 0,
44                 "Should be a multiple of 64!");
45   std::array<uint64_t, MAX_SUBTARGET_WORDS> Bits{};
46 
47 protected:
FeatureBitset(const std::array<uint64_t,MAX_SUBTARGET_WORDS> & B)48   constexpr FeatureBitset(const std::array<uint64_t, MAX_SUBTARGET_WORDS> &B)
49       : Bits{B} {}
50 
51 public:
52   constexpr FeatureBitset() = default;
FeatureBitset(std::initializer_list<unsigned> Init)53   constexpr FeatureBitset(std::initializer_list<unsigned> Init) {
54     for (auto I : Init)
55       set(I);
56   }
57 
set()58   FeatureBitset &set() {
59     llvm::fill(Bits, -1ULL);
60     return *this;
61   }
62 
set(unsigned I)63   constexpr FeatureBitset &set(unsigned I) {
64     Bits[I / 64] |= uint64_t(1) << (I % 64);
65     return *this;
66   }
67 
reset(unsigned I)68   constexpr FeatureBitset &reset(unsigned I) {
69     Bits[I / 64] &= ~(uint64_t(1) << (I % 64));
70     return *this;
71   }
72 
flip(unsigned I)73   constexpr FeatureBitset &flip(unsigned I) {
74     Bits[I / 64] ^= uint64_t(1) << (I % 64);
75     return *this;
76   }
77 
78   constexpr bool operator[](unsigned I) const {
79     uint64_t Mask = uint64_t(1) << (I % 64);
80     return (Bits[I / 64] & Mask) != 0;
81   }
82 
test(unsigned I)83   constexpr bool test(unsigned I) const { return (*this)[I]; }
84 
size()85   constexpr size_t size() const { return MAX_SUBTARGET_FEATURES; }
86 
any()87   bool any() const {
88     return llvm::any_of(Bits, [](uint64_t I) { return I != 0; });
89   }
none()90   bool none() const { return !any(); }
count()91   size_t count() const {
92     size_t Count = 0;
93     for (auto B : Bits)
94       Count += llvm::popcount(B);
95     return Count;
96   }
97 
98   constexpr FeatureBitset &operator^=(const FeatureBitset &RHS) {
99     for (unsigned I = 0, E = Bits.size(); I != E; ++I) {
100       Bits[I] ^= RHS.Bits[I];
101     }
102     return *this;
103   }
104   constexpr FeatureBitset operator^(const FeatureBitset &RHS) const {
105     FeatureBitset Result = *this;
106     Result ^= RHS;
107     return Result;
108   }
109 
110   constexpr FeatureBitset &operator&=(const FeatureBitset &RHS) {
111     for (unsigned I = 0, E = Bits.size(); I != E; ++I)
112       Bits[I] &= RHS.Bits[I];
113     return *this;
114   }
115   constexpr FeatureBitset operator&(const FeatureBitset &RHS) const {
116     FeatureBitset Result = *this;
117     Result &= RHS;
118     return Result;
119   }
120 
121   constexpr FeatureBitset &operator|=(const FeatureBitset &RHS) {
122     for (unsigned I = 0, E = Bits.size(); I != E; ++I) {
123       Bits[I] |= RHS.Bits[I];
124     }
125     return *this;
126   }
127   constexpr FeatureBitset operator|(const FeatureBitset &RHS) const {
128     FeatureBitset Result = *this;
129     Result |= RHS;
130     return Result;
131   }
132 
133   constexpr FeatureBitset operator~() const {
134     FeatureBitset Result = *this;
135     for (auto &B : Result.Bits)
136       B = ~B;
137     return Result;
138   }
139 
140   bool operator==(const FeatureBitset &RHS) const {
141     return std::equal(std::begin(Bits), std::end(Bits), std::begin(RHS.Bits));
142   }
143 
144   bool operator!=(const FeatureBitset &RHS) const { return !(*this == RHS); }
145 
146   bool operator < (const FeatureBitset &Other) const {
147     for (unsigned I = 0, E = size(); I != E; ++I) {
148       bool LHS = test(I), RHS = Other.test(I);
149       if (LHS != RHS)
150         return LHS < RHS;
151     }
152     return false;
153   }
154 };
155 
156 /// Class used to store the subtarget bits in the tables created by tablegen.
157 class FeatureBitArray : public FeatureBitset {
158 public:
FeatureBitArray(const std::array<uint64_t,MAX_SUBTARGET_WORDS> & B)159   constexpr FeatureBitArray(const std::array<uint64_t, MAX_SUBTARGET_WORDS> &B)
160       : FeatureBitset(B) {}
161 
getAsBitset()162   const FeatureBitset &getAsBitset() const { return *this; }
163 };
164 
165 //===----------------------------------------------------------------------===//
166 
167 /// Manages the enabling and disabling of subtarget specific features.
168 ///
169 /// Features are encoded as a string of the form
170 ///   "+attr1,+attr2,-attr3,...,+attrN"
171 /// A comma separates each feature from the next (all lowercase.)
172 /// Each of the remaining features is prefixed with + or - indicating whether
173 /// that feature should be enabled or disabled contrary to the cpu
174 /// specification.
175 class SubtargetFeatures {
176   std::vector<std::string> Features;    ///< Subtarget features as a vector
177 
178 public:
179   LLVM_ABI explicit SubtargetFeatures(StringRef Initial = "");
180 
181   /// Returns features as a string.
182   LLVM_ABI std::string getString() const;
183 
184   /// Adds Features.
185   LLVM_ABI void AddFeature(StringRef String, bool Enable = true);
186 
187   LLVM_ABI void addFeaturesVector(const ArrayRef<std::string> OtherFeatures);
188 
189   /// Returns the vector of individual subtarget features.
getFeatures()190   const std::vector<std::string> &getFeatures() const { return Features; }
191 
192   /// Prints feature string.
193   LLVM_ABI void print(raw_ostream &OS) const;
194 
195   // Dumps feature info.
196   LLVM_ABI void dump() const;
197 
198   /// Adds the default features for the specified target triple.
199   LLVM_ABI void getDefaultSubtargetFeatures(const Triple &Triple);
200 
201   /// Determine if a feature has a flag; '+' or '-'
hasFlag(StringRef Feature)202   static bool hasFlag(StringRef Feature) {
203     assert(!Feature.empty() && "Empty string");
204     // Get first character
205     char Ch = Feature[0];
206     // Check if first character is '+' or '-' flag
207     return Ch == '+' || Ch =='-';
208   }
209 
210   /// Return string stripped of flag.
StripFlag(StringRef Feature)211   static StringRef StripFlag(StringRef Feature) {
212     return hasFlag(Feature) ? Feature.substr(1) : Feature;
213   }
214 
215   /// Return true if enable flag; '+'.
isEnabled(StringRef Feature)216   static inline bool isEnabled(StringRef Feature) {
217     assert(!Feature.empty() && "Empty string");
218     // Get first character
219     char Ch = Feature[0];
220     // Check if first character is '+' for enabled
221     return Ch == '+';
222   }
223 
224   /// Splits a string of comma separated items in to a vector of strings.
225   LLVM_ABI static void Split(std::vector<std::string> &V, StringRef S);
226 };
227 
228 } // end namespace llvm
229 
230 #endif // LLVM_TARGETPARSER_SUBTARGETFEATURE_H
231