-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[MC] Use StringTable for MCSchedClassDesc names #137012
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[MC] Use StringTable for MCSchedClassDesc names #137012
Conversation
Use StringTable for the name strings so that large arrays of MCSchedClassDesc can live in read-only data. This only affects builds with assertions enabled, otherwise these strings are compiled out. This improves startup times for llc on my Ubuntu system where PIE is enabled by default. In a Release+Asserts build it reduced the check-llvm time from 159 to 112 seconds.
@llvm/pr-subscribers-tools-llvm-mca @llvm/pr-subscribers-mc Author: Jay Foad (jayfoad) ChangesUse StringTable for the name strings so that large arrays of This improves startup times for llc on my Ubuntu system where PIE is Full diff: https://github.com/llvm/llvm-project/pull/137012.diff 7 Files Affected:
diff --git a/llvm/include/llvm/MC/MCSchedule.h b/llvm/include/llvm/MC/MCSchedule.h
index 57c8ebeee02a7..2d6d0d4199ee6 100644
--- a/llvm/include/llvm/MC/MCSchedule.h
+++ b/llvm/include/llvm/MC/MCSchedule.h
@@ -15,6 +15,7 @@
#define LLVM_MC_MCSCHEDULE_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringTable.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
@@ -123,7 +124,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;
@@ -321,6 +322,9 @@ struct MCSchedModel {
unsigned ProcID;
const MCProcResourceDesc *ProcResourceTable;
const MCSchedClassDesc *SchedClassTable;
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ StringTable SchedClassNameTable = "";
+#endif
unsigned NumProcResourceKinds;
unsigned NumSchedClasses;
// Instruction itinerary tables used by InstrItineraryData.
@@ -408,6 +412,12 @@ struct MCSchedModel {
/// Returns the default initialized model.
static const MCSchedModel Default;
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ StringRef getSchedClassName(const MCSchedClassDesc *SCDesc) const {
+ return SchedClassNameTable[SCDesc->NameOffset];
+ }
+#endif
};
// The first three are only template'd arguments so we can get away with leaving
diff --git a/llvm/lib/MC/MCSchedule.cpp b/llvm/lib/MC/MCSchedule.cpp
index 8aea08919f469..b1e1904d654c8 100644
--- a/llvm/lib/MC/MCSchedule.cpp
+++ b/llvm/lib/MC/MCSchedule.cpp
@@ -20,24 +20,25 @@
using namespace llvm;
-static_assert(std::is_trivial_v<MCSchedModel>,
- "MCSchedModel is required to be a trivial type");
-const MCSchedModel MCSchedModel::Default = {DefaultIssueWidth,
- DefaultMicroOpBufferSize,
- DefaultLoopMicroOpBufferSize,
- DefaultLoadLatency,
- DefaultHighLatency,
- DefaultMispredictPenalty,
- false,
- true,
- /*EnableIntervals=*/false,
- 0,
- nullptr,
- nullptr,
- 0,
- 0,
- nullptr,
- nullptr};
+constexpr MCSchedModel MCSchedModel::Default = {DefaultIssueWidth,
+ DefaultMicroOpBufferSize,
+ DefaultLoopMicroOpBufferSize,
+ DefaultLoadLatency,
+ DefaultHighLatency,
+ DefaultMispredictPenalty,
+ false,
+ true,
+ /*EnableIntervals=*/false,
+ 0,
+ nullptr,
+ nullptr,
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ "",
+#endif
+ 0,
+ 0,
+ nullptr,
+ nullptr};
int MCSchedModel::computeInstrLatency(const MCSubtargetInfo &STI,
const MCSchedClassDesc &SCDesc) {
diff --git a/llvm/lib/MCA/InstrBuilder.cpp b/llvm/lib/MCA/InstrBuilder.cpp
index 2bac99b6309af..d80eb28115b47 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 "
+ << SM.getSchedClassName(&SCDesc) << " (write index #"
+ << I << ")\n";
#endif
continue;
}
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..496f23b016a7e 100644
--- a/llvm/tools/llvm-exegesis/lib/Analysis.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Analysis.cpp
@@ -137,9 +137,9 @@ 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 MCSchedClassDesc *const SCDesc =
- State_.getSubtargetInfo().getSchedModel().getSchedClassDesc(SchedClassId);
- writeEscaped<kEscapeCsv>(OS, SCDesc->Name);
+ const MCSchedModel &SM = State_.getSubtargetInfo().getSchedModel();
+ const MCSchedClassDesc *const SCDesc = SM.getSchedClassDesc(SchedClassId);
+ writeEscaped<kEscapeCsv>(OS, SM.getSchedClassName(SCDesc));
#else
OS << SchedClassId;
#endif
@@ -563,7 +563,9 @@ Error Analysis::run<Analysis::PrintSchedClassInconsistencies>(
OS << "<div class=\"inconsistency\"><p>Sched Class <span "
"class=\"sched-class-name\">";
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- writeEscaped<kEscapeHtml>(OS, RSCAndPoints.RSC.SCDesc->Name);
+ const auto &SM = SI.getSchedModel();
+ writeEscaped<kEscapeHtml>(OS,
+ SM.getSchedClassName(RSCAndPoints.RSC.SCDesc));
#else
OS << RSCAndPoints.RSC.SchedClassId;
#endif
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp
index 8d2fc99f84670..a454575e609e2 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 <algorithm>
@@ -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")
@@ -1467,6 +1472,7 @@ void SubtargetEmitter::emitSchedClassTables(SchedClassTables &SchedTables,
<< MCDesc.NumReadAdvanceEntries << "}, // #" << SCIdx << '\n';
}
OS << "}; // " << Proc.ModelName << "SchedClasses\n";
+ NameTable.EmitStringTableDef(OS, Proc.ModelName + "SchedClassNames");
}
}
@@ -1516,10 +1522,11 @@ void SubtargetEmitter::emitProcessorModels(raw_ostream &OS) {
if (PM.hasInstrSchedModel())
OS << " " << PM.ModelName << "ProcResources" << ",\n"
<< " " << PM.ModelName << "SchedClasses" << ",\n"
+ << " DBGFIELD(" << PM.ModelName << "SchedClassNames" << ")\n"
<< " " << PM.ProcResourceDefs.size() + 1 << ",\n"
<< " " << SchedModels.schedClasses().size() << ",\n";
else
- OS << " nullptr, nullptr, 0, 0,"
+ OS << " nullptr, nullptr, DBGFIELD(\"\") 0, 0,"
<< " // No instruction-level machine model.\n";
if (PM.hasItineraries())
OS << " " << PM.ItinsDef->getName() << ",\n";
@@ -1561,10 +1568,10 @@ void SubtargetEmitter::emitSchedModel(raw_ostream &OS) {
}
emitSchedClassTables(SchedTables, OS);
- OS << "\n#undef DBGFIELD\n";
-
// Emit the processor machine model
emitProcessorModels(OS);
+
+ OS << "\n#undef DBGFIELD\n";
}
static void emitPredicateProlog(const RecordKeeper &Records, raw_ostream &OS) {
|
@llvm/pr-subscribers-tools-llvm-exegesis Author: Jay Foad (jayfoad) ChangesUse StringTable for the name strings so that large arrays of This improves startup times for llc on my Ubuntu system where PIE is Full diff: https://github.com/llvm/llvm-project/pull/137012.diff 7 Files Affected:
diff --git a/llvm/include/llvm/MC/MCSchedule.h b/llvm/include/llvm/MC/MCSchedule.h
index 57c8ebeee02a7..2d6d0d4199ee6 100644
--- a/llvm/include/llvm/MC/MCSchedule.h
+++ b/llvm/include/llvm/MC/MCSchedule.h
@@ -15,6 +15,7 @@
#define LLVM_MC_MCSCHEDULE_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringTable.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
@@ -123,7 +124,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;
@@ -321,6 +322,9 @@ struct MCSchedModel {
unsigned ProcID;
const MCProcResourceDesc *ProcResourceTable;
const MCSchedClassDesc *SchedClassTable;
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ StringTable SchedClassNameTable = "";
+#endif
unsigned NumProcResourceKinds;
unsigned NumSchedClasses;
// Instruction itinerary tables used by InstrItineraryData.
@@ -408,6 +412,12 @@ struct MCSchedModel {
/// Returns the default initialized model.
static const MCSchedModel Default;
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ StringRef getSchedClassName(const MCSchedClassDesc *SCDesc) const {
+ return SchedClassNameTable[SCDesc->NameOffset];
+ }
+#endif
};
// The first three are only template'd arguments so we can get away with leaving
diff --git a/llvm/lib/MC/MCSchedule.cpp b/llvm/lib/MC/MCSchedule.cpp
index 8aea08919f469..b1e1904d654c8 100644
--- a/llvm/lib/MC/MCSchedule.cpp
+++ b/llvm/lib/MC/MCSchedule.cpp
@@ -20,24 +20,25 @@
using namespace llvm;
-static_assert(std::is_trivial_v<MCSchedModel>,
- "MCSchedModel is required to be a trivial type");
-const MCSchedModel MCSchedModel::Default = {DefaultIssueWidth,
- DefaultMicroOpBufferSize,
- DefaultLoopMicroOpBufferSize,
- DefaultLoadLatency,
- DefaultHighLatency,
- DefaultMispredictPenalty,
- false,
- true,
- /*EnableIntervals=*/false,
- 0,
- nullptr,
- nullptr,
- 0,
- 0,
- nullptr,
- nullptr};
+constexpr MCSchedModel MCSchedModel::Default = {DefaultIssueWidth,
+ DefaultMicroOpBufferSize,
+ DefaultLoopMicroOpBufferSize,
+ DefaultLoadLatency,
+ DefaultHighLatency,
+ DefaultMispredictPenalty,
+ false,
+ true,
+ /*EnableIntervals=*/false,
+ 0,
+ nullptr,
+ nullptr,
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ "",
+#endif
+ 0,
+ 0,
+ nullptr,
+ nullptr};
int MCSchedModel::computeInstrLatency(const MCSubtargetInfo &STI,
const MCSchedClassDesc &SCDesc) {
diff --git a/llvm/lib/MCA/InstrBuilder.cpp b/llvm/lib/MCA/InstrBuilder.cpp
index 2bac99b6309af..d80eb28115b47 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 "
+ << SM.getSchedClassName(&SCDesc) << " (write index #"
+ << I << ")\n";
#endif
continue;
}
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..496f23b016a7e 100644
--- a/llvm/tools/llvm-exegesis/lib/Analysis.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Analysis.cpp
@@ -137,9 +137,9 @@ 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 MCSchedClassDesc *const SCDesc =
- State_.getSubtargetInfo().getSchedModel().getSchedClassDesc(SchedClassId);
- writeEscaped<kEscapeCsv>(OS, SCDesc->Name);
+ const MCSchedModel &SM = State_.getSubtargetInfo().getSchedModel();
+ const MCSchedClassDesc *const SCDesc = SM.getSchedClassDesc(SchedClassId);
+ writeEscaped<kEscapeCsv>(OS, SM.getSchedClassName(SCDesc));
#else
OS << SchedClassId;
#endif
@@ -563,7 +563,9 @@ Error Analysis::run<Analysis::PrintSchedClassInconsistencies>(
OS << "<div class=\"inconsistency\"><p>Sched Class <span "
"class=\"sched-class-name\">";
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- writeEscaped<kEscapeHtml>(OS, RSCAndPoints.RSC.SCDesc->Name);
+ const auto &SM = SI.getSchedModel();
+ writeEscaped<kEscapeHtml>(OS,
+ SM.getSchedClassName(RSCAndPoints.RSC.SCDesc));
#else
OS << RSCAndPoints.RSC.SchedClassId;
#endif
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp
index 8d2fc99f84670..a454575e609e2 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 <algorithm>
@@ -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")
@@ -1467,6 +1472,7 @@ void SubtargetEmitter::emitSchedClassTables(SchedClassTables &SchedTables,
<< MCDesc.NumReadAdvanceEntries << "}, // #" << SCIdx << '\n';
}
OS << "}; // " << Proc.ModelName << "SchedClasses\n";
+ NameTable.EmitStringTableDef(OS, Proc.ModelName + "SchedClassNames");
}
}
@@ -1516,10 +1522,11 @@ void SubtargetEmitter::emitProcessorModels(raw_ostream &OS) {
if (PM.hasInstrSchedModel())
OS << " " << PM.ModelName << "ProcResources" << ",\n"
<< " " << PM.ModelName << "SchedClasses" << ",\n"
+ << " DBGFIELD(" << PM.ModelName << "SchedClassNames" << ")\n"
<< " " << PM.ProcResourceDefs.size() + 1 << ",\n"
<< " " << SchedModels.schedClasses().size() << ",\n";
else
- OS << " nullptr, nullptr, 0, 0,"
+ OS << " nullptr, nullptr, DBGFIELD(\"\") 0, 0,"
<< " // No instruction-level machine model.\n";
if (PM.hasItineraries())
OS << " " << PM.ItinsDef->getName() << ",\n";
@@ -1561,10 +1568,10 @@ void SubtargetEmitter::emitSchedModel(raw_ostream &OS) {
}
emitSchedClassTables(SchedTables, OS);
- OS << "\n#undef DBGFIELD\n";
-
// Emit the processor machine model
emitProcessorModels(OS);
+
+ OS << "\n#undef DBGFIELD\n";
}
static void emitPredicateProlog(const RecordKeeper &Records, raw_ostream &OS) {
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it'll be a good idea to share a single StringTable for all the sched models under the same target, e.g. A single X86SchedClassNames instead of Znver3SchedClassNames, SkylakeSchedClassNames etc. Given the fact that they basically share the same set of sched class names?
Yes, good idea, done. It shrinks the llc binary significantly, in my case from ~162 MB to 150 MB. |
Looks like the build failure is related. LLVMNVPTXCodeGen.lib(NVPTXSubtarget.cpp.obj) : error LNK2019: unresolved external symbol "class llvm::StringTable const llvm::NVPTXNameTable" |
@@ -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} = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can we renumber 1 and 2 and swap the args to formatv()? Just that its easier to follow if they are in increasing order to the extent possible,
@@ -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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we guard this def as well with if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
? And in the constructor, assert that the NT
passed is empty() in non-assert builds optionally?
NameTable.EmitStringTableDef(OS, Target + "NameTable", /*Indent=*/"", | ||
"extern"); | ||
OS << "\n#else\n"; | ||
OS << "\nextern constexpr llvm::StringTable " << Target |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extern constexpr
? I'm surprised this even compiles.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that could also be the cause of the link failure seen above
OS << "\n#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)\n"; | ||
NameTable.EmitStringTableDef(OS, Target + "NameTable", /*Indent=*/"", | ||
"extern"); | ||
OS << "\n#else\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C++ raw string might make this easier to read
Use StringTable for the name strings so that large arrays of
MCSchedClassDesc can live in read-only data. This only affects builds
with assertions enabled, otherwise these strings are compiled out.
This improves startup times for llc on my Ubuntu system where PIE is
enabled by default. In a Release+Asserts build it reduced the check-llvm
time from 159 to 112 seconds.