1 //===-- BenchmarkResultTest.cpp ---------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "BenchmarkResult.h" 10 #include "MipsInstrInfo.h" 11 #include "TestBase.h" 12 #include "llvm/ADT/SmallString.h" 13 #include "llvm/MC/TargetRegistry.h" 14 #include "llvm/Support/Error.h" 15 #include "llvm/Support/Path.h" 16 #include "llvm/Support/TargetSelect.h" 17 #include "llvm/Support/YAMLTraits.h" 18 #include "llvm/Support/raw_ostream.h" 19 #include "llvm/Testing/Support/SupportHelpers.h" 20 #include "gmock/gmock.h" 21 #include "gtest/gtest.h" 22 23 using ::testing::Pointwise; 24 25 using llvm::unittest::TempDir; 26 27 namespace llvm { 28 namespace exegesis { 29 30 static std::string Dump(const MCInst &McInst) { 31 std::string Buffer; 32 raw_string_ostream OS(Buffer); 33 McInst.print(OS); 34 return Buffer; 35 } 36 37 MATCHER(EqMCInst, "") { 38 const std::string Lhs = Dump(get<0>(arg)); 39 const std::string Rhs = Dump(get<1>(arg)); 40 if (Lhs != Rhs) { 41 *result_listener << Lhs << " <=> " << Rhs; 42 return false; 43 } 44 return true; 45 } 46 47 namespace { 48 49 class MipsBenchmarkResultTest : public MipsTestBase {}; 50 51 TEST_F(MipsBenchmarkResultTest, WriteToAndReadFromDisk) { 52 ExitOnError ExitOnErr; 53 54 Benchmark ToDisk; 55 56 ToDisk.Key.Instructions.push_back(MCInstBuilder(Mips::XOR) 57 .addReg(Mips::T0) 58 .addReg(Mips::T1) 59 .addReg(Mips::T2)); 60 ToDisk.Key.Config = "config"; 61 ToDisk.Key.RegisterInitialValues = { 62 RegisterValue{Mips::T1, APInt(8, "123", 10)}, 63 RegisterValue{Mips::T2, APInt(8, "456", 10)}}; 64 ToDisk.Mode = Benchmark::Latency; 65 ToDisk.CpuName = "cpu_name"; 66 ToDisk.LLVMTriple = "llvm_triple"; 67 ToDisk.NumRepetitions = 1; 68 ToDisk.Measurements.push_back(BenchmarkMeasure::Create("a", 1, {})); 69 ToDisk.Measurements.push_back(BenchmarkMeasure::Create("b", 2, {})); 70 ToDisk.Error = "error"; 71 ToDisk.Info = "info"; 72 73 TempDir TestDirectory("BenchmarkResultTestDir", /*Unique*/ true); 74 SmallString<64> Filename(TestDirectory.path()); 75 sys::path::append(Filename, "data.yaml"); 76 errs() << Filename << "-------\n"; 77 { 78 int ResultFD = 0; 79 // Create output file or open existing file and truncate it, once. 80 ExitOnErr(errorCodeToError(openFileForWrite(Filename, ResultFD, 81 sys::fs::CD_CreateAlways, 82 sys::fs::OF_TextWithCRLF))); 83 raw_fd_ostream FileOstr(ResultFD, true /*shouldClose*/); 84 85 ExitOnErr(ToDisk.writeYamlTo(State, FileOstr)); 86 } 87 const std::unique_ptr<MemoryBuffer> Buffer = 88 std::move(*MemoryBuffer::getFile(Filename)); 89 90 { 91 // One-element version. 92 const auto FromDisk = 93 ExitOnErr(Benchmark::readYaml(State, *Buffer)); 94 95 EXPECT_THAT(FromDisk.Key.Instructions, 96 Pointwise(EqMCInst(), ToDisk.Key.Instructions)); 97 EXPECT_EQ(FromDisk.Key.Config, ToDisk.Key.Config); 98 EXPECT_EQ(FromDisk.Mode, ToDisk.Mode); 99 EXPECT_EQ(FromDisk.CpuName, ToDisk.CpuName); 100 EXPECT_EQ(FromDisk.LLVMTriple, ToDisk.LLVMTriple); 101 EXPECT_EQ(FromDisk.NumRepetitions, ToDisk.NumRepetitions); 102 EXPECT_THAT(FromDisk.Measurements, ToDisk.Measurements); 103 EXPECT_THAT(FromDisk.Error, ToDisk.Error); 104 EXPECT_EQ(FromDisk.Info, ToDisk.Info); 105 } 106 { 107 // Vector version. 108 const auto FromDiskVector = 109 ExitOnErr(Benchmark::readYamls(State, *Buffer)); 110 ASSERT_EQ(FromDiskVector.size(), size_t{1}); 111 const auto &FromDisk = FromDiskVector[0]; 112 EXPECT_THAT(FromDisk.Key.Instructions, 113 Pointwise(EqMCInst(), ToDisk.Key.Instructions)); 114 EXPECT_EQ(FromDisk.Key.Config, ToDisk.Key.Config); 115 EXPECT_EQ(FromDisk.Mode, ToDisk.Mode); 116 EXPECT_EQ(FromDisk.CpuName, ToDisk.CpuName); 117 EXPECT_EQ(FromDisk.LLVMTriple, ToDisk.LLVMTriple); 118 EXPECT_EQ(FromDisk.NumRepetitions, ToDisk.NumRepetitions); 119 EXPECT_THAT(FromDisk.Measurements, ToDisk.Measurements); 120 EXPECT_THAT(FromDisk.Error, ToDisk.Error); 121 EXPECT_EQ(FromDisk.Info, ToDisk.Info); 122 } 123 } 124 125 TEST_F(MipsBenchmarkResultTest, PerInstructionStats) { 126 PerInstructionStats Stats; 127 Stats.push(BenchmarkMeasure::Create("a", 0.5, {})); 128 Stats.push(BenchmarkMeasure::Create("a", 1.5, {})); 129 Stats.push(BenchmarkMeasure::Create("a", -1.0, {})); 130 Stats.push(BenchmarkMeasure::Create("a", 0.0, {})); 131 EXPECT_EQ(Stats.min(), -1.0); 132 EXPECT_EQ(Stats.max(), 1.5); 133 EXPECT_EQ(Stats.avg(), 0.25); // (0.5+1.5-1.0+0.0) / 4 134 } 135 } // namespace 136 } // namespace exegesis 137 } // namespace llvm 138