mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
Use std::bitset for SubtargetFeatures
Previously, subtarget features were a bitfield with the underlying type being uint64_t. Since several targets (X86 and ARM, in particular) have hit or were very close to hitting this bound, switching the features to use a bitset. No functional change. Differential Revision: http://reviews.llvm.org/D7065 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229831 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -2242,7 +2242,7 @@ static void emitComputeAvailableFeatures(AsmMatcherInfo &Info,
|
||||
Info.AsmParser->getValueAsString("AsmParserClassName");
|
||||
|
||||
OS << "uint64_t " << Info.Target.getName() << ClassName << "::\n"
|
||||
<< "ComputeAvailableFeatures(uint64_t FB) const {\n";
|
||||
<< "ComputeAvailableFeatures(const FeatureBitset& FB) const {\n";
|
||||
OS << " uint64_t Features = 0;\n";
|
||||
for (const auto &SF : Info.SubtargetFeatures) {
|
||||
const SubtargetFeatureInfo &SFI = SF.second;
|
||||
@@ -2264,12 +2264,10 @@ static void emitComputeAvailableFeatures(AsmMatcherInfo &Info,
|
||||
Cond = Cond.substr(1);
|
||||
}
|
||||
|
||||
OS << "((FB & " << Info.Target.getName() << "::" << Cond << ")";
|
||||
OS << "(";
|
||||
if (Neg)
|
||||
OS << " == 0";
|
||||
else
|
||||
OS << " != 0";
|
||||
OS << ")";
|
||||
OS << "!";
|
||||
OS << "FB[" << Info.Target.getName() << "::" << Cond << "])";
|
||||
|
||||
if (Comma.second.empty())
|
||||
break;
|
||||
@@ -2639,7 +2637,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
OS << "#undef GET_ASSEMBLER_HEADER\n";
|
||||
OS << " // This should be included into the middle of the declaration of\n";
|
||||
OS << " // your subclasses implementation of MCTargetAsmParser.\n";
|
||||
OS << " uint64_t ComputeAvailableFeatures(uint64_t FeatureBits) const;\n";
|
||||
OS << " uint64_t ComputeAvailableFeatures(const FeatureBitset& FB) const;\n";
|
||||
OS << " void convertToMCInst(unsigned Kind, MCInst &Inst, "
|
||||
<< "unsigned Opcode,\n"
|
||||
<< " const OperandVector "
|
||||
|
@@ -848,7 +848,7 @@ emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates,
|
||||
// The predicate function is just a big switch statement based on the
|
||||
// input predicate index.
|
||||
OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, "
|
||||
<< "uint64_t Bits) {\n";
|
||||
<< "const FeatureBitset& Bits) {\n";
|
||||
Indentation += 2;
|
||||
if (!Predicates.empty()) {
|
||||
OS.indent(Indentation) << "switch (Idx) {\n";
|
||||
@@ -1102,10 +1102,10 @@ unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders,
|
||||
static void emitSinglePredicateMatch(raw_ostream &o, StringRef str,
|
||||
const std::string &PredicateNamespace) {
|
||||
if (str[0] == '!')
|
||||
o << "!(Bits & " << PredicateNamespace << "::"
|
||||
<< str.slice(1,str.size()) << ")";
|
||||
o << "!Bits[" << PredicateNamespace << "::"
|
||||
<< str.slice(1,str.size()) << "]";
|
||||
else
|
||||
o << "(Bits & " << PredicateNamespace << "::" << str << ")";
|
||||
o << "Bits[" << PredicateNamespace << "::" << str << "]";
|
||||
}
|
||||
|
||||
bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
|
||||
@@ -2010,7 +2010,7 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
|
||||
<< " InsnType insn, uint64_t Address,\n"
|
||||
<< " const void *DisAsm,\n"
|
||||
<< " const MCSubtargetInfo &STI) {\n"
|
||||
<< " uint64_t Bits = STI.getFeatureBits();\n"
|
||||
<< " const FeatureBitset& Bits = STI.getFeatureBits();\n"
|
||||
<< "\n"
|
||||
<< " const uint8_t *Ptr = DecodeTable;\n"
|
||||
<< " uint32_t CurFieldValue = 0;\n"
|
||||
|
@@ -547,15 +547,15 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
|
||||
CodeGenTarget &Target = CDP.getTargetInfo();
|
||||
if (Inst.HasComplexDeprecationPredicate)
|
||||
// Emit a function pointer to the complex predicate method.
|
||||
OS << ",0"
|
||||
OS << ", { } "
|
||||
<< ",&get" << Inst.DeprecatedReason << "DeprecationInfo";
|
||||
else if (!Inst.DeprecatedReason.empty())
|
||||
// Emit the Subtarget feature.
|
||||
OS << "," << Target.getInstNamespace() << "::" << Inst.DeprecatedReason
|
||||
<< ",nullptr";
|
||||
OS << ", { " << Target.getInstNamespace() << "::" << Inst.DeprecatedReason
|
||||
<< "} ,nullptr";
|
||||
else
|
||||
// Instruction isn't deprecated.
|
||||
OS << ",0,nullptr";
|
||||
OS << ", { } ,nullptr";
|
||||
|
||||
OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/MC/MCInstrItineraries.h"
|
||||
#include "llvm/MC/SubtargetFeature.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/TableGen/Error.h"
|
||||
@@ -62,7 +63,7 @@ class SubtargetEmitter {
|
||||
CodeGenSchedModels &SchedModels;
|
||||
std::string Target;
|
||||
|
||||
void Enumeration(raw_ostream &OS, const char *ClassName, bool isBits);
|
||||
void Enumeration(raw_ostream &OS, const char *ClassName);
|
||||
unsigned FeatureKeyValues(raw_ostream &OS);
|
||||
unsigned CPUKeyValues(raw_ostream &OS);
|
||||
void FormItineraryStageString(const std::string &Names,
|
||||
@@ -112,8 +113,7 @@ public:
|
||||
// Enumeration - Emit the specified class as an enumeration.
|
||||
//
|
||||
void SubtargetEmitter::Enumeration(raw_ostream &OS,
|
||||
const char *ClassName,
|
||||
bool isBits) {
|
||||
const char *ClassName) {
|
||||
// Get all records of class and sort
|
||||
std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName);
|
||||
std::sort(DefList.begin(), DefList.end(), LessRecord());
|
||||
@@ -121,50 +121,30 @@ void SubtargetEmitter::Enumeration(raw_ostream &OS,
|
||||
unsigned N = DefList.size();
|
||||
if (N == 0)
|
||||
return;
|
||||
if (N > 64) {
|
||||
errs() << "Too many (> 64) subtarget features!\n";
|
||||
if (N > MAX_SUBTARGET_FEATURES) {
|
||||
errs() << "Too many subtarget features! Bump MAX_SUBTARGET_FEATURES.";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OS << "namespace " << Target << " {\n";
|
||||
|
||||
// For bit flag enumerations with more than 32 items, emit constants.
|
||||
// Emit an enum for everything else.
|
||||
if (isBits && N > 32) {
|
||||
// For each record
|
||||
for (unsigned i = 0; i < N; i++) {
|
||||
// Next record
|
||||
Record *Def = DefList[i];
|
||||
// Open enumeration
|
||||
OS << "enum {\n";
|
||||
|
||||
// Get and emit name and expression (1 << i)
|
||||
OS << " const uint64_t " << Def->getName() << " = 1ULL << " << i << ";\n";
|
||||
}
|
||||
} else {
|
||||
// Open enumeration
|
||||
OS << "enum {\n";
|
||||
// For each record
|
||||
for (unsigned i = 0; i < N;) {
|
||||
// Next record
|
||||
Record *Def = DefList[i];
|
||||
|
||||
// For each record
|
||||
for (unsigned i = 0; i < N;) {
|
||||
// Next record
|
||||
Record *Def = DefList[i];
|
||||
// Get and emit name
|
||||
OS << " " << Def->getName() << " = " << i;
|
||||
if (++i < N) OS << ",";
|
||||
|
||||
// Get and emit name
|
||||
OS << " " << Def->getName();
|
||||
|
||||
// If bit flags then emit expression (1 << i)
|
||||
if (isBits) OS << " = " << " 1ULL << " << i;
|
||||
|
||||
// Depending on 'if more in the list' emit comma
|
||||
if (++i < N) OS << ",";
|
||||
|
||||
OS << "\n";
|
||||
}
|
||||
|
||||
// Close enumeration
|
||||
OS << "};\n";
|
||||
OS << "\n";
|
||||
}
|
||||
|
||||
OS << "}\n";
|
||||
// Close enumeration and namespace
|
||||
OS << "};\n}\n";
|
||||
}
|
||||
|
||||
//
|
||||
@@ -198,22 +178,24 @@ unsigned SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {
|
||||
|
||||
if (CommandLineName.empty()) continue;
|
||||
|
||||
// Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in }
|
||||
// Emit as { "feature", "description", { featureEnum }, { i1 , i2 , ... , in } }
|
||||
OS << " { "
|
||||
<< "\"" << CommandLineName << "\", "
|
||||
<< "\"" << Desc << "\", "
|
||||
<< Target << "::" << Name << ", ";
|
||||
<< "{ " << Target << "::" << Name << " }, ";
|
||||
|
||||
const std::vector<Record*> &ImpliesList =
|
||||
Feature->getValueAsListOfDefs("Implies");
|
||||
|
||||
if (ImpliesList.empty()) {
|
||||
OS << "0ULL";
|
||||
OS << "{ }";
|
||||
} else {
|
||||
OS << "{ ";
|
||||
for (unsigned j = 0, M = ImpliesList.size(); j < M;) {
|
||||
OS << Target << "::" << ImpliesList[j]->getName();
|
||||
if (++j < M) OS << " | ";
|
||||
if (++j < M) OS << ", ";
|
||||
}
|
||||
OS << " }";
|
||||
}
|
||||
|
||||
OS << " }";
|
||||
@@ -255,22 +237,24 @@ unsigned SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {
|
||||
const std::vector<Record*> &FeatureList =
|
||||
Processor->getValueAsListOfDefs("Features");
|
||||
|
||||
// Emit as { "cpu", "description", f1 | f2 | ... fn },
|
||||
// Emit as { "cpu", "description", { f1 , f2 , ... fn } },
|
||||
OS << " { "
|
||||
<< "\"" << Name << "\", "
|
||||
<< "\"Select the " << Name << " processor\", ";
|
||||
|
||||
if (FeatureList.empty()) {
|
||||
OS << "0ULL";
|
||||
OS << "{ }";
|
||||
} else {
|
||||
OS << "{ ";
|
||||
for (unsigned j = 0, M = FeatureList.size(); j < M;) {
|
||||
OS << Target << "::" << FeatureList[j]->getName();
|
||||
if (++j < M) OS << " | ";
|
||||
if (++j < M) OS << ", ";
|
||||
}
|
||||
OS << " }";
|
||||
}
|
||||
|
||||
// The "0" is for the "implies" section of this data structure.
|
||||
OS << ", 0ULL }";
|
||||
// The { } is for the "implies" section of this data structure.
|
||||
OS << ", { } }";
|
||||
|
||||
// Depending on 'if more in the list' emit comma
|
||||
if (++i < N) OS << ",";
|
||||
@@ -1398,7 +1382,7 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS,
|
||||
}
|
||||
|
||||
OS << " InitMCProcessorInfo(CPU, FS);\n"
|
||||
<< " uint64_t Bits = getFeatureBits();\n";
|
||||
<< " const FeatureBitset& Bits = getFeatureBits();\n";
|
||||
|
||||
for (unsigned i = 0; i < Features.size(); i++) {
|
||||
// Next record
|
||||
@@ -1408,12 +1392,12 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS,
|
||||
const std::string &Attribute = R->getValueAsString("Attribute");
|
||||
|
||||
if (Value=="true" || Value=="false")
|
||||
OS << " if ((Bits & " << Target << "::"
|
||||
<< Instance << ") != 0) "
|
||||
OS << " if (Bits[" << Target << "::"
|
||||
<< Instance << "]) "
|
||||
<< Attribute << " = " << Value << ";\n";
|
||||
else
|
||||
OS << " if ((Bits & " << Target << "::"
|
||||
<< Instance << ") != 0 && "
|
||||
OS << " if (Bits[" << Target << "::"
|
||||
<< Instance << "] && "
|
||||
<< Attribute << " < " << Value << ") "
|
||||
<< Attribute << " = " << Value << ";\n";
|
||||
}
|
||||
@@ -1431,7 +1415,7 @@ void SubtargetEmitter::run(raw_ostream &OS) {
|
||||
OS << "#undef GET_SUBTARGETINFO_ENUM\n";
|
||||
|
||||
OS << "namespace llvm {\n";
|
||||
Enumeration(OS, "SubtargetFeature", true);
|
||||
Enumeration(OS, "SubtargetFeature");
|
||||
OS << "} // End llvm namespace \n";
|
||||
OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n";
|
||||
|
||||
|
Reference in New Issue
Block a user