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