1 //===- llvm/unittest/IR/PassManager.cpp - PassManager tests ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/Assembly/Parser.h"
11 #include "llvm/IR/Function.h"
12 #include "llvm/IR/LLVMContext.h"
13 #include "llvm/IR/Module.h"
14 #include "llvm/IR/PassManager.h"
15 #include "llvm/Support/SourceMgr.h"
16 #include "gtest/gtest.h"
22 class TestAnalysisPass {
25 Result(int Count) : InstructionCount(Count) {}
29 /// \brief Returns an opaque, unique ID for this pass type.
30 static void *ID() { return (void *)&PassID; }
32 TestAnalysisPass(int &Runs) : Runs(Runs) {}
34 /// \brief Run the analysis pass over the function and return a result.
35 Result run(Function *F) {
38 for (Function::iterator BBI = F->begin(), BBE = F->end(); BBI != BBE; ++BBI)
39 for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
46 /// \brief Private static data to provide unique ID.
52 char TestAnalysisPass::PassID;
54 struct TestModulePass {
55 TestModulePass(int &RunCount) : RunCount(RunCount) {}
57 PreservedAnalyses run(Module *M) {
59 return PreservedAnalyses::none();
65 struct TestPreservingModulePass {
66 PreservedAnalyses run(Module *M) {
67 return PreservedAnalyses::all();
71 struct TestMinPreservingModulePass {
72 PreservedAnalyses run(Module *M) {
74 PA.preserve<FunctionAnalysisManagerModuleProxy>();
79 struct TestFunctionPass {
80 TestFunctionPass(int &RunCount, int &AnalyzedInstrCount)
81 : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount) {}
83 PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM) {
86 const TestAnalysisPass::Result &AR = AM->getResult<TestAnalysisPass>(F);
87 AnalyzedInstrCount += AR.InstructionCount;
89 return PreservedAnalyses::all();
93 int &AnalyzedInstrCount;
96 Module *parseIR(const char *IR) {
97 LLVMContext &C = getGlobalContext();
99 return ParseAssemblyString(IR, 0, Err, C);
102 class PassManagerTest : public ::testing::Test {
108 : M(parseIR("define void @f() {\n"
114 "define void @g() {\n"
117 "define void @h() {\n"
122 TEST_F(PassManagerTest, Basic) {
123 FunctionAnalysisManager FAM;
124 int AnalysisRuns = 0;
125 FAM.registerPass(TestAnalysisPass(AnalysisRuns));
127 ModuleAnalysisManager MAM;
128 MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM));
130 ModulePassManager MPM;
132 // Count the runs over a Function.
133 FunctionPassManager FPM1;
134 int FunctionPassRunCount1 = 0;
135 int AnalyzedInstrCount1 = 0;
136 FPM1.addPass(TestFunctionPass(FunctionPassRunCount1, AnalyzedInstrCount1));
137 MPM.addPass(createModuleToFunctionPassAdaptor(FPM1));
139 // Count the runs over a module.
140 int ModulePassRunCount = 0;
141 MPM.addPass(TestModulePass(ModulePassRunCount));
143 // Count the runs over a Function in a separate manager.
144 FunctionPassManager FPM2;
145 int FunctionPassRunCount2 = 0;
146 int AnalyzedInstrCount2 = 0;
147 FPM2.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2));
148 MPM.addPass(createModuleToFunctionPassAdaptor(FPM2));
150 // A third function pass manager but with only preserving intervening passes.
151 MPM.addPass(TestPreservingModulePass());
152 FunctionPassManager FPM3;
153 int FunctionPassRunCount3 = 0;
154 int AnalyzedInstrCount3 = 0;
155 FPM3.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3));
156 MPM.addPass(createModuleToFunctionPassAdaptor(FPM3));
158 // A fourth function pass manager but with a minimal intervening passes.
159 MPM.addPass(TestMinPreservingModulePass());
160 FunctionPassManager FPM4;
161 int FunctionPassRunCount4 = 0;
162 int AnalyzedInstrCount4 = 0;
163 FPM4.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4));
164 MPM.addPass(createModuleToFunctionPassAdaptor(FPM4));
166 MPM.run(M.get(), &MAM);
168 // Validate module pass counters.
169 EXPECT_EQ(1, ModulePassRunCount);
171 // Validate both function pass counter sets.
172 EXPECT_EQ(3, FunctionPassRunCount1);
173 EXPECT_EQ(5, AnalyzedInstrCount1);
174 EXPECT_EQ(3, FunctionPassRunCount2);
175 EXPECT_EQ(5, AnalyzedInstrCount2);
176 EXPECT_EQ(3, FunctionPassRunCount3);
177 EXPECT_EQ(5, AnalyzedInstrCount3);
178 EXPECT_EQ(3, FunctionPassRunCount4);
179 EXPECT_EQ(5, AnalyzedInstrCount4);
181 // Validate the analysis counters.
182 EXPECT_EQ(9, AnalysisRuns);