diff --git a/llvm/include/llvm/Target/TargetPfmCounters.td b/llvm/include/llvm/Target/TargetPfmCounters.td index b00f3e19c35f9..49b2d1fc25651 100644 --- a/llvm/include/llvm/Target/TargetPfmCounters.td +++ b/llvm/include/llvm/Target/TargetPfmCounters.td @@ -28,6 +28,27 @@ class PfmIssueCounter string ResourceName = resource_name; } +// Definition of a validation event. A validation event represents a specific +// event that can be measured using performance counters that is interesting +// in regard to the snippet state. +class ValidationEvent { + int EventNumber = event_number; +} + +def L1DCacheLoadMiss : ValidationEvent<0>; +def InstructionRetired : ValidationEvent<1>; +def DataTLBLoadMiss : ValidationEvent<2>; +def DataTLBStoreMiss : ValidationEvent<3>; + +// PfmValidationCounter provides a mapping between the events that are +// are interesting in regards to the snippet execution environment and +// a concrete performance counter name that can be looked up in libpfm. +class PfmValidationCounter + : PfmCounter { + // The name of the event that the validation counter detects. + ValidationEvent EventType = event_type; +} + def NoPfmCounter : PfmCounter <""> {} // Set of PfmCounters for measuring sched model characteristics. @@ -38,6 +59,9 @@ class ProcPfmCounters { PfmCounter UopsCounter = NoPfmCounter; // Processors can define how to measure issued uops by defining IssueCounters. list IssueCounters = []; + // Processor can list mappings between validation events and real counters + // to measure the specified events. + list ValidationCounters = []; } // A binding of a set of counters to a CPU. diff --git a/llvm/lib/Target/X86/X86PfmCounters.td b/llvm/lib/Target/X86/X86PfmCounters.td index 49ef6efc6aecf..99cac504f157d 100644 --- a/llvm/lib/Target/X86/X86PfmCounters.td +++ b/llvm/lib/Target/X86/X86PfmCounters.td @@ -275,6 +275,9 @@ def ZnVer2PfmCounters : ProcPfmCounters { PfmIssueCounter<"Zn2AGU", "ls_dispatch:ld_st_dispatch + ls_dispatch:ld_dispatch + ls_dispatch:store_dispatch">, PfmIssueCounter<"Zn2Divider", "div_op_count"> ]; + let ValidationCounters = [ + PfmValidationCounter + ]; } def : PfmCountersBinding<"znver2", ZnVer2PfmCounters>; @@ -288,6 +291,9 @@ def ZnVer3PfmCounters : ProcPfmCounters { PfmIssueCounter<"Zn3Store", "ls_dispatch:store_dispatch">, PfmIssueCounter<"Zn3Divider", "div_op_count"> ]; + let ValidationCounters = [ + PfmValidationCounter + ]; } def : PfmCountersBinding<"znver3", ZnVer3PfmCounters>; diff --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp index 23c80e5b98953..fe1eded63dc51 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/Target.cpp @@ -149,10 +149,15 @@ std::unique_ptr ExegesisTarget::createUopsBenchmarkRunner( static_assert(std::is_trivial_v, "We shouldn't have dynamic initialization here"); + const PfmCountersInfo PfmCountersInfo::Default = {nullptr, nullptr, nullptr, - 0u}; + 0u, nullptr, 0u}; const PfmCountersInfo PfmCountersInfo::Dummy = { - pfm::PerfEvent::DummyEventString, pfm::PerfEvent::DummyEventString, nullptr, + pfm::PerfEvent::DummyEventString, + pfm::PerfEvent::DummyEventString, + nullptr, + 0u, + nullptr, 0u}; const PfmCountersInfo &ExegesisTarget::getPfmCounters(StringRef CpuName) const { diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h index c37dd8b708216..9d3bb2b44af11 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.h +++ b/llvm/tools/llvm-exegesis/lib/Target.h @@ -39,6 +39,13 @@ extern cl::OptionCategory Options; extern cl::OptionCategory BenchmarkOptions; extern cl::OptionCategory AnalysisOptions; +enum ValidationEvent { + L1DCacheLoadMiss, + InstructionRetired, + DataTLBLoadMiss, + DataTLBStoreMiss +}; + struct PfmCountersInfo { // An optional name of a performance counter that can be used to measure // cycles. @@ -59,6 +66,9 @@ struct PfmCountersInfo { const IssueCounter *IssueCounters; unsigned NumIssueCounters; + const std::pair *ValidationEvents; + unsigned NumValidationEvents; + static const PfmCountersInfo Default; static const PfmCountersInfo Dummy; }; diff --git a/llvm/utils/TableGen/ExegesisEmitter.cpp b/llvm/utils/TableGen/ExegesisEmitter.cpp index 736f1220be14d..d48c7f3a480f2 100644 --- a/llvm/utils/TableGen/ExegesisEmitter.cpp +++ b/llvm/utils/TableGen/ExegesisEmitter.cpp @@ -81,6 +81,11 @@ collectPfmCounters(const RecordKeeper &Records) { "duplicate ResourceName " + ResourceName); AddPfmCounterName(IssueCounter); } + + for (const Record *ValidationCounter : + Def->getValueAsListOfDefs("ValidationCounters")) + AddPfmCounterName(ValidationCounter); + AddPfmCounterName(Def->getValueAsDef("CycleCounter")); AddPfmCounterName(Def->getValueAsDef("UopsCounter")); } @@ -100,6 +105,17 @@ ExegesisEmitter::ExegesisEmitter(RecordKeeper &RK) Target = std::string(Targets[0]->getName()); } +struct ValidationCounterInfo { + int64_t EventNumber; + StringRef EventName; + unsigned PfmCounterID; +}; + +bool EventNumberLess(const ValidationCounterInfo &LHS, + const ValidationCounterInfo &RHS) { + return LHS.EventNumber < RHS.EventNumber; +} + void ExegesisEmitter::emitPfmCountersInfo(const Record &Def, unsigned &IssueCountersTableOffset, raw_ostream &OS) const { @@ -109,6 +125,31 @@ void ExegesisEmitter::emitPfmCountersInfo(const Record &Def, Def.getValueAsDef("UopsCounter")->getValueAsString("Counter"); const size_t NumIssueCounters = Def.getValueAsListOfDefs("IssueCounters").size(); + const size_t NumValidationCounters = + Def.getValueAsListOfDefs("ValidationCounters").size(); + + // Emit Validation Counters Array + if (NumValidationCounters != 0) { + std::vector ValidationCounters; + ValidationCounters.reserve(NumValidationCounters); + for (const Record *ValidationCounter : + Def.getValueAsListOfDefs("ValidationCounters")) { + ValidationCounters.push_back( + {ValidationCounter->getValueAsDef("EventType") + ->getValueAsInt("EventNumber"), + ValidationCounter->getValueAsDef("EventType")->getName(), + getPfmCounterId(ValidationCounter->getValueAsString("Counter"))}); + } + std::sort(ValidationCounters.begin(), ValidationCounters.end(), + EventNumberLess); + OS << "\nstatic const std::pair " << Target + << Def.getName() << "ValidationCounters[] = {\n"; + for (const ValidationCounterInfo &VCI : ValidationCounters) { + OS << " { " << VCI.EventName << ", " << Target << "PfmCounterNames[" + << VCI.PfmCounterID << "]},\n"; + } + OS << "};\n"; + } OS << "\nstatic const PfmCountersInfo " << Target << Def.getName() << " = {\n"; @@ -129,10 +170,17 @@ void ExegesisEmitter::emitPfmCountersInfo(const Record &Def, // Issue Counters if (NumIssueCounters == 0) - OS << " nullptr, // No issue counters.\n 0\n"; + OS << " nullptr, 0, // No issue counters\n"; else OS << " " << Target << "PfmIssueCounters + " << IssueCountersTableOffset - << ", " << NumIssueCounters << " // Issue counters.\n"; + << ", " << NumIssueCounters << ", // Issue counters.\n"; + + // Validation Counters + if (NumValidationCounters == 0) + OS << " nullptr, 0 // No validation counters.\n"; + else + OS << " " << Target << Def.getName() << "ValidationCounters, " + << NumValidationCounters << " // Validation counters.\n"; OS << "};\n"; IssueCountersTableOffset += NumIssueCounters;