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

source code of llvm/include/llvm/TargetParser/SubtargetFeature.h