xref: /aosp_15_r20/external/llvm/unittests/IR/PassManagerTest.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- llvm/unittest/IR/PassManager.cpp - PassManager tests ---------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "llvm/AsmParser/Parser.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/PassManager.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/SourceMgr.h"
16*9880d681SAndroid Build Coastguard Worker #include "gtest/gtest.h"
17*9880d681SAndroid Build Coastguard Worker 
18*9880d681SAndroid Build Coastguard Worker using namespace llvm;
19*9880d681SAndroid Build Coastguard Worker 
20*9880d681SAndroid Build Coastguard Worker namespace {
21*9880d681SAndroid Build Coastguard Worker 
22*9880d681SAndroid Build Coastguard Worker class TestFunctionAnalysis : public AnalysisInfoMixin<TestFunctionAnalysis> {
23*9880d681SAndroid Build Coastguard Worker public:
24*9880d681SAndroid Build Coastguard Worker   struct Result {
Result__anonaf871ec00111::TestFunctionAnalysis::Result25*9880d681SAndroid Build Coastguard Worker     Result(int Count) : InstructionCount(Count) {}
26*9880d681SAndroid Build Coastguard Worker     int InstructionCount;
27*9880d681SAndroid Build Coastguard Worker   };
28*9880d681SAndroid Build Coastguard Worker 
TestFunctionAnalysis(int & Runs)29*9880d681SAndroid Build Coastguard Worker   TestFunctionAnalysis(int &Runs) : Runs(Runs) {}
30*9880d681SAndroid Build Coastguard Worker 
31*9880d681SAndroid Build Coastguard Worker   /// \brief Run the analysis pass over the function and return a result.
run(Function & F,FunctionAnalysisManager & AM)32*9880d681SAndroid Build Coastguard Worker   Result run(Function &F, FunctionAnalysisManager &AM) {
33*9880d681SAndroid Build Coastguard Worker     ++Runs;
34*9880d681SAndroid Build Coastguard Worker     int Count = 0;
35*9880d681SAndroid Build Coastguard Worker     for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI)
36*9880d681SAndroid Build Coastguard Worker       for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
37*9880d681SAndroid Build Coastguard Worker            ++II)
38*9880d681SAndroid Build Coastguard Worker         ++Count;
39*9880d681SAndroid Build Coastguard Worker     return Result(Count);
40*9880d681SAndroid Build Coastguard Worker   }
41*9880d681SAndroid Build Coastguard Worker 
42*9880d681SAndroid Build Coastguard Worker private:
43*9880d681SAndroid Build Coastguard Worker   friend AnalysisInfoMixin<TestFunctionAnalysis>;
44*9880d681SAndroid Build Coastguard Worker   static char PassID;
45*9880d681SAndroid Build Coastguard Worker 
46*9880d681SAndroid Build Coastguard Worker   int &Runs;
47*9880d681SAndroid Build Coastguard Worker };
48*9880d681SAndroid Build Coastguard Worker 
49*9880d681SAndroid Build Coastguard Worker char TestFunctionAnalysis::PassID;
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker class TestModuleAnalysis : public AnalysisInfoMixin<TestModuleAnalysis> {
52*9880d681SAndroid Build Coastguard Worker public:
53*9880d681SAndroid Build Coastguard Worker   struct Result {
Result__anonaf871ec00111::TestModuleAnalysis::Result54*9880d681SAndroid Build Coastguard Worker     Result(int Count) : FunctionCount(Count) {}
55*9880d681SAndroid Build Coastguard Worker     int FunctionCount;
56*9880d681SAndroid Build Coastguard Worker   };
57*9880d681SAndroid Build Coastguard Worker 
TestModuleAnalysis(int & Runs)58*9880d681SAndroid Build Coastguard Worker   TestModuleAnalysis(int &Runs) : Runs(Runs) {}
59*9880d681SAndroid Build Coastguard Worker 
run(Module & M,ModuleAnalysisManager & AM)60*9880d681SAndroid Build Coastguard Worker   Result run(Module &M, ModuleAnalysisManager &AM) {
61*9880d681SAndroid Build Coastguard Worker     ++Runs;
62*9880d681SAndroid Build Coastguard Worker     int Count = 0;
63*9880d681SAndroid Build Coastguard Worker     for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
64*9880d681SAndroid Build Coastguard Worker       ++Count;
65*9880d681SAndroid Build Coastguard Worker     return Result(Count);
66*9880d681SAndroid Build Coastguard Worker   }
67*9880d681SAndroid Build Coastguard Worker 
68*9880d681SAndroid Build Coastguard Worker private:
69*9880d681SAndroid Build Coastguard Worker   friend AnalysisInfoMixin<TestModuleAnalysis>;
70*9880d681SAndroid Build Coastguard Worker   static char PassID;
71*9880d681SAndroid Build Coastguard Worker 
72*9880d681SAndroid Build Coastguard Worker   int &Runs;
73*9880d681SAndroid Build Coastguard Worker };
74*9880d681SAndroid Build Coastguard Worker 
75*9880d681SAndroid Build Coastguard Worker char TestModuleAnalysis::PassID;
76*9880d681SAndroid Build Coastguard Worker 
77*9880d681SAndroid Build Coastguard Worker struct TestModulePass : PassInfoMixin<TestModulePass> {
TestModulePass__anonaf871ec00111::TestModulePass78*9880d681SAndroid Build Coastguard Worker   TestModulePass(int &RunCount) : RunCount(RunCount) {}
79*9880d681SAndroid Build Coastguard Worker 
run__anonaf871ec00111::TestModulePass80*9880d681SAndroid Build Coastguard Worker   PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
81*9880d681SAndroid Build Coastguard Worker     ++RunCount;
82*9880d681SAndroid Build Coastguard Worker     return PreservedAnalyses::none();
83*9880d681SAndroid Build Coastguard Worker   }
84*9880d681SAndroid Build Coastguard Worker 
85*9880d681SAndroid Build Coastguard Worker   int &RunCount;
86*9880d681SAndroid Build Coastguard Worker };
87*9880d681SAndroid Build Coastguard Worker 
88*9880d681SAndroid Build Coastguard Worker struct TestPreservingModulePass : PassInfoMixin<TestPreservingModulePass> {
run__anonaf871ec00111::TestPreservingModulePass89*9880d681SAndroid Build Coastguard Worker   PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
90*9880d681SAndroid Build Coastguard Worker     return PreservedAnalyses::all();
91*9880d681SAndroid Build Coastguard Worker   }
92*9880d681SAndroid Build Coastguard Worker };
93*9880d681SAndroid Build Coastguard Worker 
94*9880d681SAndroid Build Coastguard Worker struct TestMinPreservingModulePass
95*9880d681SAndroid Build Coastguard Worker     : PassInfoMixin<TestMinPreservingModulePass> {
run__anonaf871ec00111::TestMinPreservingModulePass96*9880d681SAndroid Build Coastguard Worker   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) {
97*9880d681SAndroid Build Coastguard Worker     PreservedAnalyses PA;
98*9880d681SAndroid Build Coastguard Worker 
99*9880d681SAndroid Build Coastguard Worker     // Force running an analysis.
100*9880d681SAndroid Build Coastguard Worker     (void)AM.getResult<TestModuleAnalysis>(M);
101*9880d681SAndroid Build Coastguard Worker 
102*9880d681SAndroid Build Coastguard Worker     PA.preserve<FunctionAnalysisManagerModuleProxy>();
103*9880d681SAndroid Build Coastguard Worker     return PA;
104*9880d681SAndroid Build Coastguard Worker   }
105*9880d681SAndroid Build Coastguard Worker };
106*9880d681SAndroid Build Coastguard Worker 
107*9880d681SAndroid Build Coastguard Worker struct TestFunctionPass : PassInfoMixin<TestFunctionPass> {
TestFunctionPass__anonaf871ec00111::TestFunctionPass108*9880d681SAndroid Build Coastguard Worker   TestFunctionPass(int &RunCount, int &AnalyzedInstrCount,
109*9880d681SAndroid Build Coastguard Worker                    int &AnalyzedFunctionCount,
110*9880d681SAndroid Build Coastguard Worker                    bool OnlyUseCachedResults = false)
111*9880d681SAndroid Build Coastguard Worker       : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount),
112*9880d681SAndroid Build Coastguard Worker         AnalyzedFunctionCount(AnalyzedFunctionCount),
113*9880d681SAndroid Build Coastguard Worker         OnlyUseCachedResults(OnlyUseCachedResults) {}
114*9880d681SAndroid Build Coastguard Worker 
run__anonaf871ec00111::TestFunctionPass115*9880d681SAndroid Build Coastguard Worker   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
116*9880d681SAndroid Build Coastguard Worker     ++RunCount;
117*9880d681SAndroid Build Coastguard Worker 
118*9880d681SAndroid Build Coastguard Worker     const ModuleAnalysisManager &MAM =
119*9880d681SAndroid Build Coastguard Worker         AM.getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
120*9880d681SAndroid Build Coastguard Worker     if (TestModuleAnalysis::Result *TMA =
121*9880d681SAndroid Build Coastguard Worker             MAM.getCachedResult<TestModuleAnalysis>(*F.getParent()))
122*9880d681SAndroid Build Coastguard Worker       AnalyzedFunctionCount += TMA->FunctionCount;
123*9880d681SAndroid Build Coastguard Worker 
124*9880d681SAndroid Build Coastguard Worker     if (OnlyUseCachedResults) {
125*9880d681SAndroid Build Coastguard Worker       // Hack to force the use of the cached interface.
126*9880d681SAndroid Build Coastguard Worker       if (TestFunctionAnalysis::Result *AR =
127*9880d681SAndroid Build Coastguard Worker               AM.getCachedResult<TestFunctionAnalysis>(F))
128*9880d681SAndroid Build Coastguard Worker         AnalyzedInstrCount += AR->InstructionCount;
129*9880d681SAndroid Build Coastguard Worker     } else {
130*9880d681SAndroid Build Coastguard Worker       // Typical path just runs the analysis as needed.
131*9880d681SAndroid Build Coastguard Worker       TestFunctionAnalysis::Result &AR = AM.getResult<TestFunctionAnalysis>(F);
132*9880d681SAndroid Build Coastguard Worker       AnalyzedInstrCount += AR.InstructionCount;
133*9880d681SAndroid Build Coastguard Worker     }
134*9880d681SAndroid Build Coastguard Worker 
135*9880d681SAndroid Build Coastguard Worker     return PreservedAnalyses::all();
136*9880d681SAndroid Build Coastguard Worker   }
137*9880d681SAndroid Build Coastguard Worker 
138*9880d681SAndroid Build Coastguard Worker   int &RunCount;
139*9880d681SAndroid Build Coastguard Worker   int &AnalyzedInstrCount;
140*9880d681SAndroid Build Coastguard Worker   int &AnalyzedFunctionCount;
141*9880d681SAndroid Build Coastguard Worker   bool OnlyUseCachedResults;
142*9880d681SAndroid Build Coastguard Worker };
143*9880d681SAndroid Build Coastguard Worker 
144*9880d681SAndroid Build Coastguard Worker // A test function pass that invalidates all function analyses for a function
145*9880d681SAndroid Build Coastguard Worker // with a specific name.
146*9880d681SAndroid Build Coastguard Worker struct TestInvalidationFunctionPass
147*9880d681SAndroid Build Coastguard Worker     : PassInfoMixin<TestInvalidationFunctionPass> {
TestInvalidationFunctionPass__anonaf871ec00111::TestInvalidationFunctionPass148*9880d681SAndroid Build Coastguard Worker   TestInvalidationFunctionPass(StringRef FunctionName) : Name(FunctionName) {}
149*9880d681SAndroid Build Coastguard Worker 
run__anonaf871ec00111::TestInvalidationFunctionPass150*9880d681SAndroid Build Coastguard Worker   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
151*9880d681SAndroid Build Coastguard Worker     return F.getName() == Name ? PreservedAnalyses::none()
152*9880d681SAndroid Build Coastguard Worker                                : PreservedAnalyses::all();
153*9880d681SAndroid Build Coastguard Worker   }
154*9880d681SAndroid Build Coastguard Worker 
155*9880d681SAndroid Build Coastguard Worker   StringRef Name;
156*9880d681SAndroid Build Coastguard Worker };
157*9880d681SAndroid Build Coastguard Worker 
parseIR(LLVMContext & Context,const char * IR)158*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> parseIR(LLVMContext &Context, const char *IR) {
159*9880d681SAndroid Build Coastguard Worker   SMDiagnostic Err;
160*9880d681SAndroid Build Coastguard Worker   return parseAssemblyString(IR, Err, Context);
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker 
163*9880d681SAndroid Build Coastguard Worker class PassManagerTest : public ::testing::Test {
164*9880d681SAndroid Build Coastguard Worker protected:
165*9880d681SAndroid Build Coastguard Worker   LLVMContext Context;
166*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<Module> M;
167*9880d681SAndroid Build Coastguard Worker 
168*9880d681SAndroid Build Coastguard Worker public:
PassManagerTest()169*9880d681SAndroid Build Coastguard Worker   PassManagerTest()
170*9880d681SAndroid Build Coastguard Worker       : M(parseIR(Context, "define void @f() {\n"
171*9880d681SAndroid Build Coastguard Worker                            "entry:\n"
172*9880d681SAndroid Build Coastguard Worker                            "  call void @g()\n"
173*9880d681SAndroid Build Coastguard Worker                            "  call void @h()\n"
174*9880d681SAndroid Build Coastguard Worker                            "  ret void\n"
175*9880d681SAndroid Build Coastguard Worker                            "}\n"
176*9880d681SAndroid Build Coastguard Worker                            "define void @g() {\n"
177*9880d681SAndroid Build Coastguard Worker                            "  ret void\n"
178*9880d681SAndroid Build Coastguard Worker                            "}\n"
179*9880d681SAndroid Build Coastguard Worker                            "define void @h() {\n"
180*9880d681SAndroid Build Coastguard Worker                            "  ret void\n"
181*9880d681SAndroid Build Coastguard Worker                            "}\n")) {}
182*9880d681SAndroid Build Coastguard Worker };
183*9880d681SAndroid Build Coastguard Worker 
TEST_F(PassManagerTest,BasicPreservedAnalyses)184*9880d681SAndroid Build Coastguard Worker TEST_F(PassManagerTest, BasicPreservedAnalyses) {
185*9880d681SAndroid Build Coastguard Worker   PreservedAnalyses PA1 = PreservedAnalyses();
186*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(PA1.preserved<TestFunctionAnalysis>());
187*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(PA1.preserved<TestModuleAnalysis>());
188*9880d681SAndroid Build Coastguard Worker   PreservedAnalyses PA2 = PreservedAnalyses::none();
189*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(PA2.preserved<TestFunctionAnalysis>());
190*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(PA2.preserved<TestModuleAnalysis>());
191*9880d681SAndroid Build Coastguard Worker   PreservedAnalyses PA3 = PreservedAnalyses::all();
192*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(PA3.preserved<TestFunctionAnalysis>());
193*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(PA3.preserved<TestModuleAnalysis>());
194*9880d681SAndroid Build Coastguard Worker   PreservedAnalyses PA4 = PA1;
195*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(PA4.preserved<TestFunctionAnalysis>());
196*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(PA4.preserved<TestModuleAnalysis>());
197*9880d681SAndroid Build Coastguard Worker   PA4 = PA3;
198*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(PA4.preserved<TestFunctionAnalysis>());
199*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(PA4.preserved<TestModuleAnalysis>());
200*9880d681SAndroid Build Coastguard Worker   PA4 = std::move(PA2);
201*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(PA4.preserved<TestFunctionAnalysis>());
202*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(PA4.preserved<TestModuleAnalysis>());
203*9880d681SAndroid Build Coastguard Worker   PA4.preserve<TestFunctionAnalysis>();
204*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(PA4.preserved<TestFunctionAnalysis>());
205*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(PA4.preserved<TestModuleAnalysis>());
206*9880d681SAndroid Build Coastguard Worker   PA1.preserve<TestModuleAnalysis>();
207*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(PA1.preserved<TestFunctionAnalysis>());
208*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(PA1.preserved<TestModuleAnalysis>());
209*9880d681SAndroid Build Coastguard Worker   PA1.preserve<TestFunctionAnalysis>();
210*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(PA1.preserved<TestFunctionAnalysis>());
211*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(PA1.preserved<TestModuleAnalysis>());
212*9880d681SAndroid Build Coastguard Worker   PA1.intersect(PA4);
213*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(PA1.preserved<TestFunctionAnalysis>());
214*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(PA1.preserved<TestModuleAnalysis>());
215*9880d681SAndroid Build Coastguard Worker }
216*9880d681SAndroid Build Coastguard Worker 
TEST_F(PassManagerTest,Basic)217*9880d681SAndroid Build Coastguard Worker TEST_F(PassManagerTest, Basic) {
218*9880d681SAndroid Build Coastguard Worker   FunctionAnalysisManager FAM;
219*9880d681SAndroid Build Coastguard Worker   int FunctionAnalysisRuns = 0;
220*9880d681SAndroid Build Coastguard Worker   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
221*9880d681SAndroid Build Coastguard Worker 
222*9880d681SAndroid Build Coastguard Worker   ModuleAnalysisManager MAM;
223*9880d681SAndroid Build Coastguard Worker   int ModuleAnalysisRuns = 0;
224*9880d681SAndroid Build Coastguard Worker   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
225*9880d681SAndroid Build Coastguard Worker   MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
226*9880d681SAndroid Build Coastguard Worker   FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
227*9880d681SAndroid Build Coastguard Worker 
228*9880d681SAndroid Build Coastguard Worker   ModulePassManager MPM;
229*9880d681SAndroid Build Coastguard Worker 
230*9880d681SAndroid Build Coastguard Worker   // Count the runs over a Function.
231*9880d681SAndroid Build Coastguard Worker   int FunctionPassRunCount1 = 0;
232*9880d681SAndroid Build Coastguard Worker   int AnalyzedInstrCount1 = 0;
233*9880d681SAndroid Build Coastguard Worker   int AnalyzedFunctionCount1 = 0;
234*9880d681SAndroid Build Coastguard Worker   {
235*9880d681SAndroid Build Coastguard Worker     // Pointless scoped copy to test move assignment.
236*9880d681SAndroid Build Coastguard Worker     ModulePassManager NestedMPM;
237*9880d681SAndroid Build Coastguard Worker     FunctionPassManager FPM;
238*9880d681SAndroid Build Coastguard Worker     {
239*9880d681SAndroid Build Coastguard Worker       // Pointless scope to test move assignment.
240*9880d681SAndroid Build Coastguard Worker       FunctionPassManager NestedFPM;
241*9880d681SAndroid Build Coastguard Worker       NestedFPM.addPass(TestFunctionPass(
242*9880d681SAndroid Build Coastguard Worker           FunctionPassRunCount1, AnalyzedInstrCount1, AnalyzedFunctionCount1));
243*9880d681SAndroid Build Coastguard Worker       FPM = std::move(NestedFPM);
244*9880d681SAndroid Build Coastguard Worker     }
245*9880d681SAndroid Build Coastguard Worker     NestedMPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
246*9880d681SAndroid Build Coastguard Worker     MPM = std::move(NestedMPM);
247*9880d681SAndroid Build Coastguard Worker   }
248*9880d681SAndroid Build Coastguard Worker 
249*9880d681SAndroid Build Coastguard Worker   // Count the runs over a module.
250*9880d681SAndroid Build Coastguard Worker   int ModulePassRunCount = 0;
251*9880d681SAndroid Build Coastguard Worker   MPM.addPass(TestModulePass(ModulePassRunCount));
252*9880d681SAndroid Build Coastguard Worker 
253*9880d681SAndroid Build Coastguard Worker   // Count the runs over a Function in a separate manager.
254*9880d681SAndroid Build Coastguard Worker   int FunctionPassRunCount2 = 0;
255*9880d681SAndroid Build Coastguard Worker   int AnalyzedInstrCount2 = 0;
256*9880d681SAndroid Build Coastguard Worker   int AnalyzedFunctionCount2 = 0;
257*9880d681SAndroid Build Coastguard Worker   {
258*9880d681SAndroid Build Coastguard Worker     FunctionPassManager FPM;
259*9880d681SAndroid Build Coastguard Worker     FPM.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2,
260*9880d681SAndroid Build Coastguard Worker                                  AnalyzedFunctionCount2));
261*9880d681SAndroid Build Coastguard Worker     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
262*9880d681SAndroid Build Coastguard Worker   }
263*9880d681SAndroid Build Coastguard Worker 
264*9880d681SAndroid Build Coastguard Worker   // A third function pass manager but with only preserving intervening passes
265*9880d681SAndroid Build Coastguard Worker   // and with a function pass that invalidates exactly one analysis.
266*9880d681SAndroid Build Coastguard Worker   MPM.addPass(TestPreservingModulePass());
267*9880d681SAndroid Build Coastguard Worker   int FunctionPassRunCount3 = 0;
268*9880d681SAndroid Build Coastguard Worker   int AnalyzedInstrCount3 = 0;
269*9880d681SAndroid Build Coastguard Worker   int AnalyzedFunctionCount3 = 0;
270*9880d681SAndroid Build Coastguard Worker   {
271*9880d681SAndroid Build Coastguard Worker     FunctionPassManager FPM;
272*9880d681SAndroid Build Coastguard Worker     FPM.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3,
273*9880d681SAndroid Build Coastguard Worker                                  AnalyzedFunctionCount3));
274*9880d681SAndroid Build Coastguard Worker     FPM.addPass(TestInvalidationFunctionPass("f"));
275*9880d681SAndroid Build Coastguard Worker     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
276*9880d681SAndroid Build Coastguard Worker   }
277*9880d681SAndroid Build Coastguard Worker 
278*9880d681SAndroid Build Coastguard Worker   // A fourth function pass manager but with a minimal intervening passes.
279*9880d681SAndroid Build Coastguard Worker   MPM.addPass(TestMinPreservingModulePass());
280*9880d681SAndroid Build Coastguard Worker   int FunctionPassRunCount4 = 0;
281*9880d681SAndroid Build Coastguard Worker   int AnalyzedInstrCount4 = 0;
282*9880d681SAndroid Build Coastguard Worker   int AnalyzedFunctionCount4 = 0;
283*9880d681SAndroid Build Coastguard Worker   {
284*9880d681SAndroid Build Coastguard Worker     FunctionPassManager FPM;
285*9880d681SAndroid Build Coastguard Worker     FPM.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4,
286*9880d681SAndroid Build Coastguard Worker                                  AnalyzedFunctionCount4));
287*9880d681SAndroid Build Coastguard Worker     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
288*9880d681SAndroid Build Coastguard Worker   }
289*9880d681SAndroid Build Coastguard Worker 
290*9880d681SAndroid Build Coastguard Worker   // A fifth function pass manager but which uses only cached results.
291*9880d681SAndroid Build Coastguard Worker   int FunctionPassRunCount5 = 0;
292*9880d681SAndroid Build Coastguard Worker   int AnalyzedInstrCount5 = 0;
293*9880d681SAndroid Build Coastguard Worker   int AnalyzedFunctionCount5 = 0;
294*9880d681SAndroid Build Coastguard Worker   {
295*9880d681SAndroid Build Coastguard Worker     FunctionPassManager FPM;
296*9880d681SAndroid Build Coastguard Worker     FPM.addPass(TestInvalidationFunctionPass("f"));
297*9880d681SAndroid Build Coastguard Worker     FPM.addPass(TestFunctionPass(FunctionPassRunCount5, AnalyzedInstrCount5,
298*9880d681SAndroid Build Coastguard Worker                                  AnalyzedFunctionCount5,
299*9880d681SAndroid Build Coastguard Worker                                  /*OnlyUseCachedResults=*/true));
300*9880d681SAndroid Build Coastguard Worker     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
301*9880d681SAndroid Build Coastguard Worker   }
302*9880d681SAndroid Build Coastguard Worker 
303*9880d681SAndroid Build Coastguard Worker   MPM.run(*M, MAM);
304*9880d681SAndroid Build Coastguard Worker 
305*9880d681SAndroid Build Coastguard Worker   // Validate module pass counters.
306*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1, ModulePassRunCount);
307*9880d681SAndroid Build Coastguard Worker 
308*9880d681SAndroid Build Coastguard Worker   // Validate all function pass counter sets are the same.
309*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(3, FunctionPassRunCount1);
310*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(5, AnalyzedInstrCount1);
311*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, AnalyzedFunctionCount1);
312*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(3, FunctionPassRunCount2);
313*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(5, AnalyzedInstrCount2);
314*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, AnalyzedFunctionCount2);
315*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(3, FunctionPassRunCount3);
316*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(5, AnalyzedInstrCount3);
317*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, AnalyzedFunctionCount3);
318*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(3, FunctionPassRunCount4);
319*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(5, AnalyzedInstrCount4);
320*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, AnalyzedFunctionCount4);
321*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(3, FunctionPassRunCount5);
322*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(2, AnalyzedInstrCount5); // Only 'g' and 'h' were cached.
323*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, AnalyzedFunctionCount5);
324*9880d681SAndroid Build Coastguard Worker 
325*9880d681SAndroid Build Coastguard Worker   // Validate the analysis counters:
326*9880d681SAndroid Build Coastguard Worker   //   first run over 3 functions, then module pass invalidates
327*9880d681SAndroid Build Coastguard Worker   //   second run over 3 functions, nothing invalidates
328*9880d681SAndroid Build Coastguard Worker   //   third run over 0 functions, but 1 function invalidated
329*9880d681SAndroid Build Coastguard Worker   //   fourth run over 1 function
330*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(7, FunctionAnalysisRuns);
331*9880d681SAndroid Build Coastguard Worker 
332*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(1, ModuleAnalysisRuns);
333*9880d681SAndroid Build Coastguard Worker }
334*9880d681SAndroid Build Coastguard Worker }
335