SubtargetFeature.h 7.3 KB

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