blob: 77683572da69abae83d452fde9d68466ff7f300b [file] [log] [blame]
Clement Courbetac74acd2018-04-04 11:37:06 +00001//===-- llvm-exegesis.cpp ---------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// Measures execution properties (latencies/uops) of an instruction.
12///
13//===----------------------------------------------------------------------===//
14
15#include "lib/BenchmarkResult.h"
16#include "lib/BenchmarkRunner.h"
17#include "lib/Latency.h"
18#include "lib/LlvmState.h"
19#include "lib/PerfHelper.h"
20#include "lib/Uops.h"
21#include "lib/X86.h"
22#include "llvm/ADT/StringExtras.h"
23#include "llvm/ADT/Twine.h"
24#include "llvm/MC/MCInstBuilder.h"
25#include "llvm/MC/MCRegisterInfo.h"
26#include "llvm/Support/CommandLine.h"
27#include "llvm/Support/Path.h"
28#include "llvm/Support/TargetSelect.h"
29#include <algorithm>
30#include <random>
31#include <string>
32#include <unordered_map>
33
34static llvm::cl::opt<unsigned>
35 OpcodeIndex("opcode-index", llvm::cl::desc("opcode to measure, by index"),
36 llvm::cl::init(0));
37
38static llvm::cl::opt<std::string>
39 OpcodeName("opcode-name", llvm::cl::desc("opcode to measure, by name"),
40 llvm::cl::init(""));
41
Clement Courbetdffc4ca2018-05-14 11:35:37 +000042enum class BenchmarkModeE { Latency, Uops };
43static llvm::cl::opt<BenchmarkModeE>
44 BenchmarkMode("benchmark-mode", llvm::cl::desc("the benchmark mode to run"),
45 llvm::cl::values(clEnumValN(BenchmarkModeE::Latency,
46 "latency", "Instruction Latency"),
47 clEnumValN(BenchmarkModeE::Uops, "uops",
48 "Uop Decomposition")));
Clement Courbetac74acd2018-04-04 11:37:06 +000049
50static llvm::cl::opt<unsigned>
51 NumRepetitions("num-repetitions",
52 llvm::cl::desc("number of time to repeat the asm snippet"),
53 llvm::cl::init(10000));
54
55namespace exegesis {
56
Clement Courbetdffc4ca2018-05-14 11:35:37 +000057void main() {
58 if (OpcodeName.empty() == (OpcodeIndex == 0)) {
Clement Courbetac74acd2018-04-04 11:37:06 +000059 llvm::report_fatal_error(
Simon Pilgrim656444b2018-04-18 14:46:54 +000060 "please provide one and only one of 'opcode-index' or 'opcode-name'");
Clement Courbetdffc4ca2018-05-14 11:35:37 +000061 }
Clement Courbetac74acd2018-04-04 11:37:06 +000062
63 llvm::InitializeNativeTarget();
64 llvm::InitializeNativeTargetAsmPrinter();
65
66 // FIXME: Target-specific filter.
67 X86Filter Filter;
68
69 const LLVMState State;
70
Simon Pilgrim656444b2018-04-18 14:46:54 +000071 if (!State.getSubtargetInfo().getSchedModel().hasExtraProcessorInfo())
72 llvm::report_fatal_error("sched model is missing extra processor info!");
73
Clement Courbetac74acd2018-04-04 11:37:06 +000074 unsigned Opcode = OpcodeIndex;
75 if (Opcode == 0) {
76 // Resolve opcode name -> opcode.
77 for (unsigned I = 0, E = State.getInstrInfo().getNumOpcodes(); I < E; ++I) {
78 if (State.getInstrInfo().getName(I) == OpcodeName) {
79 Opcode = I;
80 break;
81 }
82 }
83 if (Opcode == 0) {
84 llvm::report_fatal_error(
85 llvm::Twine("unknown opcode ").concat(OpcodeName));
86 }
87 }
88
89 std::unique_ptr<BenchmarkRunner> Runner;
90 switch (BenchmarkMode) {
91 case BenchmarkModeE::Latency:
92 Runner = llvm::make_unique<LatencyBenchmarkRunner>();
93 break;
94 case BenchmarkModeE::Uops:
95 Runner = llvm::make_unique<UopsBenchmarkRunner>();
96 break;
97 }
98
99 Runner->run(State, Opcode, NumRepetitions > 0 ? NumRepetitions : 1, Filter)
Clement Courbetdffc4ca2018-05-14 11:35:37 +0000100 .writeYamlOrDie("-");
Clement Courbetac74acd2018-04-04 11:37:06 +0000101}
102
103} // namespace exegesis
104
105int main(int Argc, char **Argv) {
106 llvm::cl::ParseCommandLineOptions(Argc, Argv, "");
107
Clement Courbetdffc4ca2018-05-14 11:35:37 +0000108 if (exegesis::pfm::pfmInitialize()) {
109 llvm::errs() << "cannot initialize libpfm\n";
110 return EXIT_FAILURE;
Clement Courbetac74acd2018-04-04 11:37:06 +0000111 }
Clement Courbetdffc4ca2018-05-14 11:35:37 +0000112
113 exegesis::main();
114
115 exegesis::pfm::pfmTerminate();
Clement Courbetac74acd2018-04-04 11:37:06 +0000116 return EXIT_SUCCESS;
117}