Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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