diff options
author | Clement Courbet <courbet@google.com> | 2018-04-04 11:37:06 +0000 |
---|---|---|
committer | Clement Courbet <courbet@google.com> | 2018-04-04 11:37:06 +0000 |
commit | ac74acdefed9af2751d323bacef7ac47982957e8 (patch) | |
tree | 86fa1d51e6ad1bcf64c29d899c085e49f88ccf39 /llvm/tools/llvm-exegesis/llvm-exegesis.cpp | |
parent | d152d55ab25be21ec8e5a162fce74f3bf7f8ed5c (diff) | |
download | bcm5719-llvm-ac74acdefed9af2751d323bacef7ac47982957e8.tar.gz bcm5719-llvm-ac74acdefed9af2751d323bacef7ac47982957e8.zip |
Re-land r329156 "Add llvm-exegesis tool."
Fixed to depend on and initialize the native target instead of X86.
llvm-svn: 329169
Diffstat (limited to 'llvm/tools/llvm-exegesis/llvm-exegesis.cpp')
-rw-r--r-- | llvm/tools/llvm-exegesis/llvm-exegesis.cpp | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp new file mode 100644 index 00000000000..c9dfe840f4e --- /dev/null +++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp @@ -0,0 +1,114 @@ +//===-- llvm-exegesis.cpp ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Measures execution properties (latencies/uops) of an instruction. +/// +//===----------------------------------------------------------------------===// + +#include "lib/BenchmarkResult.h" +#include "lib/BenchmarkRunner.h" +#include "lib/Latency.h" +#include "lib/LlvmState.h" +#include "lib/PerfHelper.h" +#include "lib/Uops.h" +#include "lib/X86.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Twine.h" +#include "llvm/MC/MCInstBuilder.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/TargetSelect.h" +#include <algorithm> +#include <random> +#include <string> +#include <unordered_map> + +static llvm::cl::opt<unsigned> + OpcodeIndex("opcode-index", llvm::cl::desc("opcode to measure, by index"), + llvm::cl::init(0)); + +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<unsigned> + NumRepetitions("num-repetitions", + llvm::cl::desc("number of time to repeat the asm snippet"), + llvm::cl::init(10000)); + +namespace exegesis { + +void main() { + 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(); + + // FIXME: Target-specific filter. + X86Filter Filter; + + const LLVMState State; + + unsigned Opcode = OpcodeIndex; + if (Opcode == 0) { + // Resolve opcode name -> opcode. + for (unsigned I = 0, E = State.getInstrInfo().getNumOpcodes(); I < E; ++I) { + if (State.getInstrInfo().getName(I) == OpcodeName) { + Opcode = I; + break; + } + } + if (Opcode == 0) { + llvm::report_fatal_error( + llvm::Twine("unknown opcode ").concat(OpcodeName)); + } + } + + std::unique_ptr<BenchmarkRunner> Runner; + switch (BenchmarkMode) { + case BenchmarkModeE::Latency: + Runner = llvm::make_unique<LatencyBenchmarkRunner>(); + break; + case BenchmarkModeE::Uops: + Runner = llvm::make_unique<UopsBenchmarkRunner>(); + break; + } + + Runner->run(State, Opcode, NumRepetitions > 0 ? NumRepetitions : 1, Filter) + .writeYamlOrDie("-"); +} + +} // namespace exegesis + +int main(int Argc, char **Argv) { + llvm::cl::ParseCommandLineOptions(Argc, Argv, ""); + + if (exegesis::pfm::pfmInitialize()) { + llvm::errs() << "cannot initialize libpfm\n"; + return EXIT_FAILURE; + } + + exegesis::main(); + + exegesis::pfm::pfmTerminate(); + return EXIT_SUCCESS; +} |