123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- llvm/MC/SubtargetFeature.h - CPU characteristics ---------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- /// \file Defines and manages user or tool specified CPU characteristics.
- /// The intent is to be able to package specific features that should or should
- /// not be used on a specific target processor. A tool, such as llc, could, as
- /// as example, gather chip info from the command line, a long with features
- /// that should be used on that chip.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_MC_SUBTARGETFEATURE_H
- #define LLVM_MC_SUBTARGETFEATURE_H
- #include "llvm/ADT/ArrayRef.h"
- #include "llvm/ADT/STLExtras.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/Support/MathExtras.h"
- #include <array>
- #include <initializer_list>
- #include <string>
- #include <vector>
- namespace llvm {
- class raw_ostream;
- class Triple;
- const unsigned MAX_SUBTARGET_WORDS = 4;
- const unsigned MAX_SUBTARGET_FEATURES = MAX_SUBTARGET_WORDS * 64;
- /// Container class for subtarget features.
- /// This is a constexpr reimplementation of a subset of std::bitset. It would be
- /// nice to use std::bitset directly, but it doesn't support constant
- /// initialization.
- class FeatureBitset {
- static_assert((MAX_SUBTARGET_FEATURES % 64) == 0,
- "Should be a multiple of 64!");
- std::array<uint64_t, MAX_SUBTARGET_WORDS> Bits{};
- protected:
- constexpr FeatureBitset(const std::array<uint64_t, MAX_SUBTARGET_WORDS> &B)
- : Bits{B} {}
- public:
- constexpr FeatureBitset() = default;
- constexpr FeatureBitset(std::initializer_list<unsigned> Init) {
- for (auto I : Init)
- set(I);
- }
- FeatureBitset &set() {
- std::fill(std::begin(Bits), std::end(Bits), -1ULL);
- return *this;
- }
- constexpr FeatureBitset &set(unsigned I) {
- // GCC <6.2 crashes if this is written in a single statement.
- uint64_t NewBits = Bits[I / 64] | (uint64_t(1) << (I % 64));
- Bits[I / 64] = NewBits;
- return *this;
- }
- constexpr FeatureBitset &reset(unsigned I) {
- // GCC <6.2 crashes if this is written in a single statement.
- uint64_t NewBits = Bits[I / 64] & ~(uint64_t(1) << (I % 64));
- Bits[I / 64] = NewBits;
- return *this;
- }
- constexpr FeatureBitset &flip(unsigned I) {
- // GCC <6.2 crashes if this is written in a single statement.
- uint64_t NewBits = Bits[I / 64] ^ (uint64_t(1) << (I % 64));
- Bits[I / 64] = NewBits;
- return *this;
- }
- constexpr bool operator[](unsigned I) const {
- uint64_t Mask = uint64_t(1) << (I % 64);
- return (Bits[I / 64] & Mask) != 0;
- }
- constexpr bool test(unsigned I) const { return (*this)[I]; }
- constexpr size_t size() const { return MAX_SUBTARGET_FEATURES; }
- bool any() const {
- return llvm::any_of(Bits, [](uint64_t I) { return I != 0; });
- }
- bool none() const { return !any(); }
- size_t count() const {
- size_t Count = 0;
- for (auto B : Bits)
- Count += llvm::popcount(B);
- return Count;
- }
- constexpr FeatureBitset &operator^=(const FeatureBitset &RHS) {
- for (unsigned I = 0, E = Bits.size(); I != E; ++I) {
- Bits[I] ^= RHS.Bits[I];
- }
- return *this;
- }
- constexpr FeatureBitset operator^(const FeatureBitset &RHS) const {
- FeatureBitset Result = *this;
- Result ^= RHS;
- return Result;
- }
- constexpr FeatureBitset &operator&=(const FeatureBitset &RHS) {
- for (unsigned I = 0, E = Bits.size(); I != E; ++I) {
- Bits[I] &= RHS.Bits[I];
- }
- return *this;
- }
- constexpr FeatureBitset operator&(const FeatureBitset &RHS) const {
- FeatureBitset Result = *this;
- Result &= RHS;
- return Result;
- }
- constexpr FeatureBitset &operator|=(const FeatureBitset &RHS) {
- for (unsigned I = 0, E = Bits.size(); I != E; ++I) {
- Bits[I] |= RHS.Bits[I];
- }
- return *this;
- }
- constexpr FeatureBitset operator|(const FeatureBitset &RHS) const {
- FeatureBitset Result = *this;
- Result |= RHS;
- return Result;
- }
- constexpr FeatureBitset operator~() const {
- FeatureBitset Result = *this;
- for (auto &B : Result.Bits)
- B = ~B;
- return Result;
- }
- bool operator==(const FeatureBitset &RHS) const {
- return std::equal(std::begin(Bits), std::end(Bits), std::begin(RHS.Bits));
- }
- bool operator!=(const FeatureBitset &RHS) const { return !(*this == RHS); }
- bool operator < (const FeatureBitset &Other) const {
- for (unsigned I = 0, E = size(); I != E; ++I) {
- bool LHS = test(I), RHS = Other.test(I);
- if (LHS != RHS)
- return LHS < RHS;
- }
- return false;
- }
- };
- /// Class used to store the subtarget bits in the tables created by tablegen.
- class FeatureBitArray : public FeatureBitset {
- public:
- constexpr FeatureBitArray(const std::array<uint64_t, MAX_SUBTARGET_WORDS> &B)
- : FeatureBitset(B) {}
- const FeatureBitset &getAsBitset() const { return *this; }
- };
- //===----------------------------------------------------------------------===//
- /// Manages the enabling and disabling of subtarget specific features.
- ///
- /// Features are encoded as a string of the form
- /// "+attr1,+attr2,-attr3,...,+attrN"
- /// A comma separates each feature from the next (all lowercase.)
- /// Each of the remaining features is prefixed with + or - indicating whether
- /// that feature should be enabled or disabled contrary to the cpu
- /// specification.
- class SubtargetFeatures {
- std::vector<std::string> Features; ///< Subtarget features as a vector
- public:
- explicit SubtargetFeatures(StringRef Initial = "");
- /// Returns features as a string.
- std::string getString() const;
- /// Adds Features.
- void AddFeature(StringRef String, bool Enable = true);
- void addFeaturesVector(const ArrayRef<std::string> OtherFeatures);
- /// Returns the vector of individual subtarget features.
- const std::vector<std::string> &getFeatures() const { return Features; }
- /// Prints feature string.
- void print(raw_ostream &OS) const;
- // Dumps feature info.
- void dump() const;
- /// Adds the default features for the specified target triple.
- void getDefaultSubtargetFeatures(const Triple& Triple);
- /// Determine if a feature has a flag; '+' or '-'
- static bool hasFlag(StringRef Feature) {
- assert(!Feature.empty() && "Empty string");
- // Get first character
- char Ch = Feature[0];
- // Check if first character is '+' or '-' flag
- return Ch == '+' || Ch =='-';
- }
- /// Return string stripped of flag.
- static StringRef StripFlag(StringRef Feature) {
- return hasFlag(Feature) ? Feature.substr(1) : Feature;
- }
- /// Return true if enable flag; '+'.
- static inline bool isEnabled(StringRef Feature) {
- assert(!Feature.empty() && "Empty string");
- // Get first character
- char Ch = Feature[0];
- // Check if first character is '+' for enabled
- return Ch == '+';
- }
- /// Splits a string of comma separated items in to a vector of strings.
- static void Split(std::vector<std::string> &V, StringRef S);
- };
- } // end namespace llvm
- #endif // LLVM_MC_SUBTARGETFEATURE_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|