From 0196a8780f2d3a378f0fd3b86a6e6b6590ca02de Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Sat, 30 Dec 2023 15:37:56 -0800 Subject: [PATCH 1/7] [llvm-exegesis] Remove unused Counter::read method This method was simply a wrapper around readOrError. All users within the llvm-exegesis code base should have been processing an actual error rather than using the wrapper. This patch removes the wrapper and rewrites the users (just 1) to use the readOrError method. --- llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp | 6 +++++- llvm/tools/llvm-exegesis/lib/PerfHelper.cpp | 13 ------------- llvm/tools/llvm-exegesis/lib/PerfHelper.h | 3 --- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp index 1ee59a86ebbdc..c57fce970b213 100644 --- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp +++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp @@ -356,7 +356,11 @@ class SubProcessFunctionExecutorImpl if (ChildExitCode == 0) { // The child exited succesfully, read counter values and return // success - CounterValues[0] = Counter->read(); + auto CounterValueOrErr = Counter->readOrError(); + if (!CounterValueOrErr) + return CounterValueOrErr.takeError(); + CounterValues.swap(*CounterValueOrErr); + return Error::success(); } // The child exited, but not successfully diff --git a/llvm/tools/llvm-exegesis/lib/PerfHelper.cpp b/llvm/tools/llvm-exegesis/lib/PerfHelper.cpp index 3ff1745e9e062..314de1ec32366 100644 --- a/llvm/tools/llvm-exegesis/lib/PerfHelper.cpp +++ b/llvm/tools/llvm-exegesis/lib/PerfHelper.cpp @@ -148,17 +148,6 @@ void Counter::stop() { ioctl(FileDescriptor, PERF_EVENT_IOC_DISABLE, 0); } -int64_t Counter::read() const { - auto ValueOrError = readOrError(); - if (ValueOrError) { - if (!ValueOrError.get().empty()) - return ValueOrError.get()[0]; - errs() << "Counter has no reading\n"; - } else - errs() << ValueOrError.takeError() << "\n"; - return -1; -} - llvm::Expected> Counter::readOrError(StringRef /*unused*/) const { int64_t Count = 0; @@ -187,8 +176,6 @@ void Counter::start() {} void Counter::stop() {} -int64_t Counter::read() const { return 42; } - llvm::Expected> Counter::readOrError(StringRef /*unused*/) const { if (IsDummyEvent) { diff --git a/llvm/tools/llvm-exegesis/lib/PerfHelper.h b/llvm/tools/llvm-exegesis/lib/PerfHelper.h index a50974f0a67be..894aac1f197ed 100644 --- a/llvm/tools/llvm-exegesis/lib/PerfHelper.h +++ b/llvm/tools/llvm-exegesis/lib/PerfHelper.h @@ -95,9 +95,6 @@ class Counter { /// Stops the measurement of the event. void stop(); - /// Returns the current value of the counter or -1 if it cannot be read. - int64_t read() const; - /// Returns the current value of the counter or error if it cannot be read. /// FunctionBytes: The benchmark function being executed. /// This is used to filter out the measurements to ensure they are only From 75261b9626878b92fa4bde2b4801815251238748 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Sat, 30 Dec 2023 17:03:59 -0800 Subject: [PATCH 2/7] [llvm-exegesis] Add tablegen support for validation counters --- llvm/include/llvm/Target/TargetPfmCounters.td | 19 +++++++++++++ llvm/lib/Target/X86/X86PfmCounters.td | 6 ++++ llvm/tools/llvm-exegesis/lib/Target.cpp | 13 +++++---- llvm/tools/llvm-exegesis/lib/Target.h | 11 ++++++++ llvm/utils/TableGen/ExegesisEmitter.cpp | 28 +++++++++++++++++-- 5 files changed, 69 insertions(+), 8 deletions(-) diff --git a/llvm/include/llvm/Target/TargetPfmCounters.td b/llvm/include/llvm/Target/TargetPfmCounters.td index b00f3e19c35f9..72f6b39f4878f 100644 --- a/llvm/include/llvm/Target/TargetPfmCounters.td +++ b/llvm/include/llvm/Target/TargetPfmCounters.td @@ -28,6 +28,22 @@ class PfmIssueCounter string ResourceName = resource_name; } +class ValidationEvent { + int EventNumber = event_number; +} + +def L1DCacheLoadMiss : ValidationEvent<0>; +def InstructionRetired : ValidationEvent<1>; +def DataTLBLoadMiss : ValidationEvent<2>; +def DataTLBStoreMiss : ValidationEvent<3>; + +// Validation counters can be tied to a specific event +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 +54,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..20b4afb9b8f67 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/Target.cpp @@ -147,13 +147,14 @@ std::unique_ptr ExegesisTarget::createUopsBenchmarkRunner( ExecutionMode); } -static_assert(std::is_trivial_v, - "We shouldn't have dynamic initialization here"); -const PfmCountersInfo PfmCountersInfo::Default = {nullptr, nullptr, nullptr, - 0u}; +const PfmCountersInfo PfmCountersInfo::Default = { + nullptr, nullptr, nullptr, 0u, {}}; const PfmCountersInfo PfmCountersInfo::Dummy = { - pfm::PerfEvent::DummyEventString, pfm::PerfEvent::DummyEventString, nullptr, - 0u}; + pfm::PerfEvent::DummyEventString, + pfm::PerfEvent::DummyEventString, + nullptr, + 0u, + {}}; const PfmCountersInfo &ExegesisTarget::getPfmCounters(StringRef CpuName) const { assert(llvm::is_sorted( diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h index c37dd8b708216..3956bc983181f 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.h +++ b/llvm/tools/llvm-exegesis/lib/Target.h @@ -32,6 +32,8 @@ #include "llvm/TargetParser/SubtargetFeature.h" #include "llvm/TargetParser/Triple.h" +#include + namespace llvm { namespace exegesis { @@ -39,6 +41,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 +68,8 @@ struct PfmCountersInfo { const IssueCounter *IssueCounters; unsigned NumIssueCounters; + std::unordered_map ValidationCounters; + static const PfmCountersInfo Default; static const PfmCountersInfo Dummy; }; diff --git a/llvm/utils/TableGen/ExegesisEmitter.cpp b/llvm/utils/TableGen/ExegesisEmitter.cpp index 736f1220be14d..247ed83f25ea6 100644 --- a/llvm/utils/TableGen/ExegesisEmitter.cpp +++ b/llvm/utils/TableGen/ExegesisEmitter.cpp @@ -22,6 +22,8 @@ #include #include +#include + using namespace llvm; #define DEBUG_TYPE "exegesis-emitter" @@ -81,6 +83,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")); } @@ -109,6 +116,8 @@ 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(); OS << "\nstatic const PfmCountersInfo " << Target << Def.getName() << " = {\n"; @@ -129,10 +138,25 @@ 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 << " {} // No validation counters.\n"; + else { + OS << " {\n"; + for (const Record *ValidationCounter : + Def.getValueAsListOfDefs("ValidationCounters")) { + OS << " { " << ValidationCounter->getValueAsDef("EventType")->getName() + << ", " << Target << "PfmCounterNames[" + << getPfmCounterId(ValidationCounter->getValueAsString("Counter")) + << "]}\n"; + } + OS << " } // Validation counters.\n"; + } OS << "};\n"; IssueCountersTableOffset += NumIssueCounters; From 832d75cc4e8dabc4a5eeccf45ca51dee2d92ab15 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Tue, 2 Jan 2024 22:28:26 -0800 Subject: [PATCH 3/7] Add comma to end of validation counters to support multiple --- llvm/utils/TableGen/ExegesisEmitter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/utils/TableGen/ExegesisEmitter.cpp b/llvm/utils/TableGen/ExegesisEmitter.cpp index 247ed83f25ea6..6c1f7af5fd572 100644 --- a/llvm/utils/TableGen/ExegesisEmitter.cpp +++ b/llvm/utils/TableGen/ExegesisEmitter.cpp @@ -153,7 +153,7 @@ void ExegesisEmitter::emitPfmCountersInfo(const Record &Def, OS << " { " << ValidationCounter->getValueAsDef("EventType")->getName() << ", " << Target << "PfmCounterNames[" << getPfmCounterId(ValidationCounter->getValueAsString("Counter")) - << "]}\n"; + << "]},\n"; } OS << " } // Validation counters.\n"; } From 1841c85d87df01fa2686d406265bc81b766f85a8 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Fri, 5 Jan 2024 18:53:46 -0800 Subject: [PATCH 4/7] Switch to using static array --- llvm/tools/llvm-exegesis/lib/Target.cpp | 10 +++-- llvm/tools/llvm-exegesis/lib/Target.h | 5 +-- llvm/utils/TableGen/ExegesisEmitter.cpp | 52 ++++++++++++++++++------- 3 files changed, 47 insertions(+), 20 deletions(-) diff --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp index 20b4afb9b8f67..fe1eded63dc51 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/Target.cpp @@ -147,14 +147,18 @@ std::unique_ptr ExegesisTarget::createUopsBenchmarkRunner( ExecutionMode); } -const PfmCountersInfo PfmCountersInfo::Default = { - nullptr, nullptr, nullptr, 0u, {}}; +static_assert(std::is_trivial_v, + "We shouldn't have dynamic initialization here"); + +const PfmCountersInfo PfmCountersInfo::Default = {nullptr, nullptr, nullptr, + 0u, nullptr, 0u}; const PfmCountersInfo PfmCountersInfo::Dummy = { pfm::PerfEvent::DummyEventString, pfm::PerfEvent::DummyEventString, nullptr, 0u, - {}}; + nullptr, + 0u}; const PfmCountersInfo &ExegesisTarget::getPfmCounters(StringRef CpuName) const { assert(llvm::is_sorted( diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h index 3956bc983181f..8da748f51dc95 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.h +++ b/llvm/tools/llvm-exegesis/lib/Target.h @@ -32,8 +32,6 @@ #include "llvm/TargetParser/SubtargetFeature.h" #include "llvm/TargetParser/Triple.h" -#include - namespace llvm { namespace exegesis { @@ -68,7 +66,8 @@ struct PfmCountersInfo { const IssueCounter *IssueCounters; unsigned NumIssueCounters; - std::unordered_map ValidationCounters; + const std::pair *ValidationEvents; + unsigned NumValidationCounters; static const PfmCountersInfo Default; static const PfmCountersInfo Dummy; diff --git a/llvm/utils/TableGen/ExegesisEmitter.cpp b/llvm/utils/TableGen/ExegesisEmitter.cpp index 6c1f7af5fd572..111aa449ae4f3 100644 --- a/llvm/utils/TableGen/ExegesisEmitter.cpp +++ b/llvm/utils/TableGen/ExegesisEmitter.cpp @@ -22,8 +22,6 @@ #include #include -#include - using namespace llvm; #define DEBUG_TYPE "exegesis-emitter" @@ -107,6 +105,17 @@ ExegesisEmitter::ExegesisEmitter(RecordKeeper &RK) Target = std::string(Targets[0]->getName()); } +struct ValidationCounterInfo { + int64_t EventNumber; + StringRef EventName; + unsigned PfmCounterID; +}; + +bool CompareValidationCounterInfo(ValidationCounterInfo &LHS, + ValidationCounterInfo &RHS) { + return LHS.EventNumber < RHS.EventNumber; +} + void ExegesisEmitter::emitPfmCountersInfo(const Record &Def, unsigned &IssueCountersTableOffset, raw_ostream &OS) const { @@ -119,6 +128,29 @@ void ExegesisEmitter::emitPfmCountersInfo(const Record &Def, 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(), + CompareValidationCounterInfo); + 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"; @@ -145,18 +177,10 @@ void ExegesisEmitter::emitPfmCountersInfo(const Record &Def, // Validation Counters if (NumValidationCounters == 0) - OS << " {} // No validation counters.\n"; - else { - OS << " {\n"; - for (const Record *ValidationCounter : - Def.getValueAsListOfDefs("ValidationCounters")) { - OS << " { " << ValidationCounter->getValueAsDef("EventType")->getName() - << ", " << Target << "PfmCounterNames[" - << getPfmCounterId(ValidationCounter->getValueAsString("Counter")) - << "]},\n"; - } - OS << " } // Validation counters.\n"; - } + OS << " nullptr, 0 // No validation counters.\n"; + else + OS << " " << Target << Def.getName() << "ValidationCounters, " + << NumValidationCounters << " // Validation counters.\n"; OS << "};\n"; IssueCountersTableOffset += NumIssueCounters; From 6d5262636250aa0e2f1c889ee49f609efde9ea06 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Fri, 5 Jan 2024 20:43:08 -0800 Subject: [PATCH 5/7] Add better docs --- llvm/include/llvm/Target/TargetPfmCounters.td | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/Target/TargetPfmCounters.td b/llvm/include/llvm/Target/TargetPfmCounters.td index 72f6b39f4878f..edd3505409eba 100644 --- a/llvm/include/llvm/Target/TargetPfmCounters.td +++ b/llvm/include/llvm/Target/TargetPfmCounters.td @@ -28,6 +28,9 @@ class PfmIssueCounter string ResourceName = resource_name; } +// Definition of a validation event. A validation event represents a specific +// event that can be meaasured using performance counters that is interesting +// in regard to the snippet state. class ValidationEvent { int EventNumber = event_number; } @@ -37,7 +40,9 @@ def InstructionRetired : ValidationEvent<1>; def DataTLBLoadMiss : ValidationEvent<2>; def DataTLBStoreMiss : ValidationEvent<3>; -// Validation counters can be tied to a specific event +// 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. From f1f92a9cb4c53f19824dfa5fbd936a248d83c105 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Wed, 10 Jan 2024 14:42:45 -0800 Subject: [PATCH 6/7] Address reviewer feedback --- llvm/include/llvm/Target/TargetPfmCounters.td | 2 +- llvm/utils/TableGen/ExegesisEmitter.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/Target/TargetPfmCounters.td b/llvm/include/llvm/Target/TargetPfmCounters.td index edd3505409eba..49b2d1fc25651 100644 --- a/llvm/include/llvm/Target/TargetPfmCounters.td +++ b/llvm/include/llvm/Target/TargetPfmCounters.td @@ -29,7 +29,7 @@ class PfmIssueCounter } // Definition of a validation event. A validation event represents a specific -// event that can be meaasured using performance counters that is interesting +// event that can be measured using performance counters that is interesting // in regard to the snippet state. class ValidationEvent { int EventNumber = event_number; diff --git a/llvm/utils/TableGen/ExegesisEmitter.cpp b/llvm/utils/TableGen/ExegesisEmitter.cpp index 111aa449ae4f3..d48c7f3a480f2 100644 --- a/llvm/utils/TableGen/ExegesisEmitter.cpp +++ b/llvm/utils/TableGen/ExegesisEmitter.cpp @@ -111,8 +111,8 @@ struct ValidationCounterInfo { unsigned PfmCounterID; }; -bool CompareValidationCounterInfo(ValidationCounterInfo &LHS, - ValidationCounterInfo &RHS) { +bool EventNumberLess(const ValidationCounterInfo &LHS, + const ValidationCounterInfo &RHS) { return LHS.EventNumber < RHS.EventNumber; } @@ -141,7 +141,7 @@ void ExegesisEmitter::emitPfmCountersInfo(const Record &Def, getPfmCounterId(ValidationCounter->getValueAsString("Counter"))}); } std::sort(ValidationCounters.begin(), ValidationCounters.end(), - CompareValidationCounterInfo); + EventNumberLess); OS << "\nstatic const std::pair " << Target << Def.getName() << "ValidationCounters[] = {\n"; for (const ValidationCounterInfo &VCI : ValidationCounters) { From b9a5dff3ad02b7aeaf9c934d3117f2a20a274297 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Wed, 10 Jan 2024 15:03:02 -0800 Subject: [PATCH 7/7] Fix variable name --- llvm/tools/llvm-exegesis/lib/Target.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h index 8da748f51dc95..9d3bb2b44af11 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.h +++ b/llvm/tools/llvm-exegesis/lib/Target.h @@ -67,7 +67,7 @@ struct PfmCountersInfo { unsigned NumIssueCounters; const std::pair *ValidationEvents; - unsigned NumValidationCounters; + unsigned NumValidationEvents; static const PfmCountersInfo Default; static const PfmCountersInfo Dummy;