[llvm-commits] CVS: llvm/lib/Target/SubtargetFeature.cpp
Jim Laskey
jlaskey at apple.com
Thu Sep 1 14:36:30 PDT 2005
Changes in directory llvm/lib/Target:
SubtargetFeature.cpp added (r1.1)
---
Log message:
This new class provides support for platform specific "features". The intent
is to manage processor specific attributes from the command line. See examples
of use in llc/lli and PowerPCTargetSubtarget.
---
Diffs of the changes: (+173 -0)
SubtargetFeature.cpp | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 173 insertions(+)
Index: llvm/lib/Target/SubtargetFeature.cpp
diff -c /dev/null llvm/lib/Target/SubtargetFeature.cpp:1.1
*** /dev/null Thu Sep 1 16:36:28 2005
--- llvm/lib/Target/SubtargetFeature.cpp Thu Sep 1 16:36:18 2005
***************
*** 0 ****
--- 1,173 ----
+ //===- SubtargetFeature.cpp - CPU characteristics Implementation ----------===//
+ //
+ // The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Jim Laskey and is distributed under the
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file implements the SubtargetFeature interface.
+ //
+ //===----------------------------------------------------------------------===//
+
+ #include "llvm/Target/SubtargetFeature.h"
+
+ #include <string>
+ #include <algorithm>
+ #include <vector>
+ #include <cassert>
+
+
+ using namespace llvm;
+
+ /// Splits a string of comma separated items in to a vector of strings.
+ void SubtargetFeatures::Split(std::vector<std::string> &V,
+ const std::string &S) {
+ // Start at beginning of string.
+ size_t Pos = 0;
+ while (true) {
+ // Find the next comma
+ size_t Comma = S.find(',', Pos);
+ // If no comma found then the the rest of the string is used
+ if (Comma == std::string::npos) {
+ // Add string to vector
+ V.push_back(S.substr(Pos));
+ break;
+ }
+ // Otherwise add substring to vector
+ V.push_back(S.substr(Pos, Comma - Pos));
+ // Advance to next item
+ Pos = Comma + 1;
+ }
+ }
+
+ /// Join a vector of strings to a string with a comma separating each element.
+ std::string SubtargetFeatures::Join(const std::vector<std::string> &V) {
+ // Start with empty string.
+ std::string Result;
+ // If the vector is not empty
+ if (!V.empty()) {
+ // Start with the CPU feature
+ Result = V[0];
+ // For each successive feature
+ for (size_t i = 1; i < V.size(); i++) {
+ // Add a comma
+ Result += ",";
+ // Add the feature
+ Result += V[i];
+ }
+ }
+ // Return the features string
+ return Result;
+ }
+
+ /// Convert a string to lowercase.
+ std::string SubtargetFeatures::toLower(const std::string &S) {
+ // Copy the string
+ std::string Result = S;
+ // For each character in string
+ for (size_t i = 0; i < Result.size(); i++) {
+ // Convert character to lowercase
+ Result[i] = std::tolower(Result[i]);
+ }
+ // Return the lowercased string
+ return Result;
+ }
+
+ /// Adding features.
+ void SubtargetFeatures::AddFeature(const std::string &String,
+ bool IsEnabled) {
+ // Don't add empty features
+ if (!String.empty()) {
+ // Convert to lowercase, prepend flag and add to vector
+ Features.push_back(PrependFlag(toLower(String), IsEnabled));
+ }
+ }
+
+ /// Find item in array using binary search.
+ const SubtargetFeatureKV *
+ SubtargetFeatures::Find(const std::string &S,
+ const SubtargetFeatureKV *A, size_t L) {
+ // Determine the end of the array
+ const SubtargetFeatureKV *Hi = A + L;
+ // Binary search the array
+ const SubtargetFeatureKV *F = std::lower_bound(A, Hi, S);
+ // If not found then return NULL
+ if (F == Hi || std::string(F->Key) != S) return NULL;
+ // Return the found array item
+ return F;
+ }
+
+ /// Parse feature string for quick usage.
+ uint32_t SubtargetFeatures::Parse(const std::string &String,
+ const std::string &DefaultCPU,
+ const SubtargetFeatureKV *CPUTable,
+ size_t CPUTableSize,
+ const SubtargetFeatureKV *FeatureTable,
+ size_t FeatureTableSize) {
+ assert(CPUTable && "missing CPU table");
+ assert(FeatureTable && "missing features table");
+ #ifndef NDEBUG
+ for (size_t i = 1; i < CPUTableSize; i++) {
+ assert(strcmp(CPUTable[i - 1].Key, CPUTable[i].Key) < 0 &&
+ "CPU table is not sorted");
+ }
+ for (size_t i = 1; i < FeatureTableSize; i++) {
+ assert(strcmp(FeatureTable[i - 1].Key, FeatureTable[i].Key) < 0 &&
+ "CPU features table is not sorted");
+ }
+ #endif
+ std::vector<std::string> Features; // Subtarget features as a vector
+ uint32_t Bits = 0; // Resulting bits
+ // Split up features
+ Split(Features, String);
+ // Check if default is needed
+ if (Features[0].empty()) Features[0] = DefaultCPU;
+ // Find CPU entry
+ const SubtargetFeatureKV *CPUEntry =
+ Find(Features[0], CPUTable, CPUTableSize);
+ // If there is a match
+ if (CPUEntry) {
+ // Set base feature bits
+ Bits = CPUEntry->Value;
+ } else {
+ std::cerr << Features[0]
+ << " is not a recognized processor for this target"
+ << " (ignoring processor)"
+ << "\n";
+ }
+ // Iterate through each feature
+ for (size_t i = 1; i < Features.size(); i++) {
+ // Get next feature
+ const std::string &Feature = Features[i];
+ // Find feature in table.
+ const SubtargetFeatureKV *FeatureEntry =
+ Find(StripFlag(Feature), FeatureTable, FeatureTableSize);
+ // If there is a match
+ if (FeatureEntry) {
+ // Enable/disable feature in bits
+ if (isEnabled(Feature)) Bits |= FeatureEntry->Value;
+ else Bits &= ~FeatureEntry->Value;
+ } else {
+ std::cerr << Feature
+ << " is not a recognized feature for this target"
+ << " (ignoring feature)"
+ << "\n";
+ }
+ }
+ return Bits;
+ }
+
+ /// Print feature string.
+ void SubtargetFeatures::print(std::ostream &OS) const {
+ for (size_t i = 0; i < Features.size(); i++) {
+ OS << Features[i] << " ";
+ }
+ OS << "\n";
+ }
+
+ /// Dump feature info.
+ void SubtargetFeatures::dump() const {
+ print(std::cerr);
+ }
More information about the llvm-commits
mailing list