brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · 7a40901 Raw
114 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 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"16 17namespace llvm {18namespace exegesis {19namespace {20 21using testing::ElementsAre;22using testing::Eq;23using testing::Field;24using testing::Property;25using testing::UnorderedElementsAre;26 27class X86SnippetRepetitorTest : public X86TestBase {28protected:29  void SetUp() override {30    TM = State.createTargetMachine();31    Context = std::make_unique<LLVMContext>();32    Mod = std::make_unique<Module>("X86SnippetRepetitorTest", *Context);33    Mod->setDataLayout(TM->createDataLayout());34    MMI = std::make_unique<MachineModuleInfo>(TM.get());35    MF = &createVoidVoidPtrMachineFunction("TestFn", Mod.get(), MMI.get());36  }37 38  void TestCommon(Benchmark::RepetitionModeE RepetitionMode,39                  unsigned SnippetInstructions = 1) {40    const auto Repetitor = SnippetRepetitor::Create(41        RepetitionMode, State,42        State.getExegesisTarget().getDefaultLoopCounterRegister(43            State.getTargetMachine().getTargetTriple()));44    const std::vector<MCInst> Instructions(SnippetInstructions,45                                           MCInstBuilder(X86::NOOP));46    FunctionFiller Sink(*MF, {X86::EAX});47    const auto Fill =48        Repetitor->Repeat(Instructions, kMinInstructions, kLoopBodySize, false);49    Fill(Sink);50  }51 52  static constexpr unsigned kMinInstructions = 3;53  static constexpr unsigned kLoopBodySize = 5;54 55  std::unique_ptr<TargetMachine> TM;56  std::unique_ptr<LLVMContext> Context;57  std::unique_ptr<Module> Mod;58  std::unique_ptr<MachineModuleInfo> MMI;59  MachineFunction *MF = nullptr;60};61 62static auto HasOpcode = [](unsigned Opcode) {63  return Property(&MachineInstr::getOpcode, Eq(Opcode));64};65 66static auto LiveReg = [](unsigned Reg) {67  return Field(&MachineBasicBlock::RegisterMaskPair::PhysReg, Eq(Reg));68};69 70TEST_F(X86SnippetRepetitorTest, Duplicate) {71  TestCommon(Benchmark::Duplicate);72  // Duplicating creates a single basic block that repeats the instructions.73  ASSERT_EQ(MF->getNumBlockIDs(), 1u);74  EXPECT_THAT(MF->getBlockNumbered(0)->instrs(),75              ElementsAre(HasOpcode(X86::NOOP), HasOpcode(X86::NOOP),76                          HasOpcode(X86::NOOP), HasOpcode(X86::RET64)));77}78 79TEST_F(X86SnippetRepetitorTest, DuplicateSnippetInstructionCount) {80  TestCommon(Benchmark::Duplicate, 2);81  // Duplicating a snippet of two instructions with the minimum number of82  // instructions set to three duplicates the snippet twice for a total of83  // four instructions.84  ASSERT_EQ(MF->getNumBlockIDs(), 1u);85  EXPECT_THAT(MF->getBlockNumbered(0)->instrs(),86              ElementsAre(HasOpcode(X86::NOOP), HasOpcode(X86::NOOP),87                          HasOpcode(X86::NOOP), HasOpcode(X86::NOOP),88                          HasOpcode(X86::RET64)));89}90 91TEST_F(X86SnippetRepetitorTest, Loop) {92  TestCommon(Benchmark::Loop);93  // Duplicating creates an entry block, a loop body and a ret block.94  ASSERT_EQ(MF->getNumBlockIDs(), 3u);95  const auto &LoopBlock = *MF->getBlockNumbered(1);96  EXPECT_THAT(LoopBlock.instrs(),97              ElementsAre(HasOpcode(X86::NOOP), HasOpcode(X86::NOOP),98                          HasOpcode(X86::NOOP), HasOpcode(X86::NOOP),99                          HasOpcode(X86::NOOP), HasOpcode(X86::ADD64ri8),100                          HasOpcode(X86::JCC_1)));101  EXPECT_THAT(102      LoopBlock.liveins(),103      UnorderedElementsAre(104          LiveReg(X86::EAX),105          LiveReg(State.getExegesisTarget().getDefaultLoopCounterRegister(106              State.getTargetMachine().getTargetTriple()))));107  EXPECT_THAT(MF->getBlockNumbered(2)->instrs(),108              ElementsAre(HasOpcode(X86::RET64)));109}110 111} // namespace112} // namespace exegesis113} // namespace llvm114