[MC][TableGen] Add optional libpfm counter names for ProcResUnits.
Summary:
Subtargets can define the libpfm counter names that can be used to
measure cycles and uops issued on ProcResUnits.
This allows making llvm-exegesis available on more targets.
Fixes PR36984.
Reviewers: gchatelet, RKSimon, andreadb, craig.topper
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D45360
llvm-svn: 329675
diff --git a/llvm/utils/TableGen/CodeGenSchedule.cpp b/llvm/utils/TableGen/CodeGenSchedule.cpp
index f117282..db6c909 100644
--- a/llvm/utils/TableGen/CodeGenSchedule.cpp
+++ b/llvm/utils/TableGen/CodeGenSchedule.cpp
@@ -239,6 +239,11 @@
// Collect processor RetireControlUnit descriptors if available.
collectRetireControlUnits();
+
+ // Find pfm counter definitions for each processor.
+ collectPfmCounters();
+
+ checkCompleteness();
}
/// Gather all processor models.
@@ -1537,6 +1542,23 @@
}
}
+// Collect all the RegisterFile definitions available in this target.
+void CodeGenSchedModels::collectPfmCounters() {
+ for (Record *Def : Records.getAllDerivedDefinitions("PfmIssueCounter")) {
+ CodeGenProcModel &PM = getProcModel(Def->getValueAsDef("SchedModel"));
+ PM.PfmIssueCounterDefs.emplace_back(Def);
+ }
+ for (Record *Def : Records.getAllDerivedDefinitions("PfmCycleCounter")) {
+ CodeGenProcModel &PM = getProcModel(Def->getValueAsDef("SchedModel"));
+ if (PM.PfmCycleCounterDef) {
+ PrintFatalError(Def->getLoc(),
+ "multiple cycle counters for " +
+ Def->getValueAsDef("SchedModel")->getName());
+ }
+ PM.PfmCycleCounterDef = Def;
+ }
+}
+
// Collect and sort WriteRes, ReadAdvance, and ProcResources.
void CodeGenSchedModels::collectProcResources() {
ProcResourceDefs = Records.getAllDerivedDefinitions("ProcResourceUnits");
diff --git a/llvm/utils/TableGen/CodeGenSchedule.h b/llvm/utils/TableGen/CodeGenSchedule.h
index 8379a92..1479812 100644
--- a/llvm/utils/TableGen/CodeGenSchedule.h
+++ b/llvm/utils/TableGen/CodeGenSchedule.h
@@ -238,6 +238,10 @@
// Optional Retire Control Unit definition.
Record *RetireControlUnit;
+ // List of PfmCounters.
+ RecVec PfmIssueCounterDefs;
+ Record *PfmCycleCounterDef = nullptr;
+
CodeGenProcModel(unsigned Idx, std::string Name, Record *MDef,
Record *IDef) :
Index(Idx), ModelName(std::move(Name)), ModelDef(MDef), ItinsDef(IDef),
@@ -252,7 +256,9 @@
}
bool hasExtraProcessorInfo() const {
- return RetireControlUnit || !RegisterFiles.empty();
+ return RetireControlUnit || !RegisterFiles.empty() ||
+ !PfmIssueCounterDefs.empty() ||
+ PfmCycleCounterDef != nullptr;
}
unsigned getProcResourceIdx(Record *PRDef) const;
@@ -444,6 +450,8 @@
void collectRegisterFiles();
+ void collectPfmCounters();
+
void collectOptionalProcessorInfo();
std::string createSchedClassName(Record *ItinClassDef,
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp
index 443a752..e42f27a 100644
--- a/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -635,7 +635,7 @@
OS << ProcModel.ModelName << "RegisterCosts,\n ";
else
OS << "nullptr,\n ";
- OS << NumCostEntries << " // Number of register cost entries.\n";
+ OS << NumCostEntries << ", // Number of register cost entries.\n";
}
unsigned
@@ -686,6 +686,57 @@
return CostTblIndex;
}
+static bool EmitPfmIssueCountersTable(const CodeGenProcModel &ProcModel,
+ raw_ostream &OS) {
+ std::vector<const Record *> CounterDefs(ProcModel.ProcResourceDefs.size());
+ bool HasCounters = false;
+ for (const Record *CounterDef : ProcModel.PfmIssueCounterDefs) {
+ const Record *&CD = CounterDefs[ProcModel.getProcResourceIdx(
+ CounterDef->getValueAsDef("Resource"))];
+ if (CD) {
+ PrintFatalError(CounterDef->getLoc(),
+ "multiple issue counters for " +
+ CounterDef->getValueAsDef("Resource")->getName());
+ }
+ CD = CounterDef;
+ HasCounters = true;
+ }
+ if (!HasCounters) {
+ return false;
+ }
+ OS << "\nstatic const char* " << ProcModel.ModelName
+ << "PfmIssueCounters[] = {\n";
+ for (const Record *CounterDef : CounterDefs) {
+ if (CounterDef) {
+ const auto PfmCounters = CounterDef->getValueAsListOfStrings("Counters");
+ if (PfmCounters.empty())
+ PrintFatalError(CounterDef->getLoc(), "empty counter list");
+ for (const StringRef CounterName : PfmCounters)
+ OS << " \"" << CounterName << ",\"";
+ OS << ", //" << CounterDef->getValueAsDef("Resource")->getName() << "\n";
+ } else {
+ OS << " nullptr,\n";
+ }
+ }
+ OS << "};\n";
+ return true;
+}
+
+static void EmitPfmCounters(const CodeGenProcModel &ProcModel,
+ const bool HasPfmIssueCounters, raw_ostream &OS) {
+ // Emit the cycle counter.
+ if (ProcModel.PfmCycleCounterDef)
+ OS << " \"" << ProcModel.PfmCycleCounterDef->getValueAsString("Counter")
+ << "\", // Cycle counter.\n";
+ else
+ OS << " nullptr, // No cycle counter.\n";
+
+ // Emit a reference to issue counters table.
+ if (HasPfmIssueCounters)
+ OS << " " << ProcModel.ModelName << "PfmIssueCounters\n";
+ else
+ OS << " nullptr, // No issue counters.\n";
+}
void SubtargetEmitter::EmitExtraProcessorInfo(const CodeGenProcModel &ProcModel,
raw_ostream &OS) {
@@ -693,6 +744,9 @@
// defined register file), and a table of register costs.
unsigned NumCostEntries = EmitRegisterFileTables(ProcModel, OS);
+ // Generate a table of ProcRes counter names.
+ const bool HasPfmIssueCounters = EmitPfmIssueCountersTable(ProcModel, OS);
+
// Now generate a table for the extra processor info.
OS << "\nstatic const llvm::MCExtraProcessorInfo " << ProcModel.ModelName
<< "ExtraInfo = {\n ";
@@ -705,6 +759,8 @@
EmitRegisterFileInfo(ProcModel, ProcModel.RegisterFiles.size(),
NumCostEntries, OS);
+ EmitPfmCounters(ProcModel, HasPfmIssueCounters, OS);
+
OS << "};\n";
}
@@ -1308,9 +1364,9 @@
else
OS << " nullptr, // No Itinerary\n";
if (PM.hasExtraProcessorInfo())
- OS << " &" << PM.ModelName << "ExtraInfo\n";
+ OS << " &" << PM.ModelName << "ExtraInfo,\n";
else
- OS << " nullptr // No extra processor descriptor\n";
+ OS << " nullptr // No extra processor descriptor\n";
OS << "};\n";
}
}