[PM] Switch the downward invalidation to be incremental where only the
[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, FunctionAnalysisManager *AM) {
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 // A test function pass that invalidates all function analyses for a function
97 // with a specific name.
98 struct TestInvalidationFunctionPass {
99   TestInvalidationFunctionPass(StringRef FunctionName) : Name(FunctionName) {}
100
101   PreservedAnalyses run(Function *F) {
102     return F->getName() == Name ? PreservedAnalyses::none()
103                                 : PreservedAnalyses::all();
104   }
105
106   StringRef Name;
107 };
108
109 Module *parseIR(const char *IR) {
110   LLVMContext &C = getGlobalContext();
111   SMDiagnostic Err;
112   return ParseAssemblyString(IR, 0, Err, C);
113 }
114
115 class PassManagerTest : public ::testing::Test {
116 protected:
117   OwningPtr<Module> M;
118
119 public:
120   PassManagerTest()
121       : M(parseIR("define void @f() {\n"
122                   "entry:\n"
123                   "  call void @g()\n"
124                   "  call void @h()\n"
125                   "  ret void\n"
126                   "}\n"
127                   "define void @g() {\n"
128                   "  ret void\n"
129                   "}\n"
130                   "define void @h() {\n"
131                   "  ret void\n"
132                   "}\n")) {}
133 };
134
135 TEST_F(PassManagerTest, Basic) {
136   FunctionAnalysisManager FAM;
137   int AnalysisRuns = 0;
138   FAM.registerPass(TestAnalysisPass(AnalysisRuns));
139
140   ModuleAnalysisManager MAM;
141   MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM));
142
143   ModulePassManager MPM;
144
145   // Count the runs over a Function.
146   FunctionPassManager FPM1;
147   int FunctionPassRunCount1 = 0;
148   int AnalyzedInstrCount1 = 0;
149   FPM1.addPass(TestFunctionPass(FunctionPassRunCount1, AnalyzedInstrCount1));
150   MPM.addPass(createModuleToFunctionPassAdaptor(FPM1));
151
152   // Count the runs over a module.
153   int ModulePassRunCount = 0;
154   MPM.addPass(TestModulePass(ModulePassRunCount));
155
156   // Count the runs over a Function in a separate manager.
157   FunctionPassManager FPM2;
158   int FunctionPassRunCount2 = 0;
159   int AnalyzedInstrCount2 = 0;
160   FPM2.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2));
161   MPM.addPass(createModuleToFunctionPassAdaptor(FPM2));
162
163   // A third function pass manager but with only preserving intervening passes
164   // and with a function pass that invalidates exactly one analysis.
165   MPM.addPass(TestPreservingModulePass());
166   FunctionPassManager FPM3;
167   int FunctionPassRunCount3 = 0;
168   int AnalyzedInstrCount3 = 0;
169   FPM3.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3));
170   FPM3.addPass(TestInvalidationFunctionPass("f"));
171   MPM.addPass(createModuleToFunctionPassAdaptor(FPM3));
172
173   // A fourth function pass manager but with a minimal intervening passes.
174   MPM.addPass(TestMinPreservingModulePass());
175   FunctionPassManager FPM4;
176   int FunctionPassRunCount4 = 0;
177   int AnalyzedInstrCount4 = 0;
178   FPM4.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4));
179   MPM.addPass(createModuleToFunctionPassAdaptor(FPM4));
180
181   MPM.run(M.get(), &MAM);
182
183   // Validate module pass counters.
184   EXPECT_EQ(1, ModulePassRunCount);
185
186   // Validate all function pass counter sets are the same.
187   EXPECT_EQ(3, FunctionPassRunCount1);
188   EXPECT_EQ(5, AnalyzedInstrCount1);
189   EXPECT_EQ(3, FunctionPassRunCount2);
190   EXPECT_EQ(5, AnalyzedInstrCount2);
191   EXPECT_EQ(3, FunctionPassRunCount3);
192   EXPECT_EQ(5, AnalyzedInstrCount3);
193   EXPECT_EQ(3, FunctionPassRunCount4);
194   EXPECT_EQ(5, AnalyzedInstrCount4);
195
196   // Validate the analysis counters:
197   //   first run over 3 functions, then module pass invalidates
198   //   second run over 3 functions, nothing invalidates
199   //   third run over 0 functions, but 1 function invalidated
200   //   fourth run over 1 function
201   EXPECT_EQ(7, AnalysisRuns);
202 }
203 }