SubtargetFeature.h 7.1 KB

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