aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
diff options
context:
space:
mode:
authorAiden Grossman <agrossman154@yahoo.com>2024-01-19 02:00:33 -0800
committerGitHub <noreply@github.com>2024-01-19 02:00:33 -0800
commitf670112a591c83498e348f3ff2f73f02baf8e303 (patch)
treea68f2fa6c8ab80ddd580c4df49f42c6cf9752ecf /llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
parent4619147911c2a955bb605618bc518b45da994a81 (diff)
downloadllvm-f670112a591c83498e348f3ff2f73f02baf8e303.zip
llvm-f670112a591c83498e348f3ff2f73f02baf8e303.tar.gz
llvm-f670112a591c83498e348f3ff2f73f02baf8e303.tar.bz2
[llvm-exegesis] Add support for validation counters (#76653)
This patch adds support for validation counters. Validation counters can be used to measure events that occur during snippet execution like cache misses to ensure that certain assumed invariants about the benchmark actually hold. Validation counters are setup within a perf event group, so are turned on and off at exactly the same time as the "group leader" counter that measures the desired value.
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp')
-rw-r--r--llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp37
1 files changed, 37 insertions, 0 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
index 02c4da1..60264ca 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
@@ -14,6 +14,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/bit.h"
#include "llvm/ObjectYAML/YAML.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
@@ -192,6 +193,41 @@ template <> struct SequenceElementTraits<exegesis::BenchmarkMeasure> {
static const bool flow = false;
};
+const char *validationEventToString(exegesis::ValidationEvent VE) {
+ switch (VE) {
+ case exegesis::ValidationEvent::InstructionRetired:
+ return "instructions-retired";
+ }
+}
+
+Expected<exegesis::ValidationEvent> stringToValidationEvent(StringRef Input) {
+ if (Input == "instructions-retired")
+ return exegesis::ValidationEvent::InstructionRetired;
+ else
+ return make_error<StringError>("Invalid validation event string",
+ errc::invalid_argument);
+}
+
+template <>
+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 = stringToValidationEvent(KeyStr);
+ if (!Key) {
+ Io.setError("Key is not a valid validation event");
+ return;
+ }
+ Io.mapRequired(KeyStr.str().c_str(), VI[*Key]);
+ }
+
+ static void output(IO &Io, std::map<exegesis::ValidationEvent, int64_t> &VI) {
+ for (auto &IndividualVI : VI) {
+ Io.mapRequired(validationEventToString(IndividualVI.first),
+ IndividualVI.second);
+ }
+ }
+};
+
// exegesis::Measure is rendererd as a flow instead of a list.
// e.g. { "key": "the key", "value": 0123 }
template <> struct MappingTraits<exegesis::BenchmarkMeasure> {
@@ -203,6 +239,7 @@ template <> struct MappingTraits<exegesis::BenchmarkMeasure> {
}
Io.mapRequired("value", Obj.PerInstructionValue);
Io.mapOptional("per_snippet_value", Obj.PerSnippetValue);
+ Io.mapOptional("validation_counters", Obj.ValidationCounters);
}
static const bool flow = true;
};