diff options
author | Clement Courbet <courbet@google.com> | 2018-05-15 12:08:00 +0000 |
---|---|---|
committer | Clement Courbet <courbet@google.com> | 2018-05-15 12:08:00 +0000 |
commit | 37f0ca0328aa2571a05d530f35f5e2ef7cbb9498 (patch) | |
tree | 837371dd293b2c6d4284affd89981ccd3468aaa3 /llvm/tools/llvm-exegesis/llvm-exegesis.cpp | |
parent | 877d15b396494fae90a7808939aab7fd5ceebfb1 (diff) | |
download | bcm5719-llvm-37f0ca0328aa2571a05d530f35f5e2ef7cbb9498.tar.gz bcm5719-llvm-37f0ca0328aa2571a05d530f35f5e2ef7cbb9498.zip |
[llvm-exegesis] Add an analysis mode.
Summary:
The analysis mode gives the user a clustered view of the measurement results.
Next steps are (requires the split ok AsmTemplate.Name into {mnemonic, mode}):
- Show the sched class.
- Highlight any inconsistencies with the checked-in data.
Reviewers: gchatelet
Subscribers: mgorny, llvm-commits, tschuett
Differential Revision: https://reviews.llvm.org/D46865
llvm-svn: 332344
Diffstat (limited to 'llvm/tools/llvm-exegesis/llvm-exegesis.cpp')
-rw-r--r-- | llvm/tools/llvm-exegesis/llvm-exegesis.cpp | 85 |
1 files changed, 67 insertions, 18 deletions
diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp index 77683572da6..fff18776eec 100644 --- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp +++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp @@ -12,8 +12,10 @@ /// //===----------------------------------------------------------------------===// +#include "lib/Analysis.h" #include "lib/BenchmarkResult.h" #include "lib/BenchmarkRunner.h" +#include "lib/Clustering.h" #include "lib/Latency.h" #include "lib/LlvmState.h" #include "lib/PerfHelper.h" @@ -23,8 +25,11 @@ #include "llvm/ADT/Twine.h" #include "llvm/MC/MCInstBuilder.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Format.h" #include "llvm/Support/Path.h" +#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include <algorithm> #include <random> @@ -39,26 +44,41 @@ static llvm::cl::opt<std::string> OpcodeName("opcode-name", llvm::cl::desc("opcode to measure, by name"), llvm::cl::init("")); -enum class BenchmarkModeE { Latency, Uops }; -static llvm::cl::opt<BenchmarkModeE> - BenchmarkMode("benchmark-mode", llvm::cl::desc("the benchmark mode to run"), - llvm::cl::values(clEnumValN(BenchmarkModeE::Latency, - "latency", "Instruction Latency"), - clEnumValN(BenchmarkModeE::Uops, "uops", - "Uop Decomposition"))); +static llvm::cl::opt<std::string> + BenchmarkFile("benchmarks-file", llvm::cl::desc(""), llvm::cl::init("-")); + +enum class BenchmarkModeE { Latency, Uops, Analysis }; +static llvm::cl::opt<BenchmarkModeE> BenchmarkMode( + "benchmark-mode", llvm::cl::desc("the benchmark mode to run"), + llvm::cl::values( + clEnumValN(BenchmarkModeE::Latency, "latency", "Instruction Latency"), + clEnumValN(BenchmarkModeE::Uops, "uops", "Uop Decomposition"), + clEnumValN(BenchmarkModeE::Analysis, "analysis", "Analysis"))); static llvm::cl::opt<unsigned> NumRepetitions("num-repetitions", llvm::cl::desc("number of time to repeat the asm snippet"), llvm::cl::init(10000)); +static llvm::cl::opt<unsigned> AnalysisNumPoints( + "analysis-numpoints", + llvm::cl::desc("minimum number of points in an analysis cluster"), + llvm::cl::init(3)); + +static llvm::cl::opt<float> + AnalysisEpsilon("analysis-epsilon", + llvm::cl::desc("dbscan epsilon for analysis clustering"), + llvm::cl::init(0.1)); + namespace exegesis { -void main() { - if (OpcodeName.empty() == (OpcodeIndex == 0)) { +void benchmarkMain() { + if (exegesis::pfm::pfmInitialize()) + llvm::report_fatal_error("cannot initialize libpfm"); + + if (OpcodeName.empty() == (OpcodeIndex == 0)) llvm::report_fatal_error( "please provide one and only one of 'opcode-index' or 'opcode-name'"); - } llvm::InitializeNativeTarget(); llvm::InitializeNativeTargetAsmPrinter(); @@ -94,10 +114,42 @@ void main() { case BenchmarkModeE::Uops: Runner = llvm::make_unique<UopsBenchmarkRunner>(); break; + case BenchmarkModeE::Analysis: + llvm_unreachable("not a benchmark"); } Runner->run(State, Opcode, NumRepetitions > 0 ? NumRepetitions : 1, Filter) - .writeYamlOrDie("-"); + .writeYamlOrDie(BenchmarkFile); + exegesis::pfm::pfmTerminate(); +} + +void analysisMain() { + // Read benchmarks. + const std::vector<InstructionBenchmark> Points = + InstructionBenchmark::readYamlsOrDie(BenchmarkFile); + llvm::outs() << "Parsed " << Points.size() << " benchmark points\n"; + if (Points.empty()) { + llvm::errs() << "no benchmarks to analyze\n"; + return; + } + // FIXME: Check that all points have the same triple/cpu. + // FIXME: Merge points from several runs (latency and uops). + + llvm::InitializeAllTargets(); + std::string Error; + const auto *TheTarget = + llvm::TargetRegistry::lookupTarget(Points[0].LLVMTriple, Error); + if (!TheTarget) { + llvm::errs() << "unknown target '" << Points[0].LLVMTriple << "'\n"; + return; + } + std::unique_ptr<llvm::MCSubtargetInfo> STI(TheTarget->createMCSubtargetInfo( + Points[0].LLVMTriple, Points[0].CpuName, "")); + + const auto Clustering = llvm::cantFail(InstructionBenchmarkClustering::create( + Points, AnalysisNumPoints, AnalysisEpsilon)); + if (auto Err = printAnalysisClusters(Clustering, *STI, llvm::outs())) + llvm::report_fatal_error(std::move(Err)); } } // namespace exegesis @@ -105,13 +157,10 @@ void main() { int main(int Argc, char **Argv) { llvm::cl::ParseCommandLineOptions(Argc, Argv, ""); - if (exegesis::pfm::pfmInitialize()) { - llvm::errs() << "cannot initialize libpfm\n"; - return EXIT_FAILURE; + if (BenchmarkMode == BenchmarkModeE::Analysis) { + exegesis::analysisMain(); + } else { + exegesis::benchmarkMain(); } - - exegesis::main(); - - exegesis::pfm::pfmTerminate(); return EXIT_SUCCESS; } |