[docs] Fix build-docs.sh
[llvm-project.git] / llvm / unittests / tools / llvm-exegesis / X86 / SnippetRepetitorTest.cpp
blob91a271c5c1ad5d48b387592c839916031f6b6de6
1 //===-- SnippetRepetitorTest.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 //===----------------------------------------------------------------------===//
9 #include "../Common/AssemblerUtils.h"
10 #include "LlvmState.h"
11 #include "MCInstrDescView.h"
12 #include "RegisterAliasing.h"
13 #include "TestBase.h"
14 #include "X86InstrInfo.h"
15 #include "llvm/CodeGen/MachineBasicBlock.h"
17 namespace llvm {
18 namespace exegesis {
20 void InitializeX86ExegesisTarget();
22 namespace {
24 using testing::ElementsAre;
25 using testing::Eq;
26 using testing::Field;
27 using testing::Property;
28 using testing::UnorderedElementsAre;
30 class X86SnippetRepetitorTest : public X86TestBase {
31 protected:
32 void SetUp() override {
33 TM = State.createTargetMachine();
34 Context = std::make_unique<LLVMContext>();
35 Mod = std::make_unique<Module>("X86SnippetRepetitorTest", *Context);
36 Mod->setDataLayout(TM->createDataLayout());
37 MMI = std::make_unique<MachineModuleInfo>(TM.get());
38 MF = &createVoidVoidPtrMachineFunction("TestFn", Mod.get(), MMI.get());
41 void TestCommon(InstructionBenchmark::RepetitionModeE RepetitionMode) {
42 const auto Repetitor = SnippetRepetitor::Create(RepetitionMode, State);
43 const std::vector<MCInst> Instructions = {MCInstBuilder(X86::NOOP)};
44 FunctionFiller Sink(*MF, {X86::EAX});
45 const auto Fill =
46 Repetitor->Repeat(Instructions, kMinInstructions, kLoopBodySize);
47 Fill(Sink);
50 static constexpr const unsigned kMinInstructions = 3;
51 static constexpr const unsigned kLoopBodySize = 5;
53 std::unique_ptr<LLVMTargetMachine> TM;
54 std::unique_ptr<LLVMContext> Context;
55 std::unique_ptr<Module> Mod;
56 std::unique_ptr<MachineModuleInfo> MMI;
57 MachineFunction *MF = nullptr;
60 static auto HasOpcode = [](unsigned Opcode) {
61 return Property(&MachineInstr::getOpcode, Eq(Opcode));
64 static auto LiveReg = [](unsigned Reg) {
65 return Field(&MachineBasicBlock::RegisterMaskPair::PhysReg, Eq(Reg));
68 TEST_F(X86SnippetRepetitorTest, Duplicate) {
69 TestCommon(InstructionBenchmark::Duplicate);
70 // Duplicating creates a single basic block that repeats the instructions.
71 ASSERT_EQ(MF->getNumBlockIDs(), 1u);
72 EXPECT_THAT(MF->getBlockNumbered(0)->instrs(),
73 ElementsAre(HasOpcode(X86::NOOP), HasOpcode(X86::NOOP),
74 HasOpcode(X86::NOOP), HasOpcode(X86::RET64)));
77 TEST_F(X86SnippetRepetitorTest, Loop) {
78 TestCommon(InstructionBenchmark::Loop);
79 // Duplicating creates an entry block, a loop body and a ret block.
80 ASSERT_EQ(MF->getNumBlockIDs(), 3u);
81 const auto &LoopBlock = *MF->getBlockNumbered(1);
82 EXPECT_THAT(LoopBlock.instrs(),
83 ElementsAre(HasOpcode(X86::NOOP), HasOpcode(X86::NOOP),
84 HasOpcode(X86::NOOP), HasOpcode(X86::NOOP),
85 HasOpcode(X86::NOOP), HasOpcode(X86::ADD64ri8),
86 HasOpcode(X86::JCC_1)));
87 EXPECT_THAT(LoopBlock.liveins(),
88 UnorderedElementsAre(
89 LiveReg(X86::EAX),
90 LiveReg(State.getExegesisTarget().getLoopCounterRegister(
91 State.getTargetMachine().getTargetTriple()))));
92 EXPECT_THAT(MF->getBlockNumbered(2)->instrs(),
93 ElementsAre(HasOpcode(X86::RET64)));
96 } // namespace
97 } // namespace exegesis
98 } // namespace llvm