X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FSubtargetFeature.cpp;h=66ffb57e785dcda414f04828e7c2434bf63a2619;hb=bd9ef18f74a361e0ed630d373677c6fc0ce3cad9;hp=7856ddb66a48f2cc309f53ac1f5b666f476e98b6;hpb=9471c8a93b117d8ac01c4ef1cb9faa583e03dec0;p=oota-llvm.git diff --git a/lib/Target/SubtargetFeature.cpp b/lib/Target/SubtargetFeature.cpp index 7856ddb66a4..66ffb57e785 100644 --- a/lib/Target/SubtargetFeature.cpp +++ b/lib/Target/SubtargetFeature.cpp @@ -2,8 +2,8 @@ // // 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 is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -13,10 +13,11 @@ #include "llvm/Target/SubtargetFeature.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Support/Streams.h" #include +#include #include #include -#include using namespace llvm; //===----------------------------------------------------------------------===// @@ -144,23 +145,23 @@ static void Help(const SubtargetFeatureKV *CPUTable, size_t CPUTableSize, unsigned MaxFeatLen = getLongestEntryLength(FeatTable, FeatTableSize); // Print the CPU table. - std::cerr << "Available CPUs for this target:\n\n"; + 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"; + cerr << " " << CPUTable[i].Key + << std::string(MaxCPULen - std::strlen(CPUTable[i].Key), ' ') + << " - " << CPUTable[i].Desc << ".\n"; + cerr << "\n"; // Print the Feature table. - std::cerr << "Available features for this target:\n\n"; + 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"; + cerr << " " << FeatTable[i].Key + << std::string(MaxFeatLen - std::strlen(FeatTable[i].Key), ' ') + << " - " << FeatTable[i].Desc << ".\n"; + 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"; + cerr << "Use +feature to enable a feature, or -feature to disable it.\n" + << "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n"; exit(1); } @@ -198,6 +199,43 @@ void SubtargetFeatures::setCPUIfNone(const std::string &String) { if (Features[0].empty()) setCPU(String); } +/// SetImpliedBits - For each feature that is (transitively) implied by this +/// feature, set it. +/// +static +void SetImpliedBits(uint32_t &Bits, const SubtargetFeatureKV *FeatureEntry, + const SubtargetFeatureKV *FeatureTable, + size_t FeatureTableSize) { + for (size_t i = 0; i < FeatureTableSize; ++i) { + const SubtargetFeatureKV &FE = FeatureTable[i]; + + if (FeatureEntry->Value == FE.Value) continue; + + if (FeatureEntry->Implies & FE.Value) { + Bits |= FE.Value; + SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize); + } + } +} + +/// ClearImpliedBits - For each feature that (transitively) implies this +/// feature, clear it. +/// +static +void ClearImpliedBits(uint32_t &Bits, const SubtargetFeatureKV *FeatureEntry, + const SubtargetFeatureKV *FeatureTable, + size_t FeatureTableSize) { + for (size_t i = 0; i < FeatureTableSize; ++i) { + const SubtargetFeatureKV &FE = FeatureTable[i]; + + if (FeatureEntry->Value == FE.Value) continue; + + if (FE.Implies & FeatureEntry->Value) { + Bits &= ~FE.Value; + ClearImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize); + } + } +} /// getBits - Get feature bits. /// @@ -230,11 +268,18 @@ uint32_t SubtargetFeatures::getBits(const SubtargetFeatureKV *CPUTable, if (CPUEntry) { // Set base feature bits Bits = CPUEntry->Value; + + // Set the feature implied by this CPU feature, if any. + for (size_t i = 0; i < FeatureTableSize; ++i) { + const SubtargetFeatureKV &FE = FeatureTable[i]; + if (CPUEntry->Value & FE.Value) + SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize); + } } else { - std::cerr << "'" << Features[0] - << "' is not a recognized processor for this target" - << " (ignoring processor)" - << "\n"; + 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++) { @@ -250,15 +295,25 @@ uint32_t SubtargetFeatures::getBits(const SubtargetFeatureKV *CPUTable, // If there is a match if (FeatureEntry) { // Enable/disable feature in bits - if (isEnabled(Feature)) Bits |= FeatureEntry->Value; - else Bits &= ~FeatureEntry->Value; + if (isEnabled(Feature)) { + Bits |= FeatureEntry->Value; + + // For each feature that this implies, set it. + SetImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize); + } else { + Bits &= ~FeatureEntry->Value; + + // For each feature that implies this, clear it. + ClearImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize); + } } else { - std::cerr << "'" << Feature - << "' is not a recognized feature for this target" - << " (ignoring feature)" - << "\n"; + cerr << "'" << Feature + << "' is not a recognized feature for this target" + << " (ignoring feature)" + << "\n"; } } + return Bits; } @@ -278,10 +333,10 @@ void *SubtargetFeatures::getInfo(const SubtargetInfoKV *Table, if (Entry) { return Entry->Value; } else { - std::cerr << "'" << Features[0] - << "' is not a recognized processor for this target" - << " (ignoring processor)" - << "\n"; + cerr << "'" << Features[0] + << "' is not a recognized processor for this target" + << " (ignoring processor)" + << "\n"; return NULL; } } @@ -298,5 +353,5 @@ void SubtargetFeatures::print(std::ostream &OS) const { /// dump - Dump feature info. /// void SubtargetFeatures::dump() const { - print(std::cerr); + print(*cerr.stream()); }