class MCInst;
+//===----------------------------------------------------------------------===//
+
+/// Used to provide key value pairs for feature and CPU bit flags.
+struct SubtargetFeatureKV {
+ const char *Key; ///< K-V key string
+ const char *Desc; ///< Help descriptor
+ unsigned Value; ///< K-V integer value
+ FeatureBitArray Implies; ///< K-V bit mask
+
+ /// Compare routine for std::lower_bound
+ bool operator<(StringRef S) const {
+ return StringRef(Key) < S;
+ }
+
+ /// Compare routine for std::is_sorted.
+ bool operator<(const SubtargetFeatureKV &Other) const {
+ return StringRef(Key) < StringRef(Other.Key);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+
+/// Used to provide key value pairs for CPU and arbitrary pointers.
+struct SubtargetInfoKV {
+ const char *Key; ///< K-V key string
+ const void *Value; ///< K-V pointer value
+
+ /// Compare routine for std::lower_bound
+ bool operator<(StringRef S) const {
+ return StringRef(Key) < S;
+ }
+
+ /// Compare routine for std::is_sorted.
+ bool operator<(const SubtargetInfoKV &Other) const {
+ return StringRef(Key) < StringRef(Other.Key);
+ }
+};
+
//===----------------------------------------------------------------------===//
///
/// Generic base class for all target subtargets.
namespace llvm {
-template <typename T> class ArrayRef;
class raw_ostream;
class Triple;
//===----------------------------------------------------------------------===//
-/// Used to provide key value pairs for feature and CPU bit flags.
-struct SubtargetFeatureKV {
- const char *Key; ///< K-V key string
- const char *Desc; ///< Help descriptor
- unsigned Value; ///< K-V integer value
- FeatureBitArray Implies; ///< K-V bit mask
-
- /// Compare routine for std::lower_bound
- bool operator<(StringRef S) const {
- return StringRef(Key) < S;
- }
-
- /// Compare routine for std::is_sorted.
- bool operator<(const SubtargetFeatureKV &Other) const {
- return StringRef(Key) < StringRef(Other.Key);
- }
-};
-
-//===----------------------------------------------------------------------===//
-
-/// Used to provide key value pairs for CPU and arbitrary pointers.
-struct SubtargetInfoKV {
- const char *Key; ///< K-V key string
- const void *Value; ///< K-V pointer value
-
- /// Compare routine for std::lower_bound
- bool operator<(StringRef S) const {
- return StringRef(Key) < S;
- }
-
- /// Compare routine for std::is_sorted.
- bool operator<(const SubtargetInfoKV &Other) const {
- return StringRef(Key) < StringRef(Other.Key);
- }
-};
-
-//===----------------------------------------------------------------------===//
-
/// Manages the enabling and disabling of subtarget specific features.
///
/// Features are encoded as a string of the form
/// Adds Features.
void AddFeature(StringRef String, bool Enable = true);
- /// Toggles a feature and update the feature bits.
- static void ToggleFeature(FeatureBitset &Bits, StringRef String,
- ArrayRef<SubtargetFeatureKV> FeatureTable);
-
- /// Applies the feature flag and update the feature bits.
- static void ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature,
- ArrayRef<SubtargetFeatureKV> FeatureTable);
-
- /// Returns feature bits of a CPU.
- FeatureBitset getFeatureBits(StringRef CPU,
- ArrayRef<SubtargetFeatureKV> CPUTable,
- ArrayRef<SubtargetFeatureKV> FeatureTable);
-
/// Returns the vector of individual subtarget features.
const std::vector<std::string> &getFeatures() const { return Features; }
/// 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 std::string 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
#include "llvm/MC/MCInstrItineraries.h"
#include "llvm/MC/MCSchedule.h"
#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
using namespace llvm;
+/// Find KV in array using binary search.
+static const SubtargetFeatureKV *Find(StringRef S,
+ ArrayRef<SubtargetFeatureKV> A) {
+ // Binary search the array
+ auto F = std::lower_bound(A.begin(), A.end(), S);
+ // If not found then return NULL
+ if (F == A.end() || StringRef(F->Key) != S) return nullptr;
+ // Return the found array item
+ return F;
+}
+
+/// For each feature that is (transitively) implied by this feature, set it.
+static
+void SetImpliedBits(FeatureBitset &Bits, const FeatureBitset &Implies,
+ ArrayRef<SubtargetFeatureKV> FeatureTable) {
+ // OR the Implies bits in outside the loop. This allows the Implies for CPUs
+ // which might imply features not in FeatureTable to use this.
+ Bits |= Implies;
+ for (const SubtargetFeatureKV &FE : FeatureTable)
+ if (Implies.test(FE.Value))
+ SetImpliedBits(Bits, FE.Implies.getAsBitset(), FeatureTable);
+}
+
+/// For each feature that (transitively) implies this feature, clear it.
+static
+void ClearImpliedBits(FeatureBitset &Bits, unsigned Value,
+ ArrayRef<SubtargetFeatureKV> FeatureTable) {
+ for (const SubtargetFeatureKV &FE : FeatureTable) {
+ if (FE.Implies.getAsBitset().test(Value)) {
+ Bits.reset(FE.Value);
+ ClearImpliedBits(Bits, FE.Value, FeatureTable);
+ }
+ }
+}
+
+static void ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature,
+ ArrayRef<SubtargetFeatureKV> FeatureTable) {
+ assert(SubtargetFeatures::hasFlag(Feature) &&
+ "Feature flags should start with '+' or '-'");
+
+ // Find feature in table.
+ const SubtargetFeatureKV *FeatureEntry =
+ Find(SubtargetFeatures::StripFlag(Feature), FeatureTable);
+ // If there is a match
+ if (FeatureEntry) {
+ // Enable/disable feature in bits
+ if (SubtargetFeatures::isEnabled(Feature)) {
+ Bits.set(FeatureEntry->Value);
+
+ // For each feature that this implies, set it.
+ SetImpliedBits(Bits, FeatureEntry->Implies.getAsBitset(), FeatureTable);
+ } else {
+ Bits.reset(FeatureEntry->Value);
+
+ // For each feature that implies this, clear it.
+ ClearImpliedBits(Bits, FeatureEntry->Value, FeatureTable);
+ }
+ } else {
+ errs() << "'" << Feature << "' is not a recognized feature for this target"
+ << " (ignoring feature)\n";
+ }
+}
+
+/// Return the length of the longest entry in the table.
+static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) {
+ size_t MaxLen = 0;
+ for (auto &I : Table)
+ MaxLen = std::max(MaxLen, std::strlen(I.Key));
+ return MaxLen;
+}
+
+/// Display help for feature choices.
+static void Help(ArrayRef<SubtargetFeatureKV> CPUTable,
+ ArrayRef<SubtargetFeatureKV> FeatTable) {
+ // Determine the length of the longest CPU and Feature entries.
+ unsigned MaxCPULen = getLongestEntryLength(CPUTable);
+ unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
+
+ // Print the CPU table.
+ errs() << "Available CPUs for this target:\n\n";
+ for (auto &CPU : CPUTable)
+ errs() << format(" %-*s - %s.\n", MaxCPULen, CPU.Key, CPU.Desc);
+ errs() << '\n';
+
+ // Print the Feature table.
+ errs() << "Available features for this target:\n\n";
+ for (auto &Feature : FeatTable)
+ errs() << format(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
+ errs() << '\n';
+
+ errs() << "Use +feature to enable a feature, or -feature to disable it.\n"
+ "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n";
+}
+
static FeatureBitset getFeatures(StringRef CPU, StringRef FS,
ArrayRef<SubtargetFeatureKV> ProcDesc,
ArrayRef<SubtargetFeatureKV> ProcFeatures) {
SubtargetFeatures Features(FS);
- return Features.getFeatureBits(CPU, ProcDesc, ProcFeatures);
+
+ if (ProcDesc.empty() || ProcFeatures.empty())
+ return FeatureBitset();
+
+ assert(std::is_sorted(std::begin(ProcDesc), std::end(ProcDesc)) &&
+ "CPU table is not sorted");
+ assert(std::is_sorted(std::begin(ProcFeatures), std::end(ProcFeatures)) &&
+ "CPU features table is not sorted");
+ // Resulting bits
+ FeatureBitset Bits;
+
+ // Check if help is needed
+ if (CPU == "help")
+ Help(ProcDesc, ProcFeatures);
+
+ // Find CPU entry if CPU name is specified.
+ else if (!CPU.empty()) {
+ const SubtargetFeatureKV *CPUEntry = Find(CPU, ProcDesc);
+
+ // If there is a match
+ if (CPUEntry) {
+ // Set the features implied by this CPU feature, if any.
+ SetImpliedBits(Bits, CPUEntry->Implies.getAsBitset(), ProcFeatures);
+ } else {
+ errs() << "'" << CPU << "' is not a recognized processor for this target"
+ << " (ignoring processor)\n";
+ }
+ }
+
+ // Iterate through each feature
+ for (const std::string &Feature : Features.getFeatures()) {
+ // Check for help
+ if (Feature == "+help")
+ Help(ProcDesc, ProcFeatures);
+ else
+ ApplyFeatureFlag(Bits, Feature, ProcFeatures);
+ }
+
+ return Bits;
}
void MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef FS) {
return FeatureBits;
}
-FeatureBitset MCSubtargetInfo::ToggleFeature(StringRef FS) {
- SubtargetFeatures::ToggleFeature(FeatureBits, FS, ProcFeatures);
+FeatureBitset MCSubtargetInfo::ToggleFeature(StringRef Feature) {
+ // Find feature in table.
+ const SubtargetFeatureKV *FeatureEntry =
+ Find(SubtargetFeatures::StripFlag(Feature), ProcFeatures);
+ // If there is a match
+ if (FeatureEntry) {
+ if (FeatureBits.test(FeatureEntry->Value)) {
+ FeatureBits.reset(FeatureEntry->Value);
+ // For each feature that implies this, clear it.
+ ClearImpliedBits(FeatureBits, FeatureEntry->Value, ProcFeatures);
+ } else {
+ FeatureBits.set(FeatureEntry->Value);
+
+ // For each feature that this implies, set it.
+ SetImpliedBits(FeatureBits, FeatureEntry->Implies.getAsBitset(),
+ ProcFeatures);
+ }
+ } else {
+ errs() << "'" << Feature << "' is not a recognized feature for this target"
+ << " (ignoring feature)\n";
+ }
+
return FeatureBits;
}
FeatureBitset MCSubtargetInfo::ApplyFeatureFlag(StringRef FS) {
- SubtargetFeatures::ApplyFeatureFlag(FeatureBits, FS, ProcFeatures);
+ ::ApplyFeatureFlag(FeatureBits, FS, ProcFeatures);
return FeatureBits;
}
SubtargetFeatures T(FS);
FeatureBitset Set, All;
for (std::string F : T.getFeatures()) {
- SubtargetFeatures::ApplyFeatureFlag(Set, F, ProcFeatures);
+ ::ApplyFeatureFlag(Set, F, ProcFeatures);
if (F[0] == '-')
F[0] = '+';
- SubtargetFeatures::ApplyFeatureFlag(All, F, ProcFeatures);
+ ::ApplyFeatureFlag(All, F, ProcFeatures);
}
return (FeatureBits & All) == Set;
}
//===----------------------------------------------------------------------===//
#include "llvm/MC/SubtargetFeature.h"
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
using namespace llvm;
-/// Determine if a feature has a flag; '+' or '-'
-static inline 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 inline std::string 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) {
+void SubtargetFeatures::Split(std::vector<std::string> &V, StringRef S) {
SmallVector<StringRef, 3> Tmp;
S.split(Tmp, ',', -1, false /* KeepEmpty */);
V.assign(Tmp.begin(), Tmp.end());
: (Enable ? "+" : "-") + String.lower());
}
-/// Find KV in array using binary search.
-static const SubtargetFeatureKV *Find(StringRef S,
- ArrayRef<SubtargetFeatureKV> A) {
- // Binary search the array
- auto F = std::lower_bound(A.begin(), A.end(), S);
- // If not found then return NULL
- if (F == A.end() || StringRef(F->Key) != S) return nullptr;
- // Return the found array item
- return F;
-}
-
-/// Return the length of the longest entry in the table.
-static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) {
- size_t MaxLen = 0;
- for (auto &I : Table)
- MaxLen = std::max(MaxLen, std::strlen(I.Key));
- return MaxLen;
-}
-
-/// Display help for feature choices.
-static void Help(ArrayRef<SubtargetFeatureKV> CPUTable,
- ArrayRef<SubtargetFeatureKV> FeatTable) {
- // Determine the length of the longest CPU and Feature entries.
- unsigned MaxCPULen = getLongestEntryLength(CPUTable);
- unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
-
- // Print the CPU table.
- errs() << "Available CPUs for this target:\n\n";
- for (auto &CPU : CPUTable)
- errs() << format(" %-*s - %s.\n", MaxCPULen, CPU.Key, CPU.Desc);
- errs() << '\n';
-
- // Print the Feature table.
- errs() << "Available features for this target:\n\n";
- for (auto &Feature : FeatTable)
- errs() << format(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
- errs() << '\n';
-
- errs() << "Use +feature to enable a feature, or -feature to disable it.\n"
- "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n";
-}
-
SubtargetFeatures::SubtargetFeatures(StringRef Initial) {
// Break up string into separate features
Split(Features, Initial);
return join(Features.begin(), Features.end(), ",");
}
-/// For each feature that is (transitively) implied by this feature, set it.
-static
-void SetImpliedBits(FeatureBitset &Bits, const FeatureBitset &Implies,
- ArrayRef<SubtargetFeatureKV> FeatureTable) {
- // OR the Implies bits in outside the loop. This allows the Implies for CPUs
- // which might imply features not in FeatureTable to use this.
- Bits |= Implies;
- for (const SubtargetFeatureKV &FE : FeatureTable)
- if (Implies.test(FE.Value))
- SetImpliedBits(Bits, FE.Implies.getAsBitset(), FeatureTable);
-}
-
-/// For each feature that (transitively) implies this feature, clear it.
-static
-void ClearImpliedBits(FeatureBitset &Bits, unsigned Value,
- ArrayRef<SubtargetFeatureKV> FeatureTable) {
- for (const SubtargetFeatureKV &FE : FeatureTable) {
- if (FE.Implies.getAsBitset().test(Value)) {
- Bits.reset(FE.Value);
- ClearImpliedBits(Bits, FE.Value, FeatureTable);
- }
- }
-}
-
-void
-SubtargetFeatures::ToggleFeature(FeatureBitset &Bits, StringRef Feature,
- ArrayRef<SubtargetFeatureKV> FeatureTable) {
- // Find feature in table.
- const SubtargetFeatureKV *FeatureEntry =
- Find(StripFlag(Feature), FeatureTable);
- // If there is a match
- if (FeatureEntry) {
- if (Bits.test(FeatureEntry->Value)) {
- Bits.reset(FeatureEntry->Value);
- // For each feature that implies this, clear it.
- ClearImpliedBits(Bits, FeatureEntry->Value, FeatureTable);
- } else {
- Bits.set(FeatureEntry->Value);
-
- // For each feature that this implies, set it.
- SetImpliedBits(Bits, FeatureEntry->Implies.getAsBitset(), FeatureTable);
- }
- } else {
- errs() << "'" << Feature << "' is not a recognized feature for this target"
- << " (ignoring feature)\n";
- }
-}
-
-void SubtargetFeatures::ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature,
- ArrayRef<SubtargetFeatureKV> FeatureTable) {
- assert(hasFlag(Feature));
-
- // Find feature in table.
- const SubtargetFeatureKV *FeatureEntry =
- Find(StripFlag(Feature), FeatureTable);
- // If there is a match
- if (FeatureEntry) {
- // Enable/disable feature in bits
- if (isEnabled(Feature)) {
- Bits.set(FeatureEntry->Value);
-
- // For each feature that this implies, set it.
- SetImpliedBits(Bits, FeatureEntry->Implies.getAsBitset(), FeatureTable);
- } else {
- Bits.reset(FeatureEntry->Value);
-
- // For each feature that implies this, clear it.
- ClearImpliedBits(Bits, FeatureEntry->Value, FeatureTable);
- }
- } else {
- errs() << "'" << Feature << "' is not a recognized feature for this target"
- << " (ignoring feature)\n";
- }
-}
-
-FeatureBitset
-SubtargetFeatures::getFeatureBits(StringRef CPU,
- ArrayRef<SubtargetFeatureKV> CPUTable,
- ArrayRef<SubtargetFeatureKV> FeatureTable) {
- if (CPUTable.empty() || FeatureTable.empty())
- return FeatureBitset();
-
- assert(std::is_sorted(std::begin(CPUTable), std::end(CPUTable)) &&
- "CPU table is not sorted");
- assert(std::is_sorted(std::begin(FeatureTable), std::end(FeatureTable)) &&
- "CPU features table is not sorted");
- // Resulting bits
- FeatureBitset Bits;
-
- // Check if help is needed
- if (CPU == "help")
- Help(CPUTable, FeatureTable);
-
- // Find CPU entry if CPU name is specified.
- else if (!CPU.empty()) {
- const SubtargetFeatureKV *CPUEntry = Find(CPU, CPUTable);
-
- // If there is a match
- if (CPUEntry) {
- // Set the features implied by this CPU feature, if any.
- SetImpliedBits(Bits, CPUEntry->Implies.getAsBitset(), FeatureTable);
- } else {
- errs() << "'" << CPU << "' is not a recognized processor for this target"
- << " (ignoring processor)\n";
- }
- }
-
- // Iterate through each feature
- for (const std::string &Feature : Features) {
- // Check for help
- if (Feature == "+help")
- Help(CPUTable, FeatureTable);
- else
- ApplyFeatureFlag(Bits, Feature, FeatureTable);
- }
-
- return Bits;
-}
-
void SubtargetFeatures::print(raw_ostream &OS) const {
for (auto &F : Features)
OS << F << " ";