- Added MCSubtargetInfo to capture subtarget features and scheduling

itineraries.
- Refactor TargetSubtarget to be based on MCSubtargetInfo.
- Change tablegen generated subtarget info to initialize MCSubtargetInfo
  and hide more details from targets.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134257 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng
2011-07-01 20:45:01 +00:00
parent eb03c3b228
commit 94214703d9
33 changed files with 402 additions and 102 deletions

View File

@@ -223,7 +223,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
OS << "#undef GET_INSTRINFO_HEADER\n";
std::string ClassName = TargetName + "GenInstrInfo";
OS << "namespace llvm {\n\n";
OS << "namespace llvm {\n";
OS << "struct " << ClassName << " : public TargetInstrInfoImpl {\n"
<< " explicit " << ClassName << "(int SO = -1, int DO = -1);\n"
<< "};\n";
@@ -234,7 +234,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
OS << "\n#ifdef GET_INSTRINFO_CTOR\n";
OS << "#undef GET_INSTRINFO_CTOR\n";
OS << "namespace llvm {\n\n";
OS << "namespace llvm {\n";
OS << ClassName << "::" << ClassName << "(int SO, int DO)\n"
<< " : TargetInstrInfoImpl(SO, DO) {\n"
<< " InitMCInstrInfo(" << TargetName << "Insts, "

View File

@@ -29,16 +29,20 @@ void SubtargetEmitter::Enumeration(raw_ostream &OS,
std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName);
std::sort(DefList.begin(), DefList.end(), LessRecord());
// Open enumeration
OS << "enum {\n";
// For each record
unsigned N = DefList.size();
if (N == 0)
return;
if (N > 64) {
errs() << "Too many (> 64) subtarget features!\n";
exit(1);
}
OS << "namespace " << Target << " {\n";
// Open enumeration
OS << "enum {\n";
// For each record
for (unsigned i = 0; i < N;) {
// Next record
Record *Def = DefList[i];
@@ -57,23 +61,31 @@ void SubtargetEmitter::Enumeration(raw_ostream &OS,
// Close enumeration
OS << "};\n";
OS << "}\n";
}
//
// FeatureKeyValues - Emit data of all the subtarget features. Used by the
// command line.
//
void SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {
unsigned SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {
// Gather and sort all the features
std::vector<Record*> FeatureList =
Records.getAllDerivedDefinitions("SubtargetFeature");
if (FeatureList.empty())
return 0;
std::sort(FeatureList.begin(), FeatureList.end(), LessRecordFieldName());
// Begin feature table
OS << "// Sorted (by key) array of values for CPU features.\n"
<< "static const llvm::SubtargetFeatureKV FeatureKV[] = {\n";
<< "static const llvm::SubtargetFeatureKV "
<< Target << "FeatureKV[] = {\n";
// For each feature
unsigned NumFeatures = 0;
for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) {
// Next feature
Record *Feature = FeatureList[i];
@@ -88,7 +100,7 @@ void SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {
OS << " { "
<< "\"" << CommandLineName << "\", "
<< "\"" << Desc << "\", "
<< Name << ", ";
<< Target << "::" << Name << ", ";
const std::vector<Record*> &ImpliesList =
Feature->getValueAsListOfDefs("Implies");
@@ -97,12 +109,13 @@ void SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {
OS << "0ULL";
} else {
for (unsigned j = 0, M = ImpliesList.size(); j < M;) {
OS << ImpliesList[j]->getName();
OS << Target << "::" << ImpliesList[j]->getName();
if (++j < M) OS << " | ";
}
}
OS << " }";
++NumFeatures;
// Depending on 'if more in the list' emit comma
if ((i + 1) < N) OS << ",";
@@ -113,17 +126,14 @@ void SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {
// End feature table
OS << "};\n";
// Emit size of table
OS<<"\nenum {\n";
OS<<" FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV)\n";
OS<<"};\n";
return NumFeatures;
}
//
// CPUKeyValues - Emit data of all the subtarget processors. Used by command
// line.
//
void SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {
unsigned SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {
// Gather and sort processor information
std::vector<Record*> ProcessorList =
Records.getAllDerivedDefinitions("Processor");
@@ -131,7 +141,8 @@ void SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {
// Begin processor table
OS << "// Sorted (by key) array of values for CPU subtype.\n"
<< "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n";
<< "static const llvm::SubtargetFeatureKV "
<< Target << "SubTypeKV[] = {\n";
// For each processor
for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
@@ -151,7 +162,7 @@ void SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {
OS << "0ULL";
} else {
for (unsigned j = 0, M = FeatureList.size(); j < M;) {
OS << FeatureList[j]->getName();
OS << Target << "::" << FeatureList[j]->getName();
if (++j < M) OS << " | ";
}
}
@@ -168,10 +179,7 @@ void SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {
// End processor table
OS << "};\n";
// Emit size of table
OS<<"\nenum {\n";
OS<<" SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n";
OS<<"};\n";
return ProcessorList.size();
}
//
@@ -192,11 +200,6 @@ CollectAllItinClasses(raw_ostream &OS,
ItinClassesMap[ItinClass->getName()] = i;
}
// Emit size of table
OS<<"\nenum {\n";
OS<<" ItinClassesSize = " << N << "\n";
OS<<"};\n";
// Return itinerary class count
return N;
}
@@ -336,15 +339,18 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
}
// Begin stages table
std::string StageTable = "\nstatic const llvm::InstrStage Stages[] = {\n";
std::string StageTable = "\nstatic const llvm::InstrStage " + Target +
"Stages[] = {\n";
StageTable += " { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n";
// Begin operand cycle table
std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n";
std::string OperandCycleTable = "static const unsigned " + Target +
"OperandCycles[] = {\n";
OperandCycleTable += " 0, // No itinerary\n";
// Begin pipeline bypass table
std::string BypassTable = "static const unsigned ForwardingPathes[] = {\n";
std::string BypassTable = "static const unsigned " + Target +
"ForwardingPathes[] = {\n";
BypassTable += " 0, // No itinerary\n";
unsigned StageCount = 1, OperandCycleCount = 1;
@@ -457,12 +463,6 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
OS << StageTable;
OS << OperandCycleTable;
OS << BypassTable;
// Emit size of tables
OS<<"\nenum {\n";
OS<<" StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage),\n";
OS<<" OperandCyclesSize = sizeof(OperandCycles)/sizeof(unsigned)\n";
OS<<"};\n";
}
//
@@ -533,7 +533,8 @@ void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {
// Begin processor table
OS << "\n";
OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
<< "static const llvm::SubtargetInfoKV ProcItinKV[] = {\n";
<< "static const llvm::SubtargetInfoKV "
<< Target << "ProcItinKV[] = {\n";
// For each processor
for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
@@ -559,12 +560,6 @@ void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {
// End processor table
OS << "};\n";
// Emit size of table
OS<<"\nenum {\n";
OS<<" ProcItinKVSize = sizeof(ProcItinKV)/"
"sizeof(llvm::SubtargetInfoKV)\n";
OS<<"};\n";
}
//
@@ -599,7 +594,9 @@ void SubtargetEmitter::EmitData(raw_ostream &OS) {
// ParseFeaturesFunction - Produces a subtarget specific function for parsing
// the subtarget features string.
//
void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) {
void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS,
unsigned NumFeatures,
unsigned NumProcs) {
std::vector<Record*> Features =
Records.getAllDerivedDefinitions("SubtargetFeature");
std::sort(Features.begin(), Features.end(), LessRecord());
@@ -611,11 +608,18 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) {
OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"
<< " const std::string &CPU) {\n"
<< " DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n"
<< " DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n"
<< " SubtargetFeatures Features(FS);\n"
<< " DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n";
if (Features.empty()) {
OS << "}\n";
return;
}
OS << " SubtargetFeatures Features(FS);\n"
<< " uint64_t Bits = Features.getFeatureBits(CPU, "
<< "SubTypeKV, SubTypeKVSize,\n"
<< " FeatureKV, FeatureKVSize);\n";
<< Target << "SubTypeKV, " << NumProcs << ",\n"
<< " " << Target << "FeatureKV, "
<< NumFeatures << ");\n";
for (unsigned i = 0; i < Features.size(); i++) {
// Next record
@@ -625,20 +629,12 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) {
const std::string &Attribute = R->getValueAsString("Attribute");
if (Value=="true" || Value=="false")
OS << " if ((Bits & " << Instance << ") != 0) "
OS << " if ((Bits & " << Target << "::" << Instance << ") != 0) "
<< Attribute << " = " << Value << ";\n";
else
OS << " if ((Bits & " << Instance << ") != 0 && " << Attribute <<
" < " << Value << ") " << Attribute << " = " << Value << ";\n";
}
if (HasItineraries) {
OS << "\n"
<< " InstrItinerary *Itinerary = (InstrItinerary *)"
<< "Features.getItinerary(CPU, "
<< "ProcItinKV, ProcItinKVSize);\n"
<< " InstrItins = InstrItineraryData(Stages, OperandCycles, "
<< "ForwardingPathes, Itinerary);\n";
OS << " if ((Bits & " << Target << "::" << Instance << ") != 0 && "
<< Attribute << " < " << Value << ") "
<< Attribute << " = " << Value << ";\n";
}
OS << "}\n";
@@ -652,22 +648,90 @@ void SubtargetEmitter::run(raw_ostream &OS) {
EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
OS << "#include \"llvm/Support/Debug.h\"\n";
OS << "#include \"llvm/Support/raw_ostream.h\"\n";
OS << "#include \"llvm/MC/SubtargetFeature.h\"\n";
OS << "#include \"llvm/MC/MCInstrItineraries.h\"\n\n";
OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n";
OS << "#undef GET_SUBTARGETINFO_MC_DESC\n";
// Enumeration(OS, "FuncUnit", true);
// OS<<"\n";
// Enumeration(OS, "InstrItinClass", false);
// OS<<"\n";
OS << "namespace llvm {\n";
Enumeration(OS, "SubtargetFeature", true);
OS<<"\n";
FeatureKeyValues(OS);
unsigned NumFeatures = FeatureKeyValues(OS);
OS<<"\n";
CPUKeyValues(OS);
unsigned NumProcs = CPUKeyValues(OS);
OS<<"\n";
EmitData(OS);
OS<<"\n";
ParseFeaturesFunction(OS);
// MCInstrInfo initialization routine.
OS << "static inline void Init" << Target
<< "MCSubtargetInfo(MCSubtargetInfo *II) {\n";
OS << " II->InitMCSubtargetInfo(";
if (NumFeatures)
OS << Target << "FeatureKV, ";
else
OS << "0, ";
if (NumProcs)
OS << Target << "SubTypeKV, ";
else
OS << "0, ";
if (HasItineraries) {
OS << Target << "ProcItinKV, "
<< Target << "Stages, "
<< Target << "OperandCycles, "
<< Target << "ForwardingPathes, ";
} else
OS << "0, 0, 0, 0, ";
OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
OS << "} // End llvm namespace \n";
OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n";
OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n";
OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n";
OS << "#include \"llvm/Support/Debug.h\"\n";
OS << "#include \"llvm/Support/raw_ostream.h\"\n";
ParseFeaturesFunction(OS, NumFeatures, NumProcs);
OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n";
// Create a TargetSubtarget subclass to hide the MC layer initialization.
OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n";
OS << "#undef GET_SUBTARGETINFO_HEADER\n";
std::string ClassName = Target + "GenSubtargetInfo";
OS << "namespace llvm {\n";
OS << "struct " << ClassName << " : public TargetSubtarget {\n"
<< " explicit " << ClassName << "();\n"
<< "};\n";
OS << "} // End llvm namespace \n";
OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n";
OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n";
OS << "#undef GET_SUBTARGETINFO_CTOR\n";
OS << "namespace llvm {\n";
OS << ClassName << "::" << ClassName << "()\n"
<< " : TargetSubtarget() {\n"
<< " InitMCSubtargetInfo(";
if (NumFeatures)
OS << Target << "FeatureKV, ";
else
OS << "0, ";
if (NumProcs)
OS << Target << "SubTypeKV, ";
else
OS << "0, ";
if (HasItineraries) {
OS << Target << "ProcItinKV, "
<< Target << "Stages, "
<< Target << "OperandCycles, "
<< Target << "ForwardingPathes, ";
} else
OS << "0, 0, 0, 0, ";
OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
OS << "} // End llvm namespace \n";
OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n";
}

View File

@@ -30,8 +30,8 @@ class SubtargetEmitter : public TableGenBackend {
bool HasItineraries;
void Enumeration(raw_ostream &OS, const char *ClassName, bool isBits);
void FeatureKeyValues(raw_ostream &OS);
void CPUKeyValues(raw_ostream &OS);
unsigned FeatureKeyValues(raw_ostream &OS);
unsigned CPUKeyValues(raw_ostream &OS);
unsigned CollectAllItinClasses(raw_ostream &OS,
std::map<std::string,unsigned> &ItinClassesMap,
std::vector<Record*> &ItinClassList);
@@ -52,7 +52,8 @@ class SubtargetEmitter : public TableGenBackend {
std::vector<std::vector<InstrItinerary> > &ProcList);
void EmitProcessorLookup(raw_ostream &OS);
void EmitData(raw_ostream &OS);
void ParseFeaturesFunction(raw_ostream &OS);
void ParseFeaturesFunction(raw_ostream &OS, unsigned NumFeatures,
unsigned NumProcs);
public:
SubtargetEmitter(RecordKeeper &R) : Records(R), HasItineraries(false) {}