blob: 562fd058b61d87083f1b1b609a7de9ef7257da64 [file] [log] [blame]
Clement Courbet9431b722019-09-27 12:56:24 +00001//===-- 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//===----------------------------------------------------------------------===//
8
9#include "../Common/AssemblerUtils.h"
10#include "Latency.h"
11#include "LlvmState.h"
12#include "MCInstrDescView.h"
13#include "RegisterAliasing.h"
Clement Courbet81099012019-10-01 09:20:36 +000014#include "TestBase.h"
Clement Courbet9431b722019-09-27 12:56:24 +000015#include "Uops.h"
16#include "X86InstrInfo.h"
17#include "llvm/CodeGen/MachineBasicBlock.h"
18
19namespace llvm {
20namespace exegesis {
21
22void InitializeX86ExegesisTarget();
23
24namespace {
25
26using testing::ElementsAre;
27using testing::Eq;
28using testing::Field;
29using testing::Property;
30using testing::UnorderedElementsAre;
31
Clement Courbet81099012019-10-01 09:20:36 +000032class X86SnippetRepetitorTest : public X86TestBase {
Clement Courbet9431b722019-09-27 12:56:24 +000033protected:
Clement Courbet9431b722019-09-27 12:56:24 +000034 void SetUp() {
35 TM = State.createTargetMachine();
36 Context = std::make_unique<LLVMContext>();
Clement Courbet24078fe2019-09-27 13:21:37 +000037 Mod =
38 std::make_unique<Module>("X86SnippetRepetitorTest", *Context);
39 Mod->setDataLayout(TM->createDataLayout());
Clement Courbet9431b722019-09-27 12:56:24 +000040 MMI = std::make_unique<MachineModuleInfo>(TM.get());
Clement Courbet24078fe2019-09-27 13:21:37 +000041 MF = &createVoidVoidPtrMachineFunction("TestFn", Mod.get(), MMI.get());
Clement Courbet9431b722019-09-27 12:56:24 +000042 }
43
44 void TestCommon(InstructionBenchmark::RepetitionModeE RepetitionMode) {
45 const auto Repetitor = SnippetRepetitor::Create(RepetitionMode, State);
46 const std::vector<MCInst> Instructions = {MCInstBuilder(X86::NOOP)};
47 FunctionFiller Sink(*MF, {X86::EAX});
48 const auto Fill = Repetitor->Repeat(Instructions, kMinInstructions);
49 Fill(Sink);
50 }
51
52 static constexpr const unsigned kMinInstructions = 3;
53
Clement Courbet24078fe2019-09-27 13:21:37 +000054 std::unique_ptr<LLVMTargetMachine> TM;
Clement Courbet9431b722019-09-27 12:56:24 +000055 std::unique_ptr<LLVMContext> Context;
Clement Courbet24078fe2019-09-27 13:21:37 +000056 std::unique_ptr<Module> Mod;
Clement Courbet9431b722019-09-27 12:56:24 +000057 std::unique_ptr<MachineModuleInfo> MMI;
58 MachineFunction *MF = nullptr;
59};
60
61static auto HasOpcode = [](unsigned Opcode) {
62 return Property(&MachineInstr::getOpcode, Eq(Opcode));
63};
64
65static auto LiveReg = [](unsigned Reg) {
66 return Field(&MachineBasicBlock::RegisterMaskPair::PhysReg, Eq(Reg));
67};
68
69TEST_F(X86SnippetRepetitorTest, Duplicate) {
70 TestCommon(InstructionBenchmark::Duplicate);
71 // Duplicating creates a single basic block that repeats the instructions.
72 ASSERT_EQ(MF->getNumBlockIDs(), 1u);
73 EXPECT_THAT(MF->getBlockNumbered(0)->instrs(),
74 ElementsAre(HasOpcode(X86::NOOP), HasOpcode(X86::NOOP),
75 HasOpcode(X86::NOOP), HasOpcode(X86::RETQ)));
76}
77
78TEST_F(X86SnippetRepetitorTest, Loop) {
79 TestCommon(InstructionBenchmark::Loop);
80 // Duplicating creates an entry block, a loop body and a ret block.
81 ASSERT_EQ(MF->getNumBlockIDs(), 3u);
82 const auto &LoopBlock = *MF->getBlockNumbered(1);
83 EXPECT_THAT(LoopBlock.instrs(),
84 ElementsAre(HasOpcode(X86::NOOP), HasOpcode(X86::ADD64ri8),
85 HasOpcode(X86::JCC_1)));
86 EXPECT_THAT(LoopBlock.liveins(),
87 UnorderedElementsAre(
88 LiveReg(X86::EAX),
89 LiveReg(State.getExegesisTarget().getLoopCounterRegister(
90 State.getTargetMachine().getTargetTriple()))));
91 EXPECT_THAT(MF->getBlockNumbered(2)->instrs(),
92 ElementsAre(HasOpcode(X86::RETQ)));
93}
94
95} // namespace
96} // namespace exegesis
97} // namespace llvm