[MCSched] Bind PFM Counters to the CPUs instead of the SchedModel.
Summary:
The pfm counters are now in the ExegesisTarget rather than the
MCSchedModel (PR39165).
This also compresses the pfm counter tables (PR37068).
Reviewers: RKSimon, gchatelet
Subscribers: mgrang, llvm-commits
Differential Revision: https://reviews.llvm.org/D52932
llvm-svn: 345243
diff --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt
index 0428249..c88365a 100644
--- a/llvm/utils/TableGen/CMakeLists.txt
+++ b/llvm/utils/TableGen/CMakeLists.txt
@@ -21,6 +21,7 @@
DAGISelMatcher.cpp
DFAPacketizerEmitter.cpp
DisassemblerEmitter.cpp
+ ExegesisEmitter.cpp
FastISelEmitter.cpp
FixedLenDecoderEmitter.cpp
GlobalISelEmitter.cpp
diff --git a/llvm/utils/TableGen/CodeGenSchedule.cpp b/llvm/utils/TableGen/CodeGenSchedule.cpp
index e94ed76..a9a36a8 100644
--- a/llvm/utils/TableGen/CodeGenSchedule.cpp
+++ b/llvm/utils/TableGen/CodeGenSchedule.cpp
@@ -350,7 +350,7 @@
unsigned OpcodeIdx = Opcode2Index[Opcode];
if (OpcodeMasks[OpcodeIdx].first[ProcIndex]) {
std::string Message =
- "Opcode " + Opcode->getName().str() +
+ "Opcode " + Opcode->getName().str() +
" used by multiple InstructionEquivalenceClass definitions.";
PrintFatalError(EC->getLoc(), Message);
}
@@ -487,9 +487,6 @@
// Collect processor RetireControlUnit descriptors if available.
collectRetireControlUnits();
- // Find pfm counter definitions for each processor.
- collectPfmCounters();
-
checkCompleteness();
}
@@ -1789,32 +1786,6 @@
}
}
-// 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;
- }
- for (Record *Def : Records.getAllDerivedDefinitions("PfmUopsCounter")) {
- CodeGenProcModel &PM = getProcModel(Def->getValueAsDef("SchedModel"));
- if (PM.PfmUopsCounterDef) {
- PrintFatalError(Def->getLoc(),
- "multiple uops counters for " +
- Def->getValueAsDef("SchedModel")->getName());
- }
- PM.PfmUopsCounterDef = 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 39443bb..9bde5f4 100644
--- a/llvm/utils/TableGen/CodeGenSchedule.h
+++ b/llvm/utils/TableGen/CodeGenSchedule.h
@@ -246,11 +246,6 @@
// Optional Retire Control Unit definition.
Record *RetireControlUnit;
- // List of PfmCounters.
- RecVec PfmIssueCounterDefs;
- Record *PfmCycleCounterDef = nullptr;
- Record *PfmUopsCounterDef = nullptr;
-
CodeGenProcModel(unsigned Idx, std::string Name, Record *MDef,
Record *IDef) :
Index(Idx), ModelName(std::move(Name)), ModelDef(MDef), ItinsDef(IDef),
@@ -265,10 +260,7 @@
}
bool hasExtraProcessorInfo() const {
- return RetireControlUnit || !RegisterFiles.empty() ||
- !PfmIssueCounterDefs.empty() ||
- PfmCycleCounterDef != nullptr ||
- PfmUopsCounterDef != nullptr;
+ return RetireControlUnit || !RegisterFiles.empty();
}
unsigned getProcResourceIdx(Record *PRDef) const;
@@ -593,8 +585,6 @@
void collectRegisterFiles();
- void collectPfmCounters();
-
void collectOptionalProcessorInfo();
std::string createSchedClassName(Record *ItinClassDef,
diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp
index 2766fcc..305d2d1 100644
--- a/llvm/utils/TableGen/CodeGenTarget.cpp
+++ b/llvm/utils/TableGen/CodeGenTarget.cpp
@@ -711,4 +711,3 @@
// Sort the argument attributes for later benefit.
llvm::sort(ArgumentAttributes);
}
-
diff --git a/llvm/utils/TableGen/ExegesisEmitter.cpp b/llvm/utils/TableGen/ExegesisEmitter.cpp
new file mode 100644
index 0000000..083d743
--- /dev/null
+++ b/llvm/utils/TableGen/ExegesisEmitter.cpp
@@ -0,0 +1,212 @@
+//===- ExegesisEmitter.cpp - Generate exegesis target data ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend emits llvm-exegesis information.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <map>
+#include <string>
+#include <vector>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "exegesis-emitter"
+
+namespace {
+
+class ExegesisEmitter {
+public:
+ ExegesisEmitter(RecordKeeper &RK);
+
+ void run(raw_ostream &OS) const;
+
+private:
+ unsigned getPfmCounterId(llvm::StringRef Name) const {
+ const auto It = PfmCounterNameTable.find(Name);
+ if (It == PfmCounterNameTable.end())
+ PrintFatalError("no pfm counter id for " + Name);
+ return It->second;
+ }
+
+ // Collects all the ProcPfmCounters definitions available in this target.
+ void emitPfmCounters(raw_ostream &OS) const;
+
+ void emitPfmCountersInfo(const Record &Def,
+ unsigned &IssueCountersTableOffset,
+ raw_ostream &OS) const;
+
+ void emitPfmCountersLookupTable(raw_ostream &OS) const;
+
+ RecordKeeper &Records;
+ std::string Target;
+
+ // Table of counter name -> counter index.
+ const std::map<llvm::StringRef, unsigned> PfmCounterNameTable;
+};
+
+static std::map<llvm::StringRef, unsigned>
+collectPfmCounters(const RecordKeeper &Records) {
+ std::map<llvm::StringRef, unsigned> PfmCounterNameTable;
+ const auto AddPfmCounterName = [&PfmCounterNameTable](
+ const Record *PfmCounterDef) {
+ const llvm::StringRef Counter = PfmCounterDef->getValueAsString("Counter");
+ if (!Counter.empty())
+ PfmCounterNameTable.emplace(Counter, 0);
+ };
+ for (Record *Def : Records.getAllDerivedDefinitions("ProcPfmCounters")) {
+ // Check that ResourceNames are unique.
+ llvm::SmallSet<llvm::StringRef, 16> Seen;
+ for (const Record *IssueCounter :
+ Def->getValueAsListOfDefs("IssueCounters")) {
+ const llvm::StringRef ResourceName =
+ IssueCounter->getValueAsString("ResourceName");
+ if (ResourceName.empty())
+ PrintFatalError(IssueCounter->getLoc(), "invalid empty ResourceName");
+ if (!Seen.insert(ResourceName).second)
+ PrintFatalError(IssueCounter->getLoc(),
+ "duplicate ResourceName " + ResourceName);
+ AddPfmCounterName(IssueCounter);
+ }
+ AddPfmCounterName(Def->getValueAsDef("CycleCounter"));
+ AddPfmCounterName(Def->getValueAsDef("UopsCounter"));
+ }
+ unsigned Index = 0;
+ for (auto &NameAndIndex : PfmCounterNameTable)
+ NameAndIndex.second = Index++;
+ return PfmCounterNameTable;
+}
+
+ExegesisEmitter::ExegesisEmitter(RecordKeeper &RK)
+ : Records(RK), PfmCounterNameTable(collectPfmCounters(RK)) {
+ std::vector<Record *> Targets = Records.getAllDerivedDefinitions("Target");
+ if (Targets.size() == 0)
+ PrintFatalError("ERROR: No 'Target' subclasses defined!");
+ if (Targets.size() != 1)
+ PrintFatalError("ERROR: Multiple subclasses of Target defined!");
+ Target = Targets[0]->getName();
+}
+
+void ExegesisEmitter::emitPfmCountersInfo(const Record &Def,
+ unsigned &IssueCountersTableOffset,
+ raw_ostream &OS) const {
+ const auto CycleCounter =
+ Def.getValueAsDef("CycleCounter")->getValueAsString("Counter");
+ const auto UopsCounter =
+ Def.getValueAsDef("UopsCounter")->getValueAsString("Counter");
+ const size_t NumIssueCounters =
+ Def.getValueAsListOfDefs("IssueCounters").size();
+
+ // This is the default, do not emit.
+ if (CycleCounter.empty() && UopsCounter.empty() && NumIssueCounters == 0)
+ return;
+
+ OS << "\nstatic const PfmCountersInfo " << Target << Def.getName()
+ << " = {\n";
+
+ // Cycle Counter.
+ if (CycleCounter.empty())
+ OS << " nullptr, // No cycle counter.\n";
+ else
+ OS << " " << Target << "PfmCounterNames[" << getPfmCounterId(CycleCounter)
+ << "], // Cycle counter\n";
+
+ // Uops Counter.
+ if (UopsCounter.empty())
+ OS << " nullptr, // No uops counter.\n";
+ else
+ OS << " " << Target << "PfmCounterNames[" << getPfmCounterId(UopsCounter)
+ << "], // Uops counter\n";
+
+ // Issue Counters
+ if (NumIssueCounters == 0)
+ OS << " nullptr, // No issue counters.\n 0\n";
+ else
+ OS << " " << Target << "PfmIssueCounters + " << IssueCountersTableOffset
+ << ", " << NumIssueCounters << " // Issue counters.\n";
+
+ OS << "};\n";
+ IssueCountersTableOffset += NumIssueCounters;
+}
+
+void ExegesisEmitter::emitPfmCounters(raw_ostream &OS) const {
+ // Emit the counter name table.
+ OS << "\nstatic const char* " << Target << "PfmCounterNames[] = {\n";
+ for (const auto &NameAndIndex : PfmCounterNameTable)
+ OS << " \"" << NameAndIndex.first << "\", // " << NameAndIndex.second
+ << "\n";
+ OS << "};\n\n";
+
+ // Emit the IssueCounters table.
+ const auto PfmCounterDefs =
+ Records.getAllDerivedDefinitions("ProcPfmCounters");
+ OS << "static const PfmCountersInfo::IssueCounter " << Target
+ << "PfmIssueCounters[] = {\n";
+ for (const Record *Def : PfmCounterDefs) {
+ for (const Record *ICDef : Def->getValueAsListOfDefs("IssueCounters"))
+ OS << " { " << Target << "PfmCounterNames["
+ << getPfmCounterId(ICDef->getValueAsString("Counter")) << "], \""
+ << ICDef->getValueAsString("ResourceName") << "\"},\n";
+ }
+
+ OS << "};\n";
+
+ // Now generate the PfmCountersInfo.
+ unsigned IssueCountersTableOffset = 0;
+ for (const Record *Def : PfmCounterDefs)
+ emitPfmCountersInfo(*Def, IssueCountersTableOffset, OS);
+
+ OS << "\n";
+}
+
+void ExegesisEmitter::emitPfmCountersLookupTable(raw_ostream &OS) const {
+ std::vector<Record *> Bindings =
+ Records.getAllDerivedDefinitions("PfmCountersBinding");
+ llvm::sort(Bindings, [](const Record *L, const Record *R) {
+ return L->getValueAsString("CpuName") < R->getValueAsString("CpuName");
+ });
+
+ OS << "// Sorted (by CpuName) array of pfm counters.\n"
+ << "static const CpuAndPfmCounters " << Target << "CpuPfmCounters[] = {\n";
+ for (Record *Binding : Bindings) {
+ // Emit as { "cpu", procinit },
+ OS << " { \"" //
+ << Binding->getValueAsString("CpuName") << "\"," //
+ << " &" << Target << Binding->getValueAsDef("Counters")->getName() //
+ << " },\n";
+ }
+ OS << "};\n\n";
+}
+
+void ExegesisEmitter::run(raw_ostream &OS) const {
+ emitSourceFileHeader("Exegesis Tables", OS);
+ emitPfmCounters(OS);
+ emitPfmCountersLookupTable(OS);
+}
+
+} // end anonymous namespace
+
+namespace llvm {
+
+void EmitExegesis(RecordKeeper &RK, raw_ostream &OS) {
+ ExegesisEmitter(RK).run(OS);
+}
+
+} // end namespace llvm
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp
index d1ea968..4ff52b3 100644
--- a/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -697,80 +697,12 @@
return CostTblIndex;
}
-static bool EmitPfmIssueCountersTable(const CodeGenProcModel &ProcModel,
- raw_ostream &OS) {
- unsigned NumCounterDefs = 1 + ProcModel.ProcResourceDefs.size();
- std::vector<const Record *> CounterDefs(NumCounterDefs);
- 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 (unsigned i = 0; i != NumCounterDefs; ++i) {
- const Record *CounterDef = CounterDefs[i];
- if (CounterDef) {
- const auto PfmCounters = CounterDef->getValueAsListOfStrings("Counters");
- if (PfmCounters.empty())
- PrintFatalError(CounterDef->getLoc(), "empty counter list");
- OS << " \"" << PfmCounters[0];
- for (unsigned p = 1, e = PfmCounters.size(); p != e; ++p)
- OS << ",\" \"" << PfmCounters[p];
- OS << "\", // #" << i << " = ";
- OS << CounterDef->getValueAsDef("Resource")->getName() << "\n";
- } else {
- OS << " nullptr, // #" << i << "\n";
- }
- }
- OS << "};\n";
- return true;
-}
-
-static void EmitPfmCounters(const CodeGenProcModel &ProcModel,
- const bool HasPfmIssueCounters, raw_ostream &OS) {
- OS << " {\n";
- // Emit the cycle counter.
- if (ProcModel.PfmCycleCounterDef)
- OS << " \"" << ProcModel.PfmCycleCounterDef->getValueAsString("Counter")
- << "\", // Cycle counter.\n";
- else
- OS << " nullptr, // No cycle counter.\n";
-
- // Emit the uops counter.
- if (ProcModel.PfmUopsCounterDef)
- OS << " \"" << ProcModel.PfmUopsCounterDef->getValueAsString("Counter")
- << "\", // Uops counter.\n";
- else
- OS << " nullptr, // No uops counter.\n";
-
- // Emit a reference to issue counters table.
- if (HasPfmIssueCounters)
- OS << " " << ProcModel.ModelName << "PfmIssueCounters\n";
- else
- OS << " nullptr // No issue counters.\n";
- OS << " }\n";
-}
-
void SubtargetEmitter::EmitExtraProcessorInfo(const CodeGenProcModel &ProcModel,
raw_ostream &OS) {
// Generate a table of register file descriptors (one entry per each user
// 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 ";
@@ -783,8 +715,6 @@
EmitRegisterFileInfo(ProcModel, ProcModel.RegisterFiles.size(),
NumCostEntries, OS);
- EmitPfmCounters(ProcModel, HasPfmIssueCounters, OS);
-
OS << "};\n";
}
@@ -1410,7 +1340,7 @@
}
//
-// EmitProcessorLookup - generate cpu name to itinerary lookup table.
+// EmitProcessorLookup - generate cpu name to sched model lookup tables.
//
void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {
// Gather and sort processor information
@@ -1418,12 +1348,11 @@
Records.getAllDerivedDefinitions("Processor");
llvm::sort(ProcessorList, LessRecordFieldName());
- // Begin processor table
+ // Begin processor->sched model table
OS << "\n";
- OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
- << "extern const llvm::SubtargetInfoKV "
- << Target << "ProcSchedKV[] = {\n";
-
+ OS << "// Sorted (by key) array of sched model for CPU subtype.\n"
+ << "extern const llvm::SubtargetInfoKV " << Target
+ << "ProcSchedKV[] = {\n";
// For each processor
for (Record *Processor : ProcessorList) {
StringRef Name = Processor->getValueAsString("Name");
@@ -1433,8 +1362,7 @@
// Emit as { "cpu", procinit },
OS << " { \"" << Name << "\", (const void *)&" << ProcModelName << " },\n";
}
-
- // End processor table
+ // End processor->sched model table
OS << "};\n";
}
@@ -1675,7 +1603,7 @@
// Emit target predicates.
emitSchedModelHelpersImpl(OS);
-
+
OS << "} // " << ClassName << "::resolveSchedClass\n\n";
OS << "unsigned " << ClassName
diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp
index b782606..d5b6a3c 100644
--- a/llvm/utils/TableGen/TableGen.cpp
+++ b/llvm/utils/TableGen/TableGen.cpp
@@ -53,6 +53,7 @@
GenX86EVEX2VEXTables,
GenX86FoldTables,
GenRegisterBank,
+ GenExegesis,
};
namespace {
@@ -117,7 +118,9 @@
clEnumValN(GenX86FoldTables, "gen-x86-fold-tables",
"Generate X86 fold tables"),
clEnumValN(GenRegisterBank, "gen-register-bank",
- "Generate registers bank descriptions")));
+ "Generate registers bank descriptions"),
+ clEnumValN(GenExegesis, "gen-exegesis",
+ "Generate llvm-exegesis tables")));
cl::OptionCategory PrintEnumsCat("Options for -print-enums");
cl::opt<std::string>
@@ -231,6 +234,9 @@
case GenX86FoldTables:
EmitX86FoldTables(Records, OS);
break;
+ case GenExegesis:
+ EmitExegesis(Records, OS);
+ break;
}
return false;
diff --git a/llvm/utils/TableGen/TableGenBackends.h b/llvm/utils/TableGen/TableGenBackends.h
index 1329a6d..f4f2909 100644
--- a/llvm/utils/TableGen/TableGenBackends.h
+++ b/llvm/utils/TableGen/TableGenBackends.h
@@ -89,6 +89,7 @@
void EmitX86EVEX2VEXTables(RecordKeeper &RK, raw_ostream &OS);
void EmitX86FoldTables(RecordKeeper &RK, raw_ostream &OS);
void EmitRegisterBank(RecordKeeper &RK, raw_ostream &OS);
+void EmitExegesis(RecordKeeper &RK, raw_ostream &OS);
} // End llvm namespace