From 021ba269b241e9394d652293d327813eb7766923 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Mon, 17 Sep 2012 22:18:58 +0000 Subject: [PATCH] TableGen subtarget emitter. Generate resolveSchedClass generated hook for resolving instruction variants. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164062 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetSubtargetInfo.h | 9 +++ utils/TableGen/SubtargetEmitter.cpp | 84 +++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h index bc357ac5294..8fcefcbfa77 100644 --- a/include/llvm/Target/TargetSubtargetInfo.h +++ b/include/llvm/Target/TargetSubtargetInfo.h @@ -53,6 +53,15 @@ public: SchedModel.init(*getSchedModel(), this, TII); } + /// Resolve a SchedClass at runtime, where SchedClass identifies an + /// MCSchedClassDesc with the isVariant property. This may return the ID of + /// another variant SchedClass, but repeated invocation must quickly terminate + /// in a nonvariant SchedClass. + virtual unsigned resolveSchedClass(unsigned SchedClass, const MachineInstr *MI, + const TargetSchedModel* SchedModel) const { + return 0; + } + /// getSpecialAddressLatency - For targets where it is beneficial to /// backschedule instructions that compute addresses, return a value /// indicating the number of scheduling cycles of backscheduling that diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp index cd034ef2e90..80f3708b51e 100644 --- a/utils/TableGen/SubtargetEmitter.cpp +++ b/utils/TableGen/SubtargetEmitter.cpp @@ -87,6 +87,7 @@ class SubtargetEmitter { void EmitSchedClassTables(SchedClassTables &SchedTables, raw_ostream &OS); void EmitProcessorModels(raw_ostream &OS); void EmitProcessorLookup(raw_ostream &OS); + void EmitSchedModelHelpers(std::string ClassName, raw_ostream &OS); void EmitSchedModel(raw_ostream &OS); void ParseFeaturesFunction(raw_ostream &OS, unsigned NumFeatures, unsigned NumProcs); @@ -1109,6 +1110,85 @@ void SubtargetEmitter::EmitSchedModel(raw_ostream &OS) { OS << "#undef DBGFIELD"; } +void SubtargetEmitter::EmitSchedModelHelpers(std::string ClassName, + raw_ostream &OS) { + OS << "unsigned " << ClassName + << "\n::resolveSchedClass(unsigned SchedClass, const MachineInstr *MI," + << " const TargetSchedModel *SchedModel) const {\n"; + + std::vector Prologs = Records.getAllDerivedDefinitions("PredicateProlog"); + std::sort(Prologs.begin(), Prologs.end(), LessRecord()); + for (std::vector::const_iterator + PI = Prologs.begin(), PE = Prologs.end(); PI != PE; ++PI) { + OS << (*PI)->getValueAsString("Code") << '\n'; + } + IdxVec VariantClasses; + for (CodeGenSchedModels::SchedClassIter SCI = SchedModels.schedClassBegin(), + SCE = SchedModels.schedClassEnd(); SCI != SCE; ++SCI) { + if (SCI->Transitions.empty()) + continue; + VariantClasses.push_back(SCI - SchedModels.schedClassBegin()); + } + if (!VariantClasses.empty()) { + OS << " switch (SchedClass) {\n"; + for (IdxIter VCI = VariantClasses.begin(), VCE = VariantClasses.end(); + VCI != VCE; ++VCI) { + const CodeGenSchedClass &SC = SchedModels.getSchedClass(*VCI); + OS << " case " << *VCI << ": // " << SC.Name << '\n'; + IdxVec ProcIndices; + for (std::vector::const_iterator + TI = SC.Transitions.begin(), TE = SC.Transitions.end(); + TI != TE; ++TI) { + IdxVec PI; + std::set_union(TI->ProcIndices.begin(), TI->ProcIndices.end(), + ProcIndices.begin(), ProcIndices.end(), + std::back_inserter(PI)); + ProcIndices.swap(PI); + } + for (IdxIter PI = ProcIndices.begin(), PE = ProcIndices.end(); + PI != PE; ++PI) { + OS << " "; + if (*PI != 0) + OS << "if (SchedModel->getProcessorID() == " << *PI << ") "; + OS << "{ // " << (SchedModels.procModelBegin() + *PI)->ModelName + << '\n'; + for (std::vector::const_iterator + TI = SC.Transitions.begin(), TE = SC.Transitions.end(); + TI != TE; ++TI) { + OS << " if ("; + if (*PI != 0 && !std::count(TI->ProcIndices.begin(), + TI->ProcIndices.end(), *PI)) { + continue; + } + for (RecIter RI = TI->PredTerm.begin(), RE = TI->PredTerm.end(); + RI != RE; ++RI) { + if (RI != TI->PredTerm.begin()) + OS << "\n && "; + OS << "(" << (*RI)->getValueAsString("Predicate") << ")"; + } + OS << ")\n" + << " return " << TI->ToClassIdx << "; // " + << SchedModels.getSchedClass(TI->ToClassIdx).Name << '\n'; + } + OS << " }\n"; + if (*PI == 0) + break; + } + unsigned SCIdx = 0; + if (SC.ItinClassDef) + SCIdx = SchedModels.getSchedClassIdxForItin(SC.ItinClassDef); + else + SCIdx = SchedModels.findSchedClassIdx(SC.Writes, SC.Reads); + if (SCIdx != *VCI) + OS << " return " << SCIdx << ";\n"; + OS << " break;\n"; + } + OS << " };\n"; + } + OS << " report_fatal_error(\"Expected a variant SchedClass\");\n" + << "} // " << ClassName << "::resolveSchedClass\n"; +} + // // ParseFeaturesFunction - Produces a subtarget specific function for parsing // the subtarget features string. @@ -1238,6 +1318,8 @@ void SubtargetEmitter::run(raw_ostream &OS) { << " explicit " << ClassName << "(StringRef TT, StringRef CPU, " << "StringRef FS);\n" << "public:\n" + << " unsigned resolveSchedClass(unsigned SchedClass, const MachineInstr *DefMI," + << " const TargetSchedModel *SchedModel) const;\n" << " DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)" << " const;\n" << "};\n"; @@ -1291,6 +1373,8 @@ void SubtargetEmitter::run(raw_ostream &OS) { OS << "0, 0, 0, "; OS << NumFeatures << ", " << NumProcs << ");\n}\n\n"; + EmitSchedModelHelpers(ClassName, OS); + OS << "} // End llvm namespace \n"; OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n"; -- 2.34.1