1 //===-- BenchmarkResultTest.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 #include "BenchmarkResult.h" 11 #include "X86InstrInfo.h" 12 #include "llvm/ADT/SmallString.h" 13 #include "llvm/Support/Error.h" 14 #include "llvm/Support/Path.h" 15 #include "llvm/Support/TargetRegistry.h" 16 #include "llvm/Support/TargetSelect.h" 17 #include "llvm/Support/YAMLTraits.h" 18 #include "llvm/Support/raw_ostream.h" 19 #include "gmock/gmock.h" 20 #include "gtest/gtest.h" 21 22 using ::testing::AllOf; 23 using ::testing::Eq; 24 using ::testing::get; 25 using ::testing::Pointwise; 26 using ::testing::Property; 27 28 namespace exegesis { 29 30 bool operator==(const BenchmarkMeasure &A, const BenchmarkMeasure &B) { 31 return std::tie(A.Key, A.Value) == std::tie(B.Key, B.Value); 32 } 33 34 static std::string Dump(const llvm::MCInst &McInst) { 35 std::string Buffer; 36 llvm::raw_string_ostream OS(Buffer); 37 McInst.print(OS); 38 return Buffer; 39 } 40 41 MATCHER(EqMCInst, "") { 42 const std::string Lhs = Dump(get<0>(arg)); 43 const std::string Rhs = Dump(get<1>(arg)); 44 if (Lhs != Rhs) { 45 *result_listener << Lhs << " <=> " << Rhs; 46 return false; 47 } 48 return true; 49 } 50 51 namespace { 52 53 TEST(BenchmarkResultTest, WriteToAndReadFromDisk) { 54 LLVMInitializeX86TargetInfo(); 55 LLVMInitializeX86Target(); 56 LLVMInitializeX86TargetMC(); 57 58 // Read benchmarks. 59 const LLVMState State("x86_64-unknown-linux", "haswell"); 60 61 llvm::ExitOnError ExitOnErr; 62 63 InstructionBenchmark ToDisk; 64 65 ToDisk.Key.Instructions.push_back(llvm::MCInstBuilder(llvm::X86::XOR32rr) 66 .addReg(llvm::X86::AL) 67 .addReg(llvm::X86::AH) 68 .addImm(123) 69 .addFPImm(0.5)); 70 ToDisk.Key.Config = "config"; 71 ToDisk.Mode = InstructionBenchmark::Latency; 72 ToDisk.CpuName = "cpu_name"; 73 ToDisk.LLVMTriple = "llvm_triple"; 74 ToDisk.NumRepetitions = 1; 75 ToDisk.Measurements.push_back(BenchmarkMeasure{"a", 1, "debug a"}); 76 ToDisk.Measurements.push_back(BenchmarkMeasure{"b", 2, ""}); 77 ToDisk.Error = "error"; 78 ToDisk.Info = "info"; 79 80 llvm::SmallString<64> Filename; 81 std::error_code EC; 82 EC = llvm::sys::fs::createUniqueDirectory("BenchmarkResultTestDir", Filename); 83 ASSERT_FALSE(EC); 84 llvm::sys::path::append(Filename, "data.yaml"); 85 llvm::errs() << Filename << "-------\n"; 86 ExitOnErr(ToDisk.writeYaml(State, Filename)); 87 88 { 89 // One-element version. 90 const auto FromDisk = 91 ExitOnErr(InstructionBenchmark::readYaml(State, Filename)); 92 93 EXPECT_THAT(FromDisk.Key.Instructions, 94 Pointwise(EqMCInst(), ToDisk.Key.Instructions)); 95 EXPECT_EQ(FromDisk.Key.Config, ToDisk.Key.Config); 96 EXPECT_EQ(FromDisk.Mode, ToDisk.Mode); 97 EXPECT_EQ(FromDisk.CpuName, ToDisk.CpuName); 98 EXPECT_EQ(FromDisk.LLVMTriple, ToDisk.LLVMTriple); 99 EXPECT_EQ(FromDisk.NumRepetitions, ToDisk.NumRepetitions); 100 EXPECT_THAT(FromDisk.Measurements, ToDisk.Measurements); 101 EXPECT_THAT(FromDisk.Error, ToDisk.Error); 102 EXPECT_EQ(FromDisk.Info, ToDisk.Info); 103 } 104 { 105 // Vector version. 106 const auto FromDiskVector = 107 ExitOnErr(InstructionBenchmark::readYamls(State, Filename)); 108 ASSERT_EQ(FromDiskVector.size(), size_t{1}); 109 const auto FromDisk = FromDiskVector[0]; 110 EXPECT_THAT(FromDisk.Key.Instructions, 111 Pointwise(EqMCInst(), ToDisk.Key.Instructions)); 112 EXPECT_EQ(FromDisk.Key.Config, ToDisk.Key.Config); 113 EXPECT_EQ(FromDisk.Mode, ToDisk.Mode); 114 EXPECT_EQ(FromDisk.CpuName, ToDisk.CpuName); 115 EXPECT_EQ(FromDisk.LLVMTriple, ToDisk.LLVMTriple); 116 EXPECT_EQ(FromDisk.NumRepetitions, ToDisk.NumRepetitions); 117 EXPECT_THAT(FromDisk.Measurements, ToDisk.Measurements); 118 EXPECT_THAT(FromDisk.Error, ToDisk.Error); 119 EXPECT_EQ(FromDisk.Info, ToDisk.Info); 120 } 121 } 122 123 TEST(BenchmarkResultTest, BenchmarkMeasureStats) { 124 BenchmarkMeasureStats Stats; 125 Stats.push(BenchmarkMeasure{"a", 0.5, "debug a"}); 126 Stats.push(BenchmarkMeasure{"a", 1.5, "debug a"}); 127 Stats.push(BenchmarkMeasure{"a", -1.0, "debug a"}); 128 Stats.push(BenchmarkMeasure{"a", 0.0, "debug a"}); 129 EXPECT_EQ(Stats.min(), -1.0); 130 EXPECT_EQ(Stats.max(), 1.5); 131 EXPECT_EQ(Stats.avg(), 0.25); // (0.5+1.5-1.0+0.0) / 4 132 } 133 } // namespace 134 } // namespace exegesis 135