[llvm] [llvm-exegesis][NFC] Refactor all `ValidationEvent` info in a single … (PR #82256)

via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 19 07:24:42 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-tools-llvm-exegesis

Author: Clement Courbet (legrosbuffle)

<details>
<summary>Changes</summary>

…table.

All data is derived from a single table rather than being spread out over an enum, a table and the main entry point.

This is intended as a replacement for #<!-- -->82092.

---
Full diff: https://github.com/llvm/llvm-project/pull/82256.diff


9 Files Affected:

- (modified) llvm/include/llvm/Target/TargetPfmCounters.td (+1) 
- (modified) llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp (+3-46) 
- (modified) llvm/tools/llvm-exegesis/lib/BenchmarkResult.h (+1-14) 
- (modified) llvm/tools/llvm-exegesis/lib/CMakeLists.txt (+1) 
- (modified) llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp (+2-2) 
- (modified) llvm/tools/llvm-exegesis/lib/Target.h (+1) 
- (added) llvm/tools/llvm-exegesis/lib/ValidationEvent.cpp (+53) 
- (added) llvm/tools/llvm-exegesis/lib/ValidationEvent.h (+60) 
- (modified) llvm/tools/llvm-exegesis/llvm-exegesis.cpp (+2-18) 


``````````diff
diff --git a/llvm/include/llvm/Target/TargetPfmCounters.td b/llvm/include/llvm/Target/TargetPfmCounters.td
index 8c4d5f50c63a24..cfe432a992b71f 100644
--- a/llvm/include/llvm/Target/TargetPfmCounters.td
+++ b/llvm/include/llvm/Target/TargetPfmCounters.td
@@ -35,6 +35,7 @@ class ValidationEvent <int event_number> {
   int EventNumber = event_number;
 }
 
+// TableGen names for events defined in `llvm::exegesis::ValidationEvent`.
 def InstructionRetired  : ValidationEvent<0>;
 def L1DCacheLoadMiss : ValidationEvent<1>;
 def L1DCacheStoreMiss : ValidationEvent<2>;
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
index 189add6464173f..f84ebd2a4e68ef 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
@@ -9,6 +9,7 @@
 #include "BenchmarkResult.h"
 #include "BenchmarkRunner.h"
 #include "Error.h"
+#include "ValidationEvent.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/StringRef.h"
@@ -198,7 +199,7 @@ struct CustomMappingTraits<std::map<exegesis::ValidationEvent, int64_t>> {
   static void inputOne(IO &Io, StringRef KeyStr,
                        std::map<exegesis::ValidationEvent, int64_t> &VI) {
     Expected<exegesis::ValidationEvent> Key =
-        exegesis::stringToValidationEvent(KeyStr);
+        exegesis::getValidationEventByName(KeyStr);
     if (!Key) {
       Io.setError("Key is not a valid validation event");
       return;
@@ -208,7 +209,7 @@ struct CustomMappingTraits<std::map<exegesis::ValidationEvent, int64_t>> {
 
   static void output(IO &Io, std::map<exegesis::ValidationEvent, int64_t> &VI) {
     for (auto &IndividualVI : VI) {
-      Io.mapRequired(exegesis::validationEventToString(IndividualVI.first),
+      Io.mapRequired(exegesis::getValidationEventName(IndividualVI.first),
                      IndividualVI.second);
     }
   }
@@ -441,49 +442,5 @@ bool operator==(const BenchmarkMeasure &A, const BenchmarkMeasure &B) {
          std::tie(B.Key, B.PerInstructionValue, B.PerSnippetValue);
 }
 
-const char *validationEventToString(ValidationEvent VE) {
-  switch (VE) {
-  case exegesis::ValidationEvent::InstructionRetired:
-    return "instructions-retired";
-  case exegesis::ValidationEvent::L1DCacheLoadMiss:
-    return "l1d-cache-load-misses";
-  case exegesis::ValidationEvent::L1DCacheStoreMiss:
-    return "l1d-cache-store-misses";
-  case exegesis::ValidationEvent::L1ICacheLoadMiss:
-    return "l1i-cache-load-misses";
-  case exegesis::ValidationEvent::DataTLBLoadMiss:
-    return "data-tlb-load-misses";
-  case exegesis::ValidationEvent::DataTLBStoreMiss:
-    return "data-tlb-store-misses";
-  case exegesis::ValidationEvent::InstructionTLBLoadMiss:
-    return "instruction-tlb-load-misses";
-  case exegesis::ValidationEvent::BranchPredictionMiss:
-    return "branch-prediction-misses";
-  }
-  llvm_unreachable("Unhandled exegesis::ValidationEvent enum");
-}
-
-Expected<ValidationEvent> stringToValidationEvent(StringRef Input) {
-  if (Input == "instructions-retired")
-    return exegesis::ValidationEvent::InstructionRetired;
-  else if (Input == "l1d-cache-load-misses")
-    return exegesis::ValidationEvent::L1DCacheLoadMiss;
-  else if (Input == "l1d-cache-store-misses")
-    return exegesis::ValidationEvent::L1DCacheStoreMiss;
-  else if (Input == "l1i-cache-load-misses")
-    return exegesis::ValidationEvent::L1ICacheLoadMiss;
-  else if (Input == "data-tlb-load-misses")
-    return exegesis::ValidationEvent::DataTLBLoadMiss;
-  else if (Input == "data-tlb-store-misses")
-    return exegesis::ValidationEvent::DataTLBStoreMiss;
-  else if (Input == "instruction-tlb-load-misses")
-    return exegesis::ValidationEvent::InstructionTLBLoadMiss;
-  else if (Input == "branch-prediction-misses")
-    return exegesis::ValidationEvent::BranchPredictionMiss;
-  else
-    return make_error<StringError>("Invalid validation event string",
-                                   errc::invalid_argument);
-}
-
 } // namespace exegesis
 } // namespace llvm
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h
index 60115c51bba321..0aecaaeea4b2e7 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h
@@ -17,6 +17,7 @@
 
 #include "LlvmState.h"
 #include "RegisterValue.h"
+#include "ValidationEvent.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/MC/MCInstBuilder.h"
@@ -32,20 +33,6 @@ class Error;
 
 namespace exegesis {
 
-enum ValidationEvent {
-  InstructionRetired,
-  L1DCacheLoadMiss,
-  L1DCacheStoreMiss,
-  L1ICacheLoadMiss,
-  DataTLBLoadMiss,
-  DataTLBStoreMiss,
-  InstructionTLBLoadMiss,
-  BranchPredictionMiss
-};
-
-const char *validationEventToString(exegesis::ValidationEvent VE);
-Expected<ValidationEvent> stringToValidationEvent(StringRef Input);
-
 enum class BenchmarkPhaseSelectorE {
   PrepareSnippet,
   PrepareAndAssembleSnippet,
diff --git a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt
index 6ae441d31f07fe..414b49e5e021c2 100644
--- a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt
+++ b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt
@@ -73,6 +73,7 @@ add_llvm_library(LLVMExegesis
   SubprocessMemory.cpp
   Target.cpp
   UopsBenchmarkRunner.cpp
+  ValidationEvent.cpp
 
   LINK_LIBS ${libs}
 
diff --git a/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp
index a9917a29cce24d..de61fff6432944 100644
--- a/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp
@@ -107,8 +107,8 @@ Expected<std::vector<BenchmarkMeasure>> LatencyBenchmarkRunner::runMeasurements(
     }
 
     for (size_t I = 0; I < ValCounterValues.size(); ++I) {
-      LLVM_DEBUG(dbgs() << validationEventToString(ValidationCounters[I])
-                        << ": " << IterationValCounterValues[I] << "\n");
+      LLVM_DEBUG(dbgs() << getValidationEventName(ValidationCounters[I]) << ": "
+                        << IterationValCounterValues[I] << "\n");
       ValCounterValues[I] += IterationValCounterValues[I];
     }
   }
diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h
index 3d6169c9650213..7bbd946b03331f 100644
--- a/llvm/tools/llvm-exegesis/lib/Target.h
+++ b/llvm/tools/llvm-exegesis/lib/Target.h
@@ -22,6 +22,7 @@
 #include "LlvmState.h"
 #include "PerfHelper.h"
 #include "SnippetGenerator.h"
+#include "ValidationEvent.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/LegacyPassManager.h"
diff --git a/llvm/tools/llvm-exegesis/lib/ValidationEvent.cpp b/llvm/tools/llvm-exegesis/lib/ValidationEvent.cpp
new file mode 100644
index 00000000000000..a212e1c4fdf7c8
--- /dev/null
+++ b/llvm/tools/llvm-exegesis/lib/ValidationEvent.cpp
@@ -0,0 +1,53 @@
+
+#include "ValidationEvent.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace exegesis {
+
+namespace {
+
+struct ValidationEventInfo {
+  const char *const Name;
+  const char *const Description;
+};
+
+// Information about validation events, indexed by `ValidationEvent` enum
+// value.
+static constexpr ValidationEventInfo ValidationEventInfos[NumValidationEvents] =
+    {
+        {"instructions-retired", "Count retired instructions"},
+        {"l1d-cache-load-misses", "Count L1D load cache misses"},
+        {"l1d-cache-store-misses", "Count L1D store cache misses"},
+        {"l1i-cache-load-misses", "Count L1I load cache misses"},
+        {"data-tlb-load-misses", "Count DTLB load misses"},
+        {"data-tlb-store-misses", "Count DTLB store misses"},
+        {"instruction-tlb-load-misses", "Count ITLB load misses"},
+        {"branch-prediction-misses", "Branch prediction misses"},
+};
+
+} // namespace
+
+const char *getValidationEventName(ValidationEvent VE) {
+  return ValidationEventInfos[VE].Name;
+}
+const char *getValidationEventDescription(ValidationEvent VE) {
+  return ValidationEventInfos[VE].Description;
+}
+
+Expected<ValidationEvent> getValidationEventByName(StringRef Name) {
+  int VE = 0;
+  for (const ValidationEventInfo &Info : ValidationEventInfos) {
+    if (Name == Info.Name)
+      return static_cast<ValidationEvent>(VE);
+    ++VE;
+  }
+
+  return make_error<StringError>("Invalid validation event string",
+                                 errc::invalid_argument);
+}
+
+} // namespace exegesis
+} // namespace llvm
diff --git a/llvm/tools/llvm-exegesis/lib/ValidationEvent.h b/llvm/tools/llvm-exegesis/lib/ValidationEvent.h
new file mode 100644
index 00000000000000..8a9f3af57dca97
--- /dev/null
+++ b/llvm/tools/llvm-exegesis/lib/ValidationEvent.h
@@ -0,0 +1,60 @@
+//===-- ValidationEvent.h ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Definitions and utilities for Validation Events.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_EXEGESIS_VALIDATIONEVENT_H
+#define LLVM_TOOLS_LLVM_EXEGESIS_VALIDATIONEVENT_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+
+namespace exegesis {
+
+// The main list of supported validation events. The mapping between validation
+// events and pfm counters is defined in TableDef files for each target.
+enum ValidationEvent {
+  InstructionRetired,
+  L1DCacheLoadMiss,
+  L1DCacheStoreMiss,
+  L1ICacheLoadMiss,
+  DataTLBLoadMiss,
+  DataTLBStoreMiss,
+  InstructionTLBLoadMiss,
+  BranchPredictionMiss,
+  // Number of events.
+  NumValidationEvents,
+};
+
+// Returns the name/description of the given event.
+const char *getValidationEventName(ValidationEvent VE);
+const char *getValidationEventDescription(ValidationEvent VE);
+
+// Returns the ValidationEvent with the given name.
+Expected<ValidationEvent> getValidationEventByName(StringRef Name);
+
+// Command-line options for validation events.
+struct ValidationEventOptions {
+  template <class Opt> void apply(Opt &O) const {
+    for (int I = 0; I < NumValidationEvents; ++I) {
+      const auto VE = static_cast<ValidationEvent>(I);
+      O.getParser().addLiteralOption(getValidationEventName(VE), VE,
+                                     getValidationEventDescription(VE));
+    }
+  }
+};
+
+} // namespace exegesis
+} // namespace llvm
+
+#endif
diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
index ac279029e6b004..66387bdec5a5a6 100644
--- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
+++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
@@ -25,6 +25,7 @@
 #include "lib/SnippetRepetitor.h"
 #include "lib/Target.h"
 #include "lib/TargetSelect.h"
+#include "lib/ValidationEvent.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/MC/MCInstBuilder.h"
@@ -278,24 +279,7 @@ static cl::list<ValidationEvent> ValidationCounters(
     cl::desc(
         "The name of a validation counter to run concurrently with the main "
         "counter to validate benchmarking assumptions"),
-    cl::CommaSeparated, cl::cat(BenchmarkOptions),
-    cl::values(
-        clEnumValN(ValidationEvent::InstructionRetired, "instructions-retired",
-                   "Count retired instructions"),
-        clEnumValN(ValidationEvent::L1DCacheLoadMiss, "l1d-cache-load-misses",
-                   "Count L1D load cache misses"),
-        clEnumValN(ValidationEvent::L1DCacheStoreMiss, "l1d-cache-store-misses",
-                   "Count L1D store cache misses"),
-        clEnumValN(ValidationEvent::L1ICacheLoadMiss, "l1i-cache-load-misses",
-                   "Count L1I load cache misses"),
-        clEnumValN(ValidationEvent::DataTLBLoadMiss, "data-tlb-load-misses",
-                   "Count DTLB load misses"),
-        clEnumValN(ValidationEvent::DataTLBStoreMiss, "data-tlb-store-misses",
-                   "Count DTLB store misses"),
-        clEnumValN(ValidationEvent::InstructionTLBLoadMiss,
-                   "instruction-tlb-load-misses", "Count ITLB load misses"),
-        clEnumValN(ValidationEvent::BranchPredictionMiss,
-                   "branch-prediction-misses", "Branch prediction misses")));
+    cl::CommaSeparated, cl::cat(BenchmarkOptions), ValidationEventOptions());
 
 static ExitOnError ExitOnErr("llvm-exegesis error: ");
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/82256


More information about the llvm-commits mailing list