[PM] Switch analysis managers to be threaded through the run methods
[oota-llvm.git] / unittests / IR / PassManagerTest.cpp
1 //===- llvm/unittest/IR/PassManager.cpp - PassManager tests ---------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
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"
17
18 using namespace llvm;
19
20 namespace {
21
22 class TestAnalysisPass {
23 public:
24   typedef Function IRUnitT;
25
26   struct Result {
27     Result(int Count) : InstructionCount(Count) {}
28     int InstructionCount;
29   };
30
31   /// \brief Returns an opaque, unique ID for this pass type.
32   static void *ID() { return (void *)&PassID; }
33
34   TestAnalysisPass(int &Runs) : Runs(Runs) {}
35
36   /// \brief Run the analysis pass over the function and return a result.
37   Result run(Function *F) {
38     ++Runs;
39     int Count = 0;
40     for (Function::iterator BBI = F->begin(), BBE = F->end(); BBI != BBE; ++BBI)
41       for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
42            ++II)
43         ++Count;
44     return Result(Count);
45   }
46
47 private:
48   /// \brief Private static data to provide unique ID.
49   static char PassID;
50
51   int &Runs;
52 };
53
54 char TestAnalysisPass::PassID;
55
56 struct TestModulePass {
57   TestModulePass(int &RunCount) : RunCount(RunCount) {}
58
59   PreservedAnalyses run(Module *M) {
60     ++RunCount;
61     return PreservedAnalyses::none();
62   }
63
64   int &RunCount;
65 };
66
67 struct TestPreservingModulePass {
68   PreservedAnalyses run(Module *M) {
69     return PreservedAnalyses::all();
70   }
71 };
72
73 struct TestMinPreservingModulePass {
74   PreservedAnalyses run(Module *M) {
75     PreservedAnalyses PA;
76     PA.preserve<FunctionAnalysisManagerModuleProxy>();
77     return PA;
78   }
79 };
80
81 struct TestFunctionPass {
82   TestFunctionPass(int &RunCount, int &AnalyzedInstrCount)
83       : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount) {}
84
85   PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM) {
86     ++RunCount;
87
88     const TestAnalysisPass::Result &AR = AM->getResult<TestAnalysisPass>(F);
89     AnalyzedInstrCount += AR.InstructionCount;
90
91     return PreservedAnalyses::all();
92   }
93
94   int &RunCount;
95   int &AnalyzedInstrCount;
96 };
97
98 Module *parseIR(const char *IR) {
99   LLVMContext &C = getGlobalContext();
100   SMDiagnostic Err;
101   return ParseAssemblyString(IR, 0, Err, C);
102 }
103
104 class PassManagerTest : public ::testing::Test {
105 protected:
106   OwningPtr<Module> M;
107
108 public:
109   PassManagerTest()
110       : M(parseIR("define void @f() {\n"
111                   "entry:\n"
112                   "  call void @g()\n"
113                   "  call void @h()\n"
114                   "  ret void\n"
115                   "}\n"
116                   "define void @g() {\n"
117                   "  ret void\n"
118                   "}\n"
119                   "define void @h() {\n"
120                   "  ret void\n"
121                   "}\n")) {}
122 };
123
124 TEST_F(PassManagerTest, Basic) {
125   FunctionAnalysisManager FAM;
126   int AnalysisRuns = 0;
127   FAM.registerPass(TestAnalysisPass(AnalysisRuns));
128
129   ModuleAnalysisManager MAM;
130   MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM));
131
132   ModulePassManager MPM;
133
134   // Count the runs over a Function.
135   FunctionPassManager FPM1;
136   int FunctionPassRunCount1 = 0;
137   int AnalyzedInstrCount1 = 0;
138   FPM1.addPass(TestFunctionPass(FunctionPassRunCount1, AnalyzedInstrCount1));
139   MPM.addPass(createModuleToFunctionPassAdaptor(FPM1));
140
141   // Count the runs over a module.
142   int ModulePassRunCount = 0;
143   MPM.addPass(TestModulePass(ModulePassRunCount));
144
145   // Count the runs over a Function in a separate manager.
146   FunctionPassManager FPM2;
147   int FunctionPassRunCount2 = 0;
148   int AnalyzedInstrCount2 = 0;
149   FPM2.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2));
150   MPM.addPass(createModuleToFunctionPassAdaptor(FPM2));
151
152   // A third function pass manager but with only preserving intervening passes.
153   MPM.addPass(TestPreservingModulePass());
154   FunctionPassManager FPM3;
155   int FunctionPassRunCount3 = 0;
156   int AnalyzedInstrCount3 = 0;
157   FPM3.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3));
158   MPM.addPass(createModuleToFunctionPassAdaptor(FPM3));
159
160   // A fourth function pass manager but with a minimal intervening passes.
161   MPM.addPass(TestMinPreservingModulePass());
162   FunctionPassManager FPM4;
163   int FunctionPassRunCount4 = 0;
164   int AnalyzedInstrCount4 = 0;
165   FPM4.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4));
166   MPM.addPass(createModuleToFunctionPassAdaptor(FPM4));
167
168   MPM.run(M.get(), &MAM);
169
170   // Validate module pass counters.
171   EXPECT_EQ(1, ModulePassRunCount);
172
173   // Validate both function pass counter sets.
174   EXPECT_EQ(3, FunctionPassRunCount1);
175   EXPECT_EQ(5, AnalyzedInstrCount1);
176   EXPECT_EQ(3, FunctionPassRunCount2);
177   EXPECT_EQ(5, AnalyzedInstrCount2);
178   EXPECT_EQ(3, FunctionPassRunCount3);
179   EXPECT_EQ(5, AnalyzedInstrCount3);
180   EXPECT_EQ(3, FunctionPassRunCount4);
181   EXPECT_EQ(5, AnalyzedInstrCount4);
182
183   // Validate the analysis counters.
184   EXPECT_EQ(9, AnalysisRuns);
185 }
186 }