SubtargetFeature.h 7.3 KB

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