[PM] Remove the IRUnitT typedef requirement for analysis passes.
[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   struct Result {
25     Result(int Count) : InstructionCount(Count) {}
26     int InstructionCount;
27   };
28
29   /// \brief Returns an opaque, unique ID for this pass type.
30   static void *ID() { return (void *)&PassID; }
31
32   TestAnalysisPass(int &Runs) : Runs(Runs) {}
33
34   /// \brief Run the analysis pass over the function and return a result.
35   Result run(Function *F) {
36     ++Runs;
37     int Count = 0;
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;
40            ++II)
41         ++Count;
42     return Result(Count);
43   }
44
45 private:
46   /// \brief Private static data to provide unique ID.
47   static char PassID;
48
49   int &Runs;
50 };
51
52 char TestAnalysisPass::PassID;
53
54 struct TestModulePass {
55   TestModulePass(int &RunCount) : RunCount(RunCount) {}
56
57   PreservedAnalyses run(Module *M) {
58     ++RunCount;
59     return PreservedAnalyses::none();
60   }
61
62   int &RunCount;
63 };
64
65 struct TestPreservingModulePass {
66   PreservedAnalyses run(Module *M) {
67     return PreservedAnalyses::all();
68   }
69 };
70
71 struct TestMinPreservingModulePass {
72   PreservedAnalyses run(Module *M) {
73     PreservedAnalyses PA;
74     PA.preserve<FunctionAnalysisManagerModuleProxy>();
75     return PA;
76   }
77 };
78
79 struct TestFunctionPass {
80   TestFunctionPass(int &RunCount, int &AnalyzedInstrCount)
81       : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount) {}
82
83   PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM) {
84     ++RunCount;
85
86     const TestAnalysisPass::Result &AR = AM->getResult<TestAnalysisPass>(F);
87     AnalyzedInstrCount += AR.InstructionCount;
88
89     return PreservedAnalyses::all();
90   }
91
92   int &RunCount;
93   int &AnalyzedInstrCount;
94 };
95
96 Module *parseIR(const char *IR) {
97   LLVMContext &C = getGlobalContext();
98   SMDiagnostic Err;
99   return ParseAssemblyString(IR, 0, Err, C);
100 }
101
102 class PassManagerTest : public ::testing::Test {
103 protected:
104   OwningPtr<Module> M;
105
106 public:
107   PassManagerTest()
108       : M(parseIR("define void @f() {\n"
109                   "entry:\n"
110                   "  call void @g()\n"
111                   "  call void @h()\n"
112                   "  ret void\n"
113                   "}\n"
114                   "define void @g() {\n"
115                   "  ret void\n"
116                   "}\n"
117                   "define void @h() {\n"
118                   "  ret void\n"
119                   "}\n")) {}
120 };
121
122 TEST_F(PassManagerTest, Basic) {
123   FunctionAnalysisManager FAM;
124   int AnalysisRuns = 0;
125   FAM.registerPass(TestAnalysisPass(AnalysisRuns));
126
127   ModuleAnalysisManager MAM;
128   MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM));
129
130   ModulePassManager MPM;
131
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));
138
139   // Count the runs over a module.
140   int ModulePassRunCount = 0;
141   MPM.addPass(TestModulePass(ModulePassRunCount));
142
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));
149
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));
157
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));
165
166   MPM.run(M.get(), &MAM);
167
168   // Validate module pass counters.
169   EXPECT_EQ(1, ModulePassRunCount);
170
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);
180
181   // Validate the analysis counters.
182   EXPECT_EQ(9, AnalysisRuns);
183 }
184 }