X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FSubtargetFeature.cpp;h=de48f4fbcb81ee33b1111d46c2c07497049ea350;hb=47622e37215429c20d8278ff57496d840811cc13;hp=54a89bdd0d52ad088f359d5b2e5250d94ec090d6;hpb=ba76c21858bac5fd953d4dbe2f0624d8e884c7b5;p=oota-llvm.git diff --git a/lib/Target/SubtargetFeature.cpp b/lib/Target/SubtargetFeature.cpp index 54a89bdd0d5..de48f4fbcb8 100644 --- a/lib/Target/SubtargetFeature.cpp +++ b/lib/Target/SubtargetFeature.cpp @@ -2,7 +2,7 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by Jim Laskey and is distributed under the +// This file was developed by James M. Laskey and is distributed under the // University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// @@ -110,44 +110,57 @@ void SubtargetFeatures::AddFeature(const std::string &String, } } -/// Find item in array using binary search. -static const SubtargetFeatureKV *Find(const std::string &S, - const SubtargetFeatureKV *A, size_t L) { +/// Find KV in array using binary search. +template const T *Find(const std::string &S, const T *A, size_t L) { + // Make the lower bound element we're looking for + T KV; + KV.Key = S.c_str(); // Determine the end of the array - const SubtargetFeatureKV *Hi = A + L; + const T *Hi = A + L; // Binary search the array - const SubtargetFeatureKV *F = std::lower_bound(A, Hi, S); + const T *F = std::lower_bound(A, Hi, KV); // If not found then return NULL if (F == Hi || std::string(F->Key) != S) return NULL; // Return the found array item return F; } -/// Display help for feature choices. +/// getLongestEntryLength - Return the length of the longest entry in the table. /// -static void Help(bool isFeature, const SubtargetFeatureKV *Table, - size_t TableSize) { - // Determine the length of the longest key. +static size_t getLongestEntryLength(const SubtargetFeatureKV *Table, + size_t Size) { size_t MaxLen = 0; - for (size_t i = 0; i < TableSize; i++) + for (size_t i = 0; i < Size; i++) MaxLen = std::max(MaxLen, std::strlen(Table[i].Key)); - - std::cerr << "Available " << (isFeature ? "features" : "CPUs") - << " for this target:\n\n"; + return MaxLen; +} - for (size_t i = 0; i < TableSize; i++) { - // Compute required padding - size_t Pad = MaxLen - std::strlen(Table[i].Key); - std::cerr << Table[i].Key << std::string(Pad, ' ') << " - " - << Table[i].Desc << ".\n"; - } +/// Display help for feature choices. +/// +static void Help(const SubtargetFeatureKV *CPUTable, size_t CPUTableSize, + const SubtargetFeatureKV *FeatTable, size_t FeatTableSize) { + // Determine the length of the longest CPU and Feature entries. + unsigned MaxCPULen = getLongestEntryLength(CPUTable, CPUTableSize); + unsigned MaxFeatLen = getLongestEntryLength(FeatTable, FeatTableSize); + // Print the CPU table. + std::cerr << "Available CPUs for this target:\n\n"; + for (size_t i = 0; i != CPUTableSize; i++) + std::cerr << " " << CPUTable[i].Key + << std::string(MaxCPULen - std::strlen(CPUTable[i].Key), ' ') + << " - " << CPUTable[i].Desc << ".\n"; std::cerr << "\n"; - if (isFeature) { - std::cerr - << "Use +feature to enable a feature, or -feature to disable it.\n" - << "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n"; - } + + // Print the Feature table. + std::cerr << "Available features for this target:\n\n"; + for (size_t i = 0; i != FeatTableSize; i++) + std::cerr << " " << FeatTable[i].Key + << std::string(MaxFeatLen - std::strlen(FeatTable[i].Key), ' ') + << " - " << FeatTable[i].Desc << ".\n"; + std::cerr << "\n"; + + std::cerr << "Use +feature to enable a feature, or -feature to disable it.\n" + << "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n"; exit(1); } @@ -171,6 +184,7 @@ void SubtargetFeatures::setString(const std::string &Initial) { Split(Features, LowercaseString(Initial)); } + /// setCPU - Set the CPU string. Replaces previous setting. Setting to "" /// clears CPU. void SubtargetFeatures::setCPU(const std::string &String) { @@ -178,15 +192,19 @@ void SubtargetFeatures::setCPU(const std::string &String) { } +/// setCPUIfNone - Setting CPU string only if no string is set. +/// +void SubtargetFeatures::setCPUIfNone(const std::string &String) { + if (Features[0].empty()) setCPU(String); +} + -/// Parse feature string for quick usage. +/// getBits - Get feature bits. /// -uint32_t SubtargetFeatures::Parse(const std::string &String, - const std::string &DefaultCPU, - const SubtargetFeatureKV *CPUTable, - size_t CPUTableSize, - const SubtargetFeatureKV *FeatureTable, - size_t FeatureTableSize) { +uint32_t SubtargetFeatures::getBits(const SubtargetFeatureKV *CPUTable, + size_t CPUTableSize, + const SubtargetFeatureKV *FeatureTable, + size_t FeatureTableSize) { assert(CPUTable && "missing CPU table"); assert(FeatureTable && "missing features table"); #ifndef NDEBUG @@ -199,14 +217,12 @@ uint32_t SubtargetFeatures::Parse(const std::string &String, "CPU features table is not sorted"); } #endif - std::vector 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; - // Check for help - if (Features[0] == "help") Help(false, CPUTable, CPUTableSize); + + // Check if help is needed + if (Features[0] == "help") + Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize); + // Find CPU entry const SubtargetFeatureKV *CPUEntry = Find(Features[0], CPUTable, CPUTableSize); @@ -222,10 +238,12 @@ uint32_t SubtargetFeatures::Parse(const std::string &String, } // Iterate through each feature for (size_t i = 1; i < Features.size(); i++) { - // Get next feature const std::string &Feature = Features[i]; + // Check for help - if (Feature == "+help") Help(true, FeatureTable, FeatureTableSize); + if (Feature == "+help") + Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize); + // Find feature in table. const SubtargetFeatureKV *FeatureEntry = Find(StripFlag(Feature), FeatureTable, FeatureTableSize); @@ -244,7 +262,32 @@ uint32_t SubtargetFeatures::Parse(const std::string &String, return Bits; } -/// Print feature string. +/// Get info pointer +void *SubtargetFeatures::getInfo(const SubtargetInfoKV *Table, + size_t TableSize) { + assert(Table && "missing table"); +#ifndef NDEBUG + for (size_t i = 1; i < TableSize; i++) { + assert(strcmp(Table[i - 1].Key, Table[i].Key) < 0 && "Table is not sorted"); + } +#endif + + // Find entry + const SubtargetInfoKV *Entry = Find(Features[0], Table, TableSize); + + if (Entry) { + return Entry->Value; + } else { + std::cerr << "'" << Features[0] + << "' is not a recognized processor for this target" + << " (ignoring processor)" + << "\n"; + return NULL; + } +} + +/// print - Print feature string. +/// void SubtargetFeatures::print(std::ostream &OS) const { for (size_t i = 0; i < Features.size(); i++) { OS << Features[i] << " "; @@ -252,7 +295,8 @@ void SubtargetFeatures::print(std::ostream &OS) const { OS << "\n"; } -/// Dump feature info. +/// dump - Dump feature info. +/// void SubtargetFeatures::dump() const { print(std::cerr); }