diff options
Diffstat (limited to 'llvm/utils/TableGen/SubtargetEmitter.cpp')
| -rw-r--r-- | llvm/utils/TableGen/SubtargetEmitter.cpp | 122 |
1 files changed, 68 insertions, 54 deletions
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp index 68ee839c43ba..7d2b4b929df3 100644 --- a/llvm/utils/TableGen/SubtargetEmitter.cpp +++ b/llvm/utils/TableGen/SubtargetEmitter.cpp @@ -114,7 +114,6 @@ class SubtargetEmitter { SchedClassTables &SchedTables); void EmitSchedClassTables(SchedClassTables &SchedTables, raw_ostream &OS); void EmitProcessorModels(raw_ostream &OS); - void EmitProcessorLookup(raw_ostream &OS); void EmitSchedModelHelpers(const std::string &ClassName, raw_ostream &OS); void emitSchedModelHelpersImpl(raw_ostream &OS, bool OnlyExpandMCInstPredicates = false); @@ -267,12 +266,15 @@ SubtargetEmitter::CPUKeyValues(raw_ostream &OS, for (Record *Processor : ProcessorList) { StringRef Name = Processor->getValueAsString("Name"); RecVec FeatureList = Processor->getValueAsListOfDefs("Features"); + RecVec TuneFeatureList = Processor->getValueAsListOfDefs("TuneFeatures"); // Emit as { "cpu", "description", 0, { f1 , f2 , ... fn } }, OS << " { " << "\"" << Name << "\", "; printFeatureMask(OS, FeatureList, FeatureMap); + OS << ", "; + printFeatureMask(OS, TuneFeatureList, FeatureMap); // Emit the scheduler model pointer. const std::string &ProcModelName = @@ -728,10 +730,8 @@ void SubtargetEmitter::EmitLoadStoreQueueInfo(const CodeGenProcModel &ProcModel, unsigned QueueID = 0; if (ProcModel.LoadQueue) { const Record *Queue = ProcModel.LoadQueue->getValueAsDef("QueueDescriptor"); - QueueID = - 1 + std::distance(ProcModel.ProcResourceDefs.begin(), - std::find(ProcModel.ProcResourceDefs.begin(), - ProcModel.ProcResourceDefs.end(), Queue)); + QueueID = 1 + std::distance(ProcModel.ProcResourceDefs.begin(), + find(ProcModel.ProcResourceDefs, Queue)); } OS << " " << QueueID << ", // Resource Descriptor for the Load Queue\n"; @@ -739,10 +739,8 @@ void SubtargetEmitter::EmitLoadStoreQueueInfo(const CodeGenProcModel &ProcModel, if (ProcModel.StoreQueue) { const Record *Queue = ProcModel.StoreQueue->getValueAsDef("QueueDescriptor"); - QueueID = - 1 + std::distance(ProcModel.ProcResourceDefs.begin(), - std::find(ProcModel.ProcResourceDefs.begin(), - ProcModel.ProcResourceDefs.end(), Queue)); + QueueID = 1 + std::distance(ProcModel.ProcResourceDefs.begin(), + find(ProcModel.ProcResourceDefs, Queue)); } OS << " " << QueueID << ", // Resource Descriptor for the Store Queue\n"; } @@ -1005,8 +1003,7 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel, bool HasVariants = false; for (const CodeGenSchedTransition &CGT : make_range(SC.Transitions.begin(), SC.Transitions.end())) { - if (CGT.ProcIndices[0] == 0 || - is_contained(CGT.ProcIndices, ProcModel.Index)) { + if (CGT.ProcIndex == ProcModel.Index) { HasVariants = true; break; } @@ -1219,11 +1216,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel, } else { SCDesc.WriteLatencyIdx = SchedTables.WriteLatencies.size(); - SchedTables.WriteLatencies.insert(SchedTables.WriteLatencies.end(), - WriteLatencies.begin(), - WriteLatencies.end()); - SchedTables.WriterNames.insert(SchedTables.WriterNames.end(), - WriterNames.begin(), WriterNames.end()); + llvm::append_range(SchedTables.WriteLatencies, WriteLatencies); + llvm::append_range(SchedTables.WriterNames, WriterNames); } // ReadAdvanceEntries must remain in operand order. SCDesc.NumReadAdvanceEntries = ReadAdvanceEntries.size(); @@ -1235,8 +1229,7 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel, SCDesc.ReadAdvanceIdx = RAPos - SchedTables.ReadAdvanceEntries.begin(); else { SCDesc.ReadAdvanceIdx = SchedTables.ReadAdvanceEntries.size(); - SchedTables.ReadAdvanceEntries.insert(RAPos, ReadAdvanceEntries.begin(), - ReadAdvanceEntries.end()); + llvm::append_range(SchedTables.ReadAdvanceEntries, ReadAdvanceEntries); } } } @@ -1443,20 +1436,20 @@ static void emitPredicateProlog(const RecordKeeper &Records, raw_ostream &OS) { OS << Buffer; } +static bool isTruePredicate(const Record *Rec) { + return Rec->isSubClassOf("MCSchedPredicate") && + Rec->getValueAsDef("Pred")->isSubClassOf("MCTrue"); +} + static void emitPredicates(const CodeGenSchedTransition &T, const CodeGenSchedClass &SC, PredicateExpander &PE, raw_ostream &OS) { std::string Buffer; raw_string_ostream SS(Buffer); - auto IsTruePredicate = [](const Record *Rec) { - return Rec->isSubClassOf("MCSchedPredicate") && - Rec->getValueAsDef("Pred")->isSubClassOf("MCTrue"); - }; - // If not all predicates are MCTrue, then we need an if-stmt. unsigned NumNonTruePreds = - T.PredTerm.size() - count_if(T.PredTerm, IsTruePredicate); + T.PredTerm.size() - count_if(T.PredTerm, isTruePredicate); SS.indent(PE.getIndentLevel() * 2); @@ -1468,7 +1461,7 @@ static void emitPredicates(const CodeGenSchedTransition &T, for (const Record *Rec : T.PredTerm) { // Skip predicates that evaluate to "true". - if (IsTruePredicate(Rec)) + if (isTruePredicate(Rec)) continue; if (FirstNonTruePredicate) { @@ -1504,7 +1497,8 @@ static void emitPredicates(const CodeGenSchedTransition &T, // Used by method `SubtargetEmitter::emitSchedModelHelpersImpl()` to generate // epilogue code for the auto-generated helper. -void emitSchedModelHelperEpilogue(raw_ostream &OS, bool ShouldReturnZero) { +static void emitSchedModelHelperEpilogue(raw_ostream &OS, + bool ShouldReturnZero) { if (ShouldReturnZero) { OS << " // Don't know how to resolve this scheduling class.\n" << " return 0;\n"; @@ -1514,15 +1508,15 @@ void emitSchedModelHelperEpilogue(raw_ostream &OS, bool ShouldReturnZero) { OS << " report_fatal_error(\"Expected a variant SchedClass\");\n"; } -bool hasMCSchedPredicates(const CodeGenSchedTransition &T) { +static bool hasMCSchedPredicates(const CodeGenSchedTransition &T) { return all_of(T.PredTerm, [](const Record *Rec) { return Rec->isSubClassOf("MCSchedPredicate"); }); } -void collectVariantClasses(const CodeGenSchedModels &SchedModels, - IdxVec &VariantClasses, - bool OnlyExpandMCInstPredicates) { +static void collectVariantClasses(const CodeGenSchedModels &SchedModels, + IdxVec &VariantClasses, + bool OnlyExpandMCInstPredicates) { for (const CodeGenSchedClass &SC : SchedModels.schedClasses()) { // Ignore non-variant scheduling classes. if (SC.Transitions.empty()) @@ -1541,19 +1535,24 @@ void collectVariantClasses(const CodeGenSchedModels &SchedModels, } } -void collectProcessorIndices(const CodeGenSchedClass &SC, IdxVec &ProcIndices) { +static void collectProcessorIndices(const CodeGenSchedClass &SC, + IdxVec &ProcIndices) { // A variant scheduling class may define transitions for multiple // processors. This function identifies wich processors are associated with // transition rules specified by variant class `SC`. for (const CodeGenSchedTransition &T : SC.Transitions) { IdxVec PI; - std::set_union(T.ProcIndices.begin(), T.ProcIndices.end(), - ProcIndices.begin(), ProcIndices.end(), - std::back_inserter(PI)); + std::set_union(&T.ProcIndex, &T.ProcIndex + 1, ProcIndices.begin(), + ProcIndices.end(), std::back_inserter(PI)); ProcIndices.swap(PI); } } +static bool isAlwaysTrue(const CodeGenSchedTransition &T) { + return llvm::all_of(T.PredTerm, + [](const Record *R) { return isTruePredicate(R); }); +} + void SubtargetEmitter::emitSchedModelHelpersImpl( raw_ostream &OS, bool OnlyExpandMCInstPredicates) { IdxVec VariantClasses; @@ -1596,8 +1595,9 @@ void SubtargetEmitter::emitSchedModelHelpersImpl( } // Now emit transitions associated with processor PI. + const CodeGenSchedTransition *FinalT = nullptr; for (const CodeGenSchedTransition &T : SC.Transitions) { - if (PI != 0 && !count(T.ProcIndices, PI)) + if (PI != 0 && T.ProcIndex != PI) continue; // Emit only transitions based on MCSchedPredicate, if it's the case. @@ -1610,9 +1610,17 @@ void SubtargetEmitter::emitSchedModelHelpersImpl( if (OnlyExpandMCInstPredicates && !hasMCSchedPredicates(T)) continue; + // If transition is folded to 'return X' it should be the last one. + if (isAlwaysTrue(T)) { + FinalT = &T; + continue; + } PE.setIndentLevel(3); emitPredicates(T, SchedModels.getSchedClass(T.ToClassIdx), PE, OS); } + if (FinalT) + emitPredicates(*FinalT, SchedModels.getSchedClass(FinalT->ToClassIdx), + PE, OS); OS << " }\n"; @@ -1646,9 +1654,9 @@ void SubtargetEmitter::EmitSchedModelHelpers(const std::string &ClassName, OS << "unsigned " << ClassName << "\n::resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI," - << " unsigned CPUID) const {\n" + << " const MCInstrInfo *MCII, unsigned CPUID) const {\n" << " return " << Target << "_MC" - << "::resolveVariantSchedClassImpl(SchedClass, MI, CPUID);\n" + << "::resolveVariantSchedClassImpl(SchedClass, MI, MCII, CPUID);\n" << "} // " << ClassName << "::resolveVariantSchedClass\n\n"; STIPredicateExpander PE(Target); @@ -1692,17 +1700,19 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS, << "// subtarget options.\n" << "void llvm::"; OS << Target; - OS << "Subtarget::ParseSubtargetFeatures(StringRef CPU, StringRef FS) {\n" + OS << "Subtarget::ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, " + << "StringRef FS) {\n" << " LLVM_DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n" - << " LLVM_DEBUG(dbgs() << \"\\nCPU:\" << CPU << \"\\n\\n\");\n"; + << " LLVM_DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n" + << " LLVM_DEBUG(dbgs() << \"\\nTuneCPU:\" << TuneCPU << \"\\n\\n\");\n"; if (Features.empty()) { OS << "}\n"; return; } - OS << " InitMCProcessorInfo(CPU, FS);\n" - << " const FeatureBitset& Bits = getFeatureBits();\n"; + OS << " InitMCProcessorInfo(CPU, TuneCPU, FS);\n" + << " const FeatureBitset &Bits = getFeatureBits();\n"; for (Record *R : Features) { // Next record @@ -1727,26 +1737,28 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS, void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) { OS << "namespace " << Target << "_MC {\n" << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,\n" - << " const MCInst *MI, unsigned CPUID) {\n"; + << " const MCInst *MI, const MCInstrInfo *MCII, unsigned CPUID) {\n"; emitSchedModelHelpersImpl(OS, /* OnlyExpandMCPredicates */ true); OS << "}\n"; OS << "} // end namespace " << Target << "_MC\n\n"; OS << "struct " << Target << "GenMCSubtargetInfo : public MCSubtargetInfo {\n"; - OS << " " << Target << "GenMCSubtargetInfo(const Triple &TT, \n" - << " StringRef CPU, StringRef FS, ArrayRef<SubtargetFeatureKV> PF,\n" + OS << " " << Target << "GenMCSubtargetInfo(const Triple &TT,\n" + << " StringRef CPU, StringRef TuneCPU, StringRef FS,\n" + << " ArrayRef<SubtargetFeatureKV> PF,\n" << " ArrayRef<SubtargetSubTypeKV> PD,\n" << " const MCWriteProcResEntry *WPR,\n" << " const MCWriteLatencyEntry *WL,\n" << " const MCReadAdvanceEntry *RA, const InstrStage *IS,\n" << " const unsigned *OC, const unsigned *FP) :\n" - << " MCSubtargetInfo(TT, CPU, FS, PF, PD,\n" + << " MCSubtargetInfo(TT, CPU, TuneCPU, FS, PF, PD,\n" << " WPR, WL, RA, IS, OC, FP) { }\n\n" << " unsigned resolveVariantSchedClass(unsigned SchedClass,\n" - << " const MCInst *MI, unsigned CPUID) const override {\n" + << " const MCInst *MI, const MCInstrInfo *MCII,\n" + << " unsigned CPUID) const override {\n" << " return " << Target << "_MC" - << "::resolveVariantSchedClassImpl(SchedClass, MI, CPUID); \n"; + << "::resolveVariantSchedClassImpl(SchedClass, MI, MCII, CPUID);\n"; OS << " }\n"; if (TGT.getHwModes().getNumModeIds() > 1) OS << " unsigned getHwMode() const override;\n"; @@ -1817,8 +1829,9 @@ void SubtargetEmitter::run(raw_ostream &OS) { OS << "\nstatic inline MCSubtargetInfo *create" << Target << "MCSubtargetInfoImpl(" - << "const Triple &TT, StringRef CPU, StringRef FS) {\n"; - OS << " return new " << Target << "GenMCSubtargetInfo(TT, CPU, FS, "; + << "const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS) {\n"; + OS << " return new " << Target + << "GenMCSubtargetInfo(TT, CPU, TuneCPU, FS, "; if (NumFeatures) OS << Target << "FeatureKV, "; else @@ -1862,17 +1875,18 @@ void SubtargetEmitter::run(raw_ostream &OS) { OS << "class DFAPacketizer;\n"; OS << "namespace " << Target << "_MC {\n" << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass," - << " const MCInst *MI, unsigned CPUID);\n" + << " const MCInst *MI, const MCInstrInfo *MCII, unsigned CPUID);\n" << "} // end namespace " << Target << "_MC\n\n"; OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n" << " explicit " << ClassName << "(const Triple &TT, StringRef CPU, " - << "StringRef FS);\n" + << "StringRef TuneCPU, StringRef FS);\n" << "public:\n" << " unsigned resolveSchedClass(unsigned SchedClass, " << " const MachineInstr *DefMI," << " const TargetSchedModel *SchedModel) const override;\n" << " unsigned resolveVariantSchedClass(unsigned SchedClass," - << " const MCInst *MI, unsigned CPUID) const override;\n" + << " const MCInst *MI, const MCInstrInfo *MCII," + << " unsigned CPUID) const override;\n" << " DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)" << " const;\n"; if (TGT.getHwModes().getNumModeIds() > 1) @@ -1909,8 +1923,8 @@ void SubtargetEmitter::run(raw_ostream &OS) { } OS << ClassName << "::" << ClassName << "(const Triple &TT, StringRef CPU, " - << "StringRef FS)\n" - << " : TargetSubtargetInfo(TT, CPU, FS, "; + << "StringRef TuneCPU, StringRef FS)\n" + << " : TargetSubtargetInfo(TT, CPU, TuneCPU, FS, "; if (NumFeatures) OS << "makeArrayRef(" << Target << "FeatureKV, " << NumFeatures << "), "; else |
