brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.3 KiB · 432dc93 Raw
192 lines · cpp
1//===- MachineInstrTest.cpp -----------------------------------------------===//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 "../lib/CodeGen/RegAllocScore.h"10#include "llvm/CodeGen/CodeGenTargetMachineImpl.h"11#include "llvm/CodeGen/MachineBasicBlock.h"12#include "llvm/CodeGen/MachineFunction.h"13#include "llvm/CodeGen/MachineInstr.h"14#include "llvm/CodeGen/MachineMemOperand.h"15#include "llvm/CodeGen/MachineModuleInfo.h"16#include "llvm/CodeGen/TargetFrameLowering.h"17#include "llvm/CodeGen/TargetInstrInfo.h"18#include "llvm/CodeGen/TargetLowering.h"19#include "llvm/CodeGen/TargetSubtargetInfo.h"20#include "llvm/IR/DebugInfoMetadata.h"21#include "llvm/IR/IRBuilder.h"22#include "llvm/IR/Module.h"23#include "llvm/IR/ModuleSlotTracker.h"24#include "llvm/MC/MCAsmInfo.h"25#include "llvm/MC/MCSymbol.h"26#include "llvm/MC/TargetRegistry.h"27#include "llvm/Support/Compiler.h"28#include "llvm/Support/TargetSelect.h"29#include "llvm/Target/TargetOptions.h"30#include "llvm/TargetParser/Triple.h"31#include "gtest/gtest.h"32 33using namespace llvm;34 35namespace llvm {36LLVM_ABI extern cl::opt<double> CopyWeight;37LLVM_ABI extern cl::opt<double> LoadWeight;38LLVM_ABI extern cl::opt<double> StoreWeight;39LLVM_ABI extern cl::opt<double> CheapRematWeight;40LLVM_ABI extern cl::opt<double> ExpensiveRematWeight;41} // namespace llvm42 43namespace {44// Include helper functions to ease the manipulation of MachineFunctions.45#include "MFCommon.inc"46 47// MachineFunction::CreateMachineInstr doesn't copy the MCInstrDesc, it48// takes its address. So we want a bunch of pre-allocated mock MCInstrDescs.49#define MOCK_INSTR(MACRO)                                                      \50  MACRO(Copy, TargetOpcode::COPY, 0)                                           \51  MACRO(Load, 0, 1ULL << MCID::MayLoad)                                        \52  MACRO(Store, 0, 1ULL << MCID::MayStore)                                      \53  MACRO(LoadStore, 0, (1ULL << MCID::MayLoad) | (1ULL << MCID::MayStore))      \54  MACRO(CheapRemat, 0, 1ULL << MCID::CheapAsAMove)                             \55  MACRO(ExpensiveRemat, 0, 0)                                                  \56  MACRO(Dbg, TargetOpcode::DBG_LABEL,                                          \57        (1ULL << MCID::MayLoad) | (1ULL << MCID::MayStore))                    \58  MACRO(InlAsm, TargetOpcode::INLINEASM,                                       \59        (1ULL << MCID::MayLoad) | (1ULL << MCID::MayStore))                    \60  MACRO(Kill, TargetOpcode::KILL,                                              \61        (1ULL << MCID::MayLoad) | (1ULL << MCID::MayStore))62 63enum MockInstrId {64#define MOCK_INSTR_ID(ID, IGNORE, IGNORE2) ID,65  MOCK_INSTR(MOCK_INSTR_ID)66#undef MOCK_INSTR_ID67      TotalMockInstrs68};69 70const std::array<MCInstrDesc, MockInstrId::TotalMockInstrs> MockInstrDescs{{71#define MOCK_SPEC(IGNORE, OPCODE, FLAGS)                                       \72  {OPCODE, 0, 0, 0, 0, 0, 0, 0, 0, FLAGS, 0},73    MOCK_INSTR(MOCK_SPEC)74#undef MOCK_SPEC75}};76 77MachineInstr *createMockCopy(MachineFunction &MF) {78  return MF.CreateMachineInstr(MockInstrDescs[MockInstrId::Copy], DebugLoc());79}80 81MachineInstr *createMockLoad(MachineFunction &MF) {82  return MF.CreateMachineInstr(MockInstrDescs[MockInstrId::Load], DebugLoc());83}84 85MachineInstr *createMockStore(MachineFunction &MF) {86  return MF.CreateMachineInstr(MockInstrDescs[MockInstrId::Store], DebugLoc());87}88 89MachineInstr *createMockLoadStore(MachineFunction &MF) {90  return MF.CreateMachineInstr(MockInstrDescs[MockInstrId::LoadStore],91                               DebugLoc());92}93 94MachineInstr *createMockCheapRemat(MachineFunction &MF) {95  return MF.CreateMachineInstr(MockInstrDescs[MockInstrId::CheapRemat],96                               DebugLoc());97}98 99MachineInstr *createMockExpensiveRemat(MachineFunction &MF) {100  return MF.CreateMachineInstr(MockInstrDescs[MockInstrId::ExpensiveRemat],101                               DebugLoc());102}103 104MachineInstr *createMockDebug(MachineFunction &MF) {105  return MF.CreateMachineInstr(MockInstrDescs[MockInstrId::Dbg], DebugLoc());106}107 108MachineInstr *createMockKill(MachineFunction &MF) {109  return MF.CreateMachineInstr(MockInstrDescs[MockInstrId::Kill], DebugLoc());110}111 112MachineInstr *createMockInlineAsm(MachineFunction &MF) {113  return MF.CreateMachineInstr(MockInstrDescs[MockInstrId::InlAsm], DebugLoc());114}115 116TEST(RegAllocScoreTest, SkipDebugKillInlineAsm) {117  LLVMContext Ctx;118  Module Mod("Module", Ctx);119  auto MF = createMachineFunction(Ctx, Mod);120 121  auto *MBB = MF->CreateMachineBasicBlock();122  MF->insert(MF->end(), MBB);123  auto MBBFreqMock = [&](const MachineBasicBlock &_MBB) -> double {124    assert(&_MBB == MBB);125    return 0.5;126  };127  auto Next = MBB->end();128  Next = MBB->insertAfter(Next, createMockInlineAsm(*MF));129  Next = MBB->insertAfter(Next, createMockDebug(*MF));130  Next = MBB->insertAfter(Next, createMockKill(*MF));131  const auto Score = llvm::calculateRegAllocScore(132      *MF, MBBFreqMock, [](const MachineInstr &) { return false; });133  ASSERT_EQ(MF->size(), 1U);134  ASSERT_EQ(Score, RegAllocScore());135}136 137TEST(RegAllocScoreTest, Counts) {138  LLVMContext Ctx;139  Module Mod("Module", Ctx);140  auto MF = createMachineFunction(Ctx, Mod);141 142  auto *MBB1 = MF->CreateMachineBasicBlock();143  auto *MBB2 = MF->CreateMachineBasicBlock();144  MF->insert(MF->end(), MBB1);145  MF->insert(MF->end(), MBB2);146  const double Freq1 = 0.5;147  const double Freq2 = 10.0;148  auto MBBFreqMock = [&](const MachineBasicBlock &MBB) -> double {149    if (&MBB == MBB1)150      return Freq1;151    if (&MBB == MBB2)152      return Freq2;153    llvm_unreachable("We only created 2 basic blocks");154  };155  auto Next = MBB1->end();156  Next = MBB1->insertAfter(Next, createMockCopy(*MF));157  Next = MBB1->insertAfter(Next, createMockLoad(*MF));158  Next = MBB1->insertAfter(Next, createMockLoad(*MF));159  Next = MBB1->insertAfter(Next, createMockStore(*MF));160  auto *CheapRemat = createMockCheapRemat(*MF);161  MBB1->insertAfter(Next, CheapRemat);162  Next = MBB2->end();163  Next = MBB2->insertAfter(Next, createMockLoad(*MF));164  Next = MBB2->insertAfter(Next, createMockStore(*MF));165  Next = MBB2->insertAfter(Next, createMockLoadStore(*MF));166  auto *ExpensiveRemat = createMockExpensiveRemat(*MF);167  MBB2->insertAfter(Next, ExpensiveRemat);168  auto IsRemat = [&](const MachineInstr &MI) {169    return &MI == CheapRemat || &MI == ExpensiveRemat;170  };171  ASSERT_EQ(MF->size(), 2U);172  const auto TotalScore =173      llvm::calculateRegAllocScore(*MF, MBBFreqMock, IsRemat);174  ASSERT_DOUBLE_EQ(Freq1, TotalScore.copyCounts());175  ASSERT_DOUBLE_EQ(2.0 * Freq1 + Freq2, TotalScore.loadCounts());176  ASSERT_DOUBLE_EQ(Freq1 + Freq2, TotalScore.storeCounts());177  ASSERT_DOUBLE_EQ(Freq2, TotalScore.loadStoreCounts());178  ASSERT_DOUBLE_EQ(Freq1, TotalScore.cheapRematCounts());179  ASSERT_DOUBLE_EQ(Freq2, TotalScore.expensiveRematCounts());180  ASSERT_DOUBLE_EQ(181      TotalScore.getScore(),182      TotalScore.copyCounts() * CopyWeight +183          TotalScore.loadCounts() * LoadWeight +184          TotalScore.storeCounts() * StoreWeight +185          TotalScore.loadStoreCounts() * (LoadWeight + StoreWeight) +186          TotalScore.cheapRematCounts() * CheapRematWeight +187          TotalScore.expensiveRematCounts() * ExpensiveRematWeight188 189  );190}191} // end namespace192