brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.4 KiB · ce0211e Raw
264 lines · cpp
1//===- llvm/unittest/CodeGen/PassManager.cpp - PassManager tests ----------===//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// Test that the various MachineFunction pass managers, adaptors, analyses, and9// analysis managers work.10//===----------------------------------------------------------------------===//11 12#include "llvm/IR/PassManager.h"13#include "llvm/Analysis/CGSCCPassManager.h"14#include "llvm/Analysis/LoopAnalysisManager.h"15#include "llvm/AsmParser/Parser.h"16#include "llvm/CodeGen/MachineFunction.h"17#include "llvm/CodeGen/MachineModuleInfo.h"18#include "llvm/CodeGen/MachinePassManager.h"19#include "llvm/IR/Analysis.h"20#include "llvm/IR/LLVMContext.h"21#include "llvm/IR/Module.h"22#include "llvm/MC/TargetRegistry.h"23#include "llvm/Passes/PassBuilder.h"24#include "llvm/Support/SourceMgr.h"25#include "llvm/Support/TargetSelect.h"26#include "llvm/Target/TargetMachine.h"27#include "llvm/TargetParser/Host.h"28#include "llvm/TargetParser/Triple.h"29#include "gtest/gtest.h"30 31using namespace llvm;32 33namespace {34 35class TestFunctionAnalysis : public AnalysisInfoMixin<TestFunctionAnalysis> {36public:37  struct Result {38    Result(int Count) : InstructionCount(Count) {}39    int InstructionCount;40  };41 42  /// The number of instructions in the Function.43  Result run(Function &F, FunctionAnalysisManager &AM) {44    return Result(F.getInstructionCount());45  }46 47private:48  friend AnalysisInfoMixin<TestFunctionAnalysis>;49  static AnalysisKey Key;50};51 52AnalysisKey TestFunctionAnalysis::Key;53 54class TestMachineFunctionAnalysis55    : public AnalysisInfoMixin<TestMachineFunctionAnalysis> {56public:57  struct Result {58    Result(int Count) : InstructionCount(Count) {}59    int InstructionCount;60  };61 62  Result run(MachineFunction &MF, MachineFunctionAnalysisManager &AM) {63    FunctionAnalysisManager &FAM =64        AM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)65            .getManager();66    TestFunctionAnalysis::Result &FAR =67        FAM.getResult<TestFunctionAnalysis>(MF.getFunction());68    return FAR.InstructionCount;69  }70 71private:72  friend AnalysisInfoMixin<TestMachineFunctionAnalysis>;73  static AnalysisKey Key;74};75 76AnalysisKey TestMachineFunctionAnalysis::Key;77 78struct TestMachineFunctionPass : public PassInfoMixin<TestMachineFunctionPass> {79  TestMachineFunctionPass(int &Count, std::vector<int> &Counts)80      : Count(Count), Counts(Counts) {}81 82  PreservedAnalyses run(MachineFunction &MF,83                        MachineFunctionAnalysisManager &MFAM) {84    FunctionAnalysisManager &FAM =85        MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)86            .getManager();87    TestFunctionAnalysis::Result &FAR =88        FAM.getResult<TestFunctionAnalysis>(MF.getFunction());89    Count += FAR.InstructionCount;90 91    TestMachineFunctionAnalysis::Result &MFAR =92        MFAM.getResult<TestMachineFunctionAnalysis>(MF);93    Count += MFAR.InstructionCount;94 95    Counts.push_back(Count);96 97    return PreservedAnalyses::none();98  }99 100  int &Count;101  std::vector<int> &Counts;102};103 104struct TestMachineModulePass : public PassInfoMixin<TestMachineModulePass> {105  TestMachineModulePass(int &Count, std::vector<int> &Counts)106      : Count(Count), Counts(Counts) {}107 108  PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM) {109    MachineModuleInfo &MMI = MAM.getResult<MachineModuleAnalysis>(M).getMMI();110    FunctionAnalysisManager &FAM =111        MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();112    MachineFunctionAnalysisManager &MFAM =113        MAM.getResult<MachineFunctionAnalysisManagerModuleProxy>(M)114            .getManager();115    for (Function &F : M) {116      MachineFunction &MF = MMI.getOrCreateMachineFunction(F);117      Count += FAM.getResult<TestFunctionAnalysis>(F).InstructionCount;118      Count += MFAM.getResult<TestMachineFunctionAnalysis>(MF).InstructionCount;119    }120    Counts.push_back(Count);121    return PreservedAnalyses::all();122  }123 124  int &Count;125  std::vector<int> &Counts;126};127 128struct ReportWarningPass : public PassInfoMixin<ReportWarningPass> {129  PreservedAnalyses run(MachineFunction &MF,130                        MachineFunctionAnalysisManager &MFAM) {131    auto &Ctx = MF.getContext();132    Ctx.reportWarning(SMLoc(), "Test warning message.");133    return PreservedAnalyses::all();134  }135};136 137std::unique_ptr<Module> parseIR(LLVMContext &Context, const char *IR) {138  SMDiagnostic Err;139  return parseAssemblyString(IR, Err, Context);140}141 142class PassManagerTest : public ::testing::Test {143protected:144  LLVMContext Context;145  std::unique_ptr<Module> M;146  std::unique_ptr<TargetMachine> TM;147 148public:149  PassManagerTest()150      : M(parseIR(Context, "define void @f() {\n"151                           "entry:\n"152                           "  call void @g()\n"153                           "  call void @h()\n"154                           "  ret void\n"155                           "}\n"156                           "define void @g() {\n"157                           "  ret void\n"158                           "}\n"159                           "define void @h() {\n"160                           "  ret void\n"161                           "}\n")) {162    // MachineModuleAnalysis needs a TargetMachine instance.163    llvm::InitializeAllTargets();164 165    Triple TT(sys::getDefaultTargetTriple());166    std::string Error;167    const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);168    if (!TheTarget)169      return;170 171    TargetOptions Options;172    TM.reset(TheTarget->createTargetMachine(TT, "", "", Options, std::nullopt));173  }174};175 176TEST_F(PassManagerTest, Basic) {177  if (!TM)178    GTEST_SKIP();179 180  M->setDataLayout(TM->createDataLayout());181 182  MachineModuleInfo MMI(TM.get());183 184  MachineFunctionAnalysisManager MFAM;185  LoopAnalysisManager LAM;186  FunctionAnalysisManager FAM;187  CGSCCAnalysisManager CGAM;188  ModuleAnalysisManager MAM;189  PassBuilder PB(TM.get());190  PB.registerModuleAnalyses(MAM);191  PB.registerCGSCCAnalyses(CGAM);192  PB.registerFunctionAnalyses(FAM);193  PB.registerLoopAnalyses(LAM);194  PB.registerMachineFunctionAnalyses(MFAM);195  PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);196 197  FAM.registerPass([&] { return TestFunctionAnalysis(); });198  MAM.registerPass([&] { return MachineModuleAnalysis(MMI); });199  MFAM.registerPass([&] { return TestMachineFunctionAnalysis(); });200 201  int Count = 0;202  std::vector<int> Counts;203 204  ModulePassManager MPM;205  FunctionPassManager FPM;206  MachineFunctionPassManager MFPM;207  MPM.addPass(TestMachineModulePass(Count, Counts));208  FPM.addPass(createFunctionToMachineFunctionPassAdaptor(209      TestMachineFunctionPass(Count, Counts)));210  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));211  MPM.addPass(TestMachineModulePass(Count, Counts));212  MFPM.addPass(TestMachineFunctionPass(Count, Counts));213  FPM = FunctionPassManager();214  FPM.addPass(createFunctionToMachineFunctionPassAdaptor(std::move(MFPM)));215  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));216 217  testing::internal::CaptureStderr();218  MPM.run(*M, MAM);219  std::string Output = testing::internal::GetCapturedStderr();220 221  EXPECT_EQ((std::vector<int>{10, 16, 18, 20, 30, 36, 38, 40}), Counts);222  EXPECT_EQ(40, Count);223}224 225TEST_F(PassManagerTest, DiagnosticHandler) {226  if (!TM)227    GTEST_SKIP();228 229  M->setDataLayout(TM->createDataLayout());230 231  MachineModuleInfo MMI(TM.get());232 233  LoopAnalysisManager LAM;234  MachineFunctionAnalysisManager MFAM;235  FunctionAnalysisManager FAM;236  CGSCCAnalysisManager CGAM;237  ModuleAnalysisManager MAM;238  PassBuilder PB(TM.get());239  PB.registerModuleAnalyses(MAM);240  PB.registerCGSCCAnalyses(CGAM);241  PB.registerFunctionAnalyses(FAM);242  PB.registerLoopAnalyses(LAM);243  PB.registerMachineFunctionAnalyses(MFAM);244  PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);245 246  MAM.registerPass([&] { return MachineModuleAnalysis(MMI); });247 248  ModulePassManager MPM;249  FunctionPassManager FPM;250  MachineFunctionPassManager MFPM;251  MPM.addPass(RequireAnalysisPass<MachineModuleAnalysis, Module>());252  MFPM.addPass(ReportWarningPass());253  FPM.addPass(createFunctionToMachineFunctionPassAdaptor(std::move(MFPM)));254  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));255  testing::internal::CaptureStderr();256  MPM.run(*M, MAM);257  std::string Output = testing::internal::GetCapturedStderr();258 259  EXPECT_TRUE(Output.find("warning: <unknown>:0: Test warning message.") !=260              std::string::npos);261}262 263} // namespace264