[llvm-exegesis][NFC] Refactor snippet file reading out of tool main.

Summary: Add unit tests.

Reviewers: gchatelet

Subscribers: mgorny, tschuett, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D68212

llvm-svn: 373202
diff --git a/llvm/unittests/tools/llvm-exegesis/X86/SnippetFileTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SnippetFileTest.cpp
new file mode 100644
index 0000000..d4773fc
--- /dev/null
+++ b/llvm/unittests/tools/llvm-exegesis/X86/SnippetFileTest.cpp
@@ -0,0 +1,132 @@
+//===-- SnippetFileTest.cpp -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "SnippetFile.h"
+
+#include "LlvmState.h"
+#include "X86InstrInfo.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+namespace exegesis {
+
+void InitializeX86ExegesisTarget();
+
+namespace {
+
+using testing::AllOf;
+using testing::ElementsAre;
+using testing::Eq;
+using testing::Field;
+using testing::Property;
+using testing::SizeIs;
+
+class X86SnippetFileTest : public ::testing::Test {
+protected:
+  X86SnippetFileTest() : State("x86_64-unknown-linux", "haswell") {}
+
+  static void SetUpTestCase() {
+    LLVMInitializeX86TargetInfo();
+    LLVMInitializeX86TargetMC();
+    LLVMInitializeX86Target();
+    LLVMInitializeX86AsmPrinter();
+    LLVMInitializeX86AsmParser();
+    InitializeX86ExegesisTarget();
+  }
+
+  Expected<std::vector<BenchmarkCode>> TestCommon(StringRef Contents) {
+    SmallString<64> Filename;
+    std::error_code EC;
+    EC = sys::fs::createUniqueDirectory("SnippetFileTestDir", Filename);
+    EXPECT_FALSE(EC);
+    sys::path::append(Filename, "snippet.s");
+    errs() << Filename << "-------\n";
+    {
+      raw_fd_ostream FOS(Filename, EC);
+      FOS << Contents;
+      EXPECT_FALSE(EC);
+    }
+    return readSnippets(State, Filename);
+  }
+
+  const LLVMState State;
+};
+
+// FIXME: Refactor these to ../Common/Matchers.h
+static auto HasOpcode = [](unsigned Opcode) {
+  return Property(&MCInst::getOpcode, Eq(Opcode));
+};
+
+MATCHER_P2(RegisterInitialValueIs, Reg, Val, "") {
+  if (arg.Register == Reg &&
+      arg.Value.getLimitedValue() == static_cast<uint64_t>(Val))
+    return true;
+  *result_listener << "expected: {" << Reg << ", " << Val << "} ";
+  *result_listener << "actual: {" << arg.Register << ", "
+                   << arg.Value.getLimitedValue() << "}";
+  return false;
+}
+
+TEST_F(X86SnippetFileTest, Works) {
+  auto Snippets = TestCommon(R"(
+    # LLVM-EXEGESIS-DEFREG RAX 0f
+    # LLVM-EXEGESIS-DEFREG SIL 0
+    # LLVM-EXEGESIS-LIVEIN RDI
+    # LLVM-EXEGESIS-LIVEIN DL
+    incq %rax
+  )");
+  EXPECT_FALSE((bool)Snippets.takeError());
+  ASSERT_THAT(*Snippets, SizeIs(1));
+  const auto &Snippet = (*Snippets)[0];
+  ASSERT_THAT(Snippet.Instructions, ElementsAre(HasOpcode(X86::INC64r)));
+  ASSERT_THAT(Snippet.RegisterInitialValues,
+              ElementsAre(RegisterInitialValueIs(X86::RAX, 15),
+                          RegisterInitialValueIs(X86::SIL, 0)));
+  ASSERT_THAT(Snippet.LiveIns, ElementsAre(X86::RDI, X86::DL));
+}
+
+TEST_F(X86SnippetFileTest, BadDefregParam) {
+  auto Error = TestCommon(R"(
+    # LLVM-EXEGESIS-DEFREG DOESNOEXIST 0
+    incq %rax
+  )")
+                   .takeError();
+  EXPECT_TRUE((bool)Error);
+  consumeError(std::move(Error));
+}
+
+TEST_F(X86SnippetFileTest, NoDefregValue) {
+  auto Error = TestCommon(R"(
+    # LLVM-EXEGESIS-DEFREG RAX
+    incq %rax
+  )")
+                   .takeError();
+  EXPECT_TRUE((bool)Error);
+  consumeError(std::move(Error));
+}
+
+TEST_F(X86SnippetFileTest, MissingParam) {
+  auto Error = TestCommon(R"(
+    # LLVM-EXEGESIS-LIVEIN
+    incq %rax
+  )")
+                   .takeError();
+  EXPECT_TRUE((bool)Error);
+  consumeError(std::move(Error));
+}
+
+} // namespace
+} // namespace exegesis
+} // namespace llvm