diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h --- a/llvm/tools/llvm-exegesis/lib/Target.h +++ b/llvm/tools/llvm-exegesis/lib/Target.h @@ -27,6 +27,7 @@ #include "llvm/IR/LegacyPassManager.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/Support/Error.h" namespace llvm { namespace exegesis { @@ -65,6 +66,10 @@ explicit ExegesisTarget(ArrayRef CpuPfmCounters) : CpuPfmCounters(CpuPfmCounters) {} + // Targets can use this to create target-specific perf counters. + virtual Expected> + createCounter(const char *CounterName, const LLVMState &State) const; + // Targets can use this to add target-specific passes in assembleToStream(); virtual void addTargetSpecificPasses(PassManagerBase &PM) const {} diff --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp --- a/llvm/tools/llvm-exegesis/lib/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/Target.cpp @@ -11,6 +11,8 @@ #include "ParallelSnippetGenerator.h" #include "SerialSnippetGenerator.h" #include "UopsBenchmarkRunner.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/Error.h" namespace llvm { namespace exegesis { @@ -27,6 +29,19 @@ return nullptr; } +Expected> +ExegesisTarget::createCounter(const char *CounterName, + const LLVMState &) const { + pfm::PerfEvent Event(CounterName); + if (!Event.valid()) + return llvm::make_error( + llvm::Twine("Unable to create counter with name '") + .concat(CounterName) + .concat("'")); + + return std::make_unique(std::move(Event)); +} + void ExegesisTarget::registerTarget(ExegesisTarget *Target) { if (FirstTarget == nullptr) { FirstTarget = Target;