diff options
author | Evan Cheng <evan.cheng@apple.com> | 2011-07-01 20:45:01 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2011-07-01 20:45:01 +0000 |
commit | 94214703d97d8d9dfca88174ffc7e94820a85e62 (patch) | |
tree | 92edaa7cf8adfab8d915bdb21eb1d78267faee4e /utils | |
parent | eb03c3b22861e5fb6459aa055378e852df29b621 (diff) | |
download | external_llvm-94214703d97d8d9dfca88174ffc7e94820a85e62.zip external_llvm-94214703d97d8d9dfca88174ffc7e94820a85e62.tar.gz external_llvm-94214703d97d8d9dfca88174ffc7e94820a85e62.tar.bz2 |
- 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
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/InstrInfoEmitter.cpp | 4 | ||||
-rw-r--r-- | utils/TableGen/SubtargetEmitter.cpp | 200 | ||||
-rw-r--r-- | utils/TableGen/SubtargetEmitter.h | 7 |
3 files changed, 138 insertions, 73 deletions
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 5e2fdf0..18d4db0 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -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, " diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp index c823cb1..a55836f 100644 --- a/utils/TableGen/SubtargetEmitter.cpp +++ b/utils/TableGen/SubtargetEmitter.cpp @@ -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"; } diff --git a/utils/TableGen/SubtargetEmitter.h b/utils/TableGen/SubtargetEmitter.h index cf793c8..b239f3d 100644 --- a/utils/TableGen/SubtargetEmitter.h +++ b/utils/TableGen/SubtargetEmitter.h @@ -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) {} |