diff --git a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h index 1230349956973..8864dac157b99 100644 --- a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h +++ b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h @@ -69,7 +69,7 @@ class TargetSubtargetInfo : public MCSubtargetInfo { const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL, const MCReadAdvanceEntry *RA, const InstrStage *IS, - const unsigned *OC, const unsigned *FP); + const unsigned *OC, const unsigned *FP, StringTable NT); public: // AntiDepBreakMode - Type of anti-dependence breaking that should diff --git a/llvm/include/llvm/MC/MCSchedule.h b/llvm/include/llvm/MC/MCSchedule.h index 57c8ebeee02a7..22c6dd7ea45f4 100644 --- a/llvm/include/llvm/MC/MCSchedule.h +++ b/llvm/include/llvm/MC/MCSchedule.h @@ -123,7 +123,7 @@ struct MCSchedClassDesc { static const unsigned short VariantNumMicroOps = InvalidNumMicroOps - 1; #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - const char* Name; + unsigned NameOffset; #endif uint16_t NumMicroOps : 13; uint16_t BeginGroup : 1; diff --git a/llvm/include/llvm/MC/MCSubtargetInfo.h b/llvm/include/llvm/MC/MCSubtargetInfo.h index 535bcfe2fb6d7..e0aa700fc5743 100644 --- a/llvm/include/llvm/MC/MCSubtargetInfo.h +++ b/llvm/include/llvm/MC/MCSubtargetInfo.h @@ -16,6 +16,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringTable.h" #include "llvm/MC/MCInstrItineraries.h" #include "llvm/MC/MCSchedule.h" #include "llvm/TargetParser/SubtargetFeature.h" @@ -93,6 +94,10 @@ class MCSubtargetInfo { FeatureBitset FeatureBits; // Feature bits for current CPU + FS std::string FeatureString; // Feature string + // General purpose name table, currently only used to store MCSchedClassDesc + // names when assertions are enabled. + StringTable NameTable; + public: MCSubtargetInfo(const MCSubtargetInfo &) = default; MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef TuneCPU, @@ -101,7 +106,7 @@ class MCSubtargetInfo { ArrayRef PD, const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL, const MCReadAdvanceEntry *RA, const InstrStage *IS, - const unsigned *OC, const unsigned *FP); + const unsigned *OC, const unsigned *FP, StringTable NT); MCSubtargetInfo() = delete; MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete; MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete; @@ -226,6 +231,12 @@ class MCSubtargetInfo { return 0; } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) + StringRef getSchedClassName(const MCSchedClassDesc *SCDesc) const { + return NameTable[SCDesc->NameOffset]; + } +#endif + /// Check whether the CPU string is valid. virtual bool isCPUStringValid(StringRef CPU) const { auto Found = llvm::lower_bound(ProcDesc, CPU); diff --git a/llvm/include/llvm/TableGen/StringToOffsetTable.h b/llvm/include/llvm/TableGen/StringToOffsetTable.h index 21795644d4bd6..016ce32e2c4f9 100644 --- a/llvm/include/llvm/TableGen/StringToOffsetTable.h +++ b/llvm/include/llvm/TableGen/StringToOffsetTable.h @@ -57,7 +57,8 @@ class StringToOffsetTable { // `static` and `constexpr`. Both `Name` and (`Name` + "Storage") must be // valid identifiers to declare. void EmitStringTableDef(raw_ostream &OS, const Twine &Name, - const Twine &Indent = "") const; + const Twine &Indent = "", + StringRef Linkage = "static") const; // Emit the string as one single string. void EmitString(raw_ostream &O) const; diff --git a/llvm/lib/CodeGen/TargetSubtargetInfo.cpp b/llvm/lib/CodeGen/TargetSubtargetInfo.cpp index cd396e6a619a8..8a8dce315db24 100644 --- a/llvm/lib/CodeGen/TargetSubtargetInfo.cpp +++ b/llvm/lib/CodeGen/TargetSubtargetInfo.cpp @@ -19,9 +19,10 @@ TargetSubtargetInfo::TargetSubtargetInfo( ArrayRef PN, ArrayRef PF, ArrayRef PD, const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL, const MCReadAdvanceEntry *RA, - const InstrStage *IS, const unsigned *OC, const unsigned *FP) - : MCSubtargetInfo(TT, CPU, TuneCPU, FS, PN, PF, PD, WPR, WL, RA, IS, OC, - FP) {} + const InstrStage *IS, const unsigned *OC, const unsigned *FP, + StringTable NT) + : MCSubtargetInfo(TT, CPU, TuneCPU, FS, PN, PF, PD, WPR, WL, RA, IS, OC, FP, + NT) {} TargetSubtargetInfo::~TargetSubtargetInfo() = default; diff --git a/llvm/lib/MC/MCSubtargetInfo.cpp b/llvm/lib/MC/MCSubtargetInfo.cpp index d86eaad48420d..41a815a6774bb 100644 --- a/llvm/lib/MC/MCSubtargetInfo.cpp +++ b/llvm/lib/MC/MCSubtargetInfo.cpp @@ -245,16 +245,19 @@ void MCSubtargetInfo::setDefaultFeatures(StringRef CPU, StringRef TuneCPU, FeatureString = std::string(FS); } -MCSubtargetInfo::MCSubtargetInfo( - const Triple &TT, StringRef C, StringRef TC, StringRef FS, - ArrayRef PN, ArrayRef PF, - ArrayRef PD, const MCWriteProcResEntry *WPR, - const MCWriteLatencyEntry *WL, const MCReadAdvanceEntry *RA, - const InstrStage *IS, const unsigned *OC, const unsigned *FP) +MCSubtargetInfo::MCSubtargetInfo(const Triple &TT, StringRef C, StringRef TC, + StringRef FS, ArrayRef PN, + ArrayRef PF, + ArrayRef PD, + const MCWriteProcResEntry *WPR, + const MCWriteLatencyEntry *WL, + const MCReadAdvanceEntry *RA, + const InstrStage *IS, const unsigned *OC, + const unsigned *FP, StringTable NT) : TargetTriple(TT), CPU(std::string(C)), TuneCPU(std::string(TC)), ProcNames(PN), ProcFeatures(PF), ProcDesc(PD), WriteProcResTable(WPR), WriteLatencyTable(WL), ReadAdvanceTable(RA), Stages(IS), - OperandCycles(OC), ForwardingPaths(FP) { + OperandCycles(OC), ForwardingPaths(FP), NameTable(NT) { InitMCProcessorInfo(CPU, TuneCPU, FS); } diff --git a/llvm/lib/MCA/InstrBuilder.cpp b/llvm/lib/MCA/InstrBuilder.cpp index 2bac99b6309af..dca0d59f1a5b7 100644 --- a/llvm/lib/MCA/InstrBuilder.cpp +++ b/llvm/lib/MCA/InstrBuilder.cpp @@ -75,8 +75,9 @@ static void initializeUsedResources(InstrDesc &ID, WithColor::warning() << "Ignoring invalid write of zero cycles on processor resource " << PR.Name << "\n"; - WithColor::note() << "found in scheduling class " << SCDesc.Name - << " (write index #" << I << ")\n"; + WithColor::note() << "found in scheduling class " + << STI.getSchedClassName(&SCDesc) << " (write index #" + << I << ")\n"; #endif continue; } diff --git a/llvm/lib/TableGen/StringToOffsetTable.cpp b/llvm/lib/TableGen/StringToOffsetTable.cpp index d73b5749ad7d5..23f9788833d4b 100644 --- a/llvm/lib/TableGen/StringToOffsetTable.cpp +++ b/llvm/lib/TableGen/StringToOffsetTable.cpp @@ -27,7 +27,8 @@ unsigned StringToOffsetTable::GetOrAddStringOffset(StringRef Str, } void StringToOffsetTable::EmitStringTableDef(raw_ostream &OS, const Twine &Name, - const Twine &Indent) const { + const Twine &Indent, + StringRef Linkage) const { OS << formatv(R"( #ifdef __GNUC__ #pragma GCC diagnostic push @@ -78,10 +79,10 @@ void StringToOffsetTable::EmitStringTableDef(raw_ostream &OS, const Twine &Name, #pragma GCC diagnostic pop #endif -{0}static constexpr llvm::StringTable {1} = +{0}{2} constexpr llvm::StringTable {1} = {0} {1}Storage; )", - Indent, Name); + Indent, Name, Linkage); } void StringToOffsetTable::EmitString(raw_ostream &O) const { diff --git a/llvm/test/TableGen/CompressWriteLatencyEntry.td b/llvm/test/TableGen/CompressWriteLatencyEntry.td index 88273e8858448..a6a942882ca7f 100644 --- a/llvm/test/TableGen/CompressWriteLatencyEntry.td +++ b/llvm/test/TableGen/CompressWriteLatencyEntry.td @@ -33,10 +33,10 @@ def Read_D : SchedRead; // CHECK-NEXT: }; // MyTargetReadAdvanceTable // CHECK: static const llvm::MCSchedClassDesc SchedModel_ASchedClasses[] = { -// CHECK-NEXT: {DBGFIELD("InvalidSchedClass") 8191, false, false, false, 0, 0, 0, 0, 0, 0}, -// CHECK-NEXT: {DBGFIELD("Inst_A") 1, false, false, false, 0, 0, 1, 1, 0, 0}, // #1 -// CHECK-NEXT: {DBGFIELD("Inst_B") 1, false, false, false, 0, 0, 2, 1, 0, 0}, // #2 -// CHECK-NEXT: {DBGFIELD("Inst_C") 1, false, false, false, 0, 0, 1, 1, 1, 1}, // #3 +// CHECK-NEXT: {DBGFIELD(1 /* InvalidSchedClass */) 8191, false, false, false, 0, 0, 0, 0, 0, 0}, +// CHECK-NEXT: {DBGFIELD(19 /* Inst_A */) 1, false, false, false, 0, 0, 1, 1, 0, 0}, // #1 +// CHECK-NEXT: {DBGFIELD(26 /* Inst_B */) 1, false, false, false, 0, 0, 2, 1, 0, 0}, // #2 +// CHECK-NEXT: {DBGFIELD(33 /* Inst_C */) 1, false, false, false, 0, 0, 1, 1, 1, 1}, // #3 // CHECK-NEXT: }; // SchedModel_ASchedClasses let SchedModel = SchedModel_A in { diff --git a/llvm/test/TableGen/InvalidMCSchedClassDesc.td b/llvm/test/TableGen/InvalidMCSchedClassDesc.td index de5392237a84c..5e12d088088ac 100644 --- a/llvm/test/TableGen/InvalidMCSchedClassDesc.td +++ b/llvm/test/TableGen/InvalidMCSchedClassDesc.td @@ -18,8 +18,8 @@ let CompleteModel = 0 in { // Inst_B didn't have the resoures, and it is invalid. // CHECK: SchedModel_ASchedClasses[] = { -// CHECK: {DBGFIELD("Inst_A") 1 -// CHECK-NEXT: {DBGFIELD("Inst_B") 8191 +// CHECK: {DBGFIELD(19 /* Inst_A */) 1 +// CHECK-NEXT: {DBGFIELD(26 /* Inst_B */) 8191 let SchedModel = SchedModel_A in { def Write_A : SchedWriteRes<[]>; def : InstRW<[Write_A], (instrs Inst_A)>; @@ -27,16 +27,16 @@ let SchedModel = SchedModel_A in { // Inst_A didn't have the resoures, and it is invalid. // CHECK: SchedModel_BSchedClasses[] = { -// CHECK: {DBGFIELD("Inst_A") 8191 -// CHECK-NEXT: {DBGFIELD("Inst_B") 1 +// CHECK: {DBGFIELD(19 /* Inst_A */) 8191 +// CHECK-NEXT: {DBGFIELD(26 /* Inst_B */) 1 let SchedModel = SchedModel_B in { def Write_B: SchedWriteRes<[]>; def : InstRW<[Write_B], (instrs Inst_B)>; } // CHECK: SchedModel_CSchedClasses[] = { -// CHECK: {DBGFIELD("Inst_A") 1 -// CHECK-NEXT: {DBGFIELD("Inst_B") 1 +// CHECK: {DBGFIELD(19 /* Inst_A */) 1 +// CHECK-NEXT: {DBGFIELD(26 /* Inst_B */) 1 let SchedModel = SchedModel_C in { def Write_C: SchedWriteRes<[]>; def : InstRW<[Write_C], (instrs Inst_A, Inst_B)>; diff --git a/llvm/tools/llvm-exegesis/lib/Analysis.cpp b/llvm/tools/llvm-exegesis/lib/Analysis.cpp index be10c32cf08d5..1fb8c394e31f0 100644 --- a/llvm/tools/llvm-exegesis/lib/Analysis.cpp +++ b/llvm/tools/llvm-exegesis/lib/Analysis.cpp @@ -137,9 +137,10 @@ void Analysis::printInstructionRowCsv(const size_t PointId, std::tie(SchedClassId, std::ignore) = ResolvedSchedClass::resolveSchedClassId( State_.getSubtargetInfo(), State_.getInstrInfo(), MCI); #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) + const auto &SI = State_.getSubtargetInfo(); const MCSchedClassDesc *const SCDesc = - State_.getSubtargetInfo().getSchedModel().getSchedClassDesc(SchedClassId); - writeEscaped(OS, SCDesc->Name); + SI.getSchedModel().getSchedClassDesc(SchedClassId); + writeEscaped(OS, SI.getSchedClassName(SCDesc)); #else OS << SchedClassId; #endif @@ -563,7 +564,8 @@ Error Analysis::run( OS << "

Sched Class "; #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - writeEscaped(OS, RSCAndPoints.RSC.SCDesc->Name); + writeEscaped(OS, + SI.getSchedClassName(RSCAndPoints.RSC.SCDesc)); #else OS << RSCAndPoints.RSC.SchedClassId; #endif diff --git a/llvm/unittests/CodeGen/MFCommon.inc b/llvm/unittests/CodeGen/MFCommon.inc index 425453fb0e280..19141a3dc5958 100644 --- a/llvm/unittests/CodeGen/MFCommon.inc +++ b/llvm/unittests/CodeGen/MFCommon.inc @@ -79,7 +79,7 @@ class BogusSubtarget : public TargetSubtargetInfo { public: BogusSubtarget(TargetMachine &TM) : TargetSubtargetInfo(Triple(""), "", "", "", {}, {}, {}, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr), + nullptr, nullptr, nullptr, nullptr, nullptr, ""), FL(), TL(TM) {} ~BogusSubtarget() override {} diff --git a/llvm/unittests/Target/AArch64/AArch64InstPrinterTest.cpp b/llvm/unittests/Target/AArch64/AArch64InstPrinterTest.cpp index 4dfc0bcb0dc4c..6c285adaa46a1 100644 --- a/llvm/unittests/Target/AArch64/AArch64InstPrinterTest.cpp +++ b/llvm/unittests/Target/AArch64/AArch64InstPrinterTest.cpp @@ -39,7 +39,7 @@ static std::string AArch64InstPrinterTestPrintAlignedLabel(uint64_t value) { MCSubtargetInfo STI(Triple(""), "", "", "", {}, ArrayRef((SubtargetFeatureKV *)NULL, (size_t)0), ArrayRef((SubtargetSubTypeKV *)NULL, (size_t)0), NULL, - NULL, NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL, ""); MCContext Ctx(Triple(""), &MAI, &MRI, &STI); MCInst MI; diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp index 8d2fc99f84670..a5aaf3beb5028 100644 --- a/llvm/utils/TableGen/SubtargetEmitter.cpp +++ b/llvm/utils/TableGen/SubtargetEmitter.cpp @@ -29,6 +29,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" +#include "llvm/TableGen/StringToOffsetTable.h" #include "llvm/TableGen/TableGenBackend.h" #include "llvm/TargetParser/SubtargetFeature.h" #include @@ -1430,6 +1431,7 @@ void SubtargetEmitter::emitSchedClassTables(SchedClassTables &SchedTables, OS << "}; // " << Target << "ReadAdvanceTable\n"; // Emit a SchedClass table for each processor. + StringToOffsetTable NameTable; for (const auto &[Idx, Proc] : enumerate(SchedModels.procModels())) { if (!Proc.hasInstrSchedModel()) continue; @@ -1446,14 +1448,17 @@ void SubtargetEmitter::emitSchedClassTables(SchedClassTables &SchedTables, // name and position. assert(SchedModels.getSchedClass(0).Name == "NoInstrModel" && "invalid class not first"); - OS << " {DBGFIELD(\"InvalidSchedClass\") " + unsigned NameOffset = NameTable.GetOrAddStringOffset("InvalidSchedClass"); + OS << " {DBGFIELD(" << NameOffset << " /* InvalidSchedClass */) " << MCSchedClassDesc::InvalidNumMicroOps << ", false, false, false, 0, 0, 0, 0, 0, 0},\n"; for (unsigned SCIdx = 1, SCEnd = SCTab.size(); SCIdx != SCEnd; ++SCIdx) { MCSchedClassDesc &MCDesc = SCTab[SCIdx]; const CodeGenSchedClass &SchedClass = SchedModels.getSchedClass(SCIdx); - OS << " {DBGFIELD(\"" << SchedClass.Name << "\") "; + NameOffset = NameTable.GetOrAddStringOffset(SchedClass.Name); + OS << " {DBGFIELD(" << NameOffset << " /* " << SchedClass.Name + << " */) "; if (SchedClass.Name.size() < 18) OS.indent(18 - SchedClass.Name.size()); OS << MCDesc.NumMicroOps << ", " << (MCDesc.BeginGroup ? "true" : "false") @@ -1468,6 +1473,14 @@ void SubtargetEmitter::emitSchedClassTables(SchedClassTables &SchedTables, } OS << "}; // " << Proc.ModelName << "SchedClasses\n"; } + + OS << "\n#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)\n"; + NameTable.EmitStringTableDef(OS, Target + "NameTable", /*Indent=*/"", + "extern"); + OS << "\n#else\n"; + OS << "\nextern constexpr llvm::StringTable " << Target + << "NameTable = \"\";\n"; + OS << "\n#endif\n"; } void SubtargetEmitter::emitProcessorModels(raw_ostream &OS) { @@ -1952,9 +1965,9 @@ void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) { << " const MCWriteProcResEntry *WPR,\n" << " const MCWriteLatencyEntry *WL,\n" << " const MCReadAdvanceEntry *RA, const InstrStage *IS,\n" - << " const unsigned *OC, const unsigned *FP) :\n" + << " const unsigned *OC, const unsigned *FP, StringTable NT) :\n" << " MCSubtargetInfo(TT, CPU, TuneCPU, FS, PN, PF, PD,\n" - << " WPR, WL, RA, IS, OC, FP) { }\n\n" + << " WPR, WL, RA, IS, OC, FP, NT) { }\n\n" << " unsigned resolveVariantSchedClass(unsigned SchedClass,\n" << " const MCInst *MI, const MCInstrInfo *MCII,\n" << " unsigned CPUID) const override {\n" @@ -2059,7 +2072,7 @@ void SubtargetEmitter::run(raw_ostream &OS) { << "ForwardingPaths"; } else OS << "nullptr, nullptr, nullptr"; - OS << ");\n}\n\n"; + OS << ", " << Target << "NameTable);\n}\n\n"; OS << "} // end namespace llvm\n\n"; @@ -2159,6 +2172,8 @@ void SubtargetEmitter::run(raw_ostream &OS) { OS << "extern const unsigned " << Target << "ForwardingPaths[];\n"; } + OS << "extern const llvm::StringTable " << Target << "NameTable;\n"; + OS << ClassName << "::" << ClassName << "(const Triple &TT, StringRef CPU, " << "StringRef TuneCPU, StringRef FS)\n"; @@ -2190,7 +2205,7 @@ void SubtargetEmitter::run(raw_ostream &OS) { << "ForwardingPaths"; } else OS << "nullptr, nullptr, nullptr"; - OS << ") {}\n\n"; + OS << ", " << Target << "NameTable) {}\n\n"; emitSchedModelHelpers(ClassName, OS); emitHwModeCheck(ClassName, OS);