xref: /llvm-project/llvm/unittests/IR/PassManagerTest.cpp (revision 20a7ea49f40e2d47eb6b87acf835782dece92f08)
1 //===- llvm/unittest/IR/PassManager.cpp - PassManager tests ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/IR/PassManager.h"
10 #include "llvm/Analysis/AssumptionCache.h"
11 #include "llvm/Analysis/TargetTransformInfo.h"
12 #include "llvm/AsmParser/Parser.h"
13 #include "llvm/IR/Dominators.h"
14 #include "llvm/IR/Function.h"
15 #include "llvm/IR/LLVMContext.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/IR/PassManagerImpl.h"
18 #include "llvm/Passes/StandardInstrumentations.h"
19 #include "llvm/Support/SourceMgr.h"
20 #include "llvm/Transforms/Scalar/SimplifyCFG.h"
21 #include "gtest/gtest.h"
22 
23 using namespace llvm;
24 
25 namespace {
26 
27 class TestFunctionAnalysis : public AnalysisInfoMixin<TestFunctionAnalysis> {
28 public:
29   struct Result {
30     Result(int Count) : InstructionCount(Count) {}
31     int InstructionCount;
32     bool invalidate(Function &, const PreservedAnalyses &PA,
33                     FunctionAnalysisManager::Invalidator &) {
34       // Check whether the analysis or all analyses on functions have been
35       // preserved.
36       auto PAC = PA.getChecker<TestFunctionAnalysis>();
37       return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>());
38     }
39   };
40 
41   TestFunctionAnalysis(int &Runs) : Runs(Runs) {}
42 
43   /// Run the analysis pass over the function and return a result.
44   Result run(Function &F, FunctionAnalysisManager &AM) {
45     ++Runs;
46     int Count = 0;
47     for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI)
48       for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
49            ++II)
50         ++Count;
51     return Result(Count);
52   }
53 
54 private:
55   friend AnalysisInfoMixin<TestFunctionAnalysis>;
56   static AnalysisKey Key;
57 
58   int &Runs;
59 };
60 
61 AnalysisKey TestFunctionAnalysis::Key;
62 
63 class TestModuleAnalysis : public AnalysisInfoMixin<TestModuleAnalysis> {
64 public:
65   struct Result {
66     Result(int Count) : FunctionCount(Count) {}
67     int FunctionCount;
68     bool invalidate(Module &, const PreservedAnalyses &PA,
69                     ModuleAnalysisManager::Invalidator &) {
70       // Check whether the analysis or all analyses on modules have been
71       // preserved.
72       auto PAC = PA.getChecker<TestModuleAnalysis>();
73       return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Module>>());
74     }
75   };
76 
77   TestModuleAnalysis(int &Runs) : Runs(Runs) {}
78 
79   Result run(Module &M, ModuleAnalysisManager &AM) {
80     ++Runs;
81     int Count = 0;
82     for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
83       ++Count;
84     return Result(Count);
85   }
86 
87 private:
88   friend AnalysisInfoMixin<TestModuleAnalysis>;
89   static AnalysisKey Key;
90 
91   int &Runs;
92 };
93 
94 AnalysisKey TestModuleAnalysis::Key;
95 
96 struct TestModulePass : PassInfoMixin<TestModulePass> {
97   TestModulePass(int &RunCount) : RunCount(RunCount) {}
98 
99   PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
100     ++RunCount;
101     return PreservedAnalyses::none();
102   }
103 
104   int &RunCount;
105 };
106 
107 struct TestPreservingModulePass : PassInfoMixin<TestPreservingModulePass> {
108   PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
109     return PreservedAnalyses::all();
110   }
111 };
112 
113 struct TestFunctionPass : PassInfoMixin<TestFunctionPass> {
114   TestFunctionPass(int &RunCount, int &AnalyzedInstrCount,
115                    int &AnalyzedFunctionCount, ModuleAnalysisManager &MAM,
116                    bool OnlyUseCachedResults = false)
117       : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount),
118         AnalyzedFunctionCount(AnalyzedFunctionCount), MAM(MAM),
119         OnlyUseCachedResults(OnlyUseCachedResults) {}
120 
121   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
122     ++RunCount;
123 
124     // Getting a cached result that isn't stateless through the proxy will
125     // trigger an assert:
126     // auto &ModuleProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
127     // Use MAM, for the purposes of this unittest.
128     if (TestModuleAnalysis::Result *TMA =
129             MAM.getCachedResult<TestModuleAnalysis>(*F.getParent())) {
130       AnalyzedFunctionCount += TMA->FunctionCount;
131     }
132 
133     if (OnlyUseCachedResults) {
134       // Hack to force the use of the cached interface.
135       if (TestFunctionAnalysis::Result *AR =
136               AM.getCachedResult<TestFunctionAnalysis>(F))
137         AnalyzedInstrCount += AR->InstructionCount;
138     } else {
139       // Typical path just runs the analysis as needed.
140       TestFunctionAnalysis::Result &AR = AM.getResult<TestFunctionAnalysis>(F);
141       AnalyzedInstrCount += AR.InstructionCount;
142     }
143 
144     return PreservedAnalyses::all();
145   }
146 
147   int &RunCount;
148   int &AnalyzedInstrCount;
149   int &AnalyzedFunctionCount;
150   ModuleAnalysisManager &MAM;
151   bool OnlyUseCachedResults;
152 };
153 
154 // A test function pass that invalidates all function analyses for a function
155 // with a specific name.
156 struct TestInvalidationFunctionPass
157     : PassInfoMixin<TestInvalidationFunctionPass> {
158   TestInvalidationFunctionPass(StringRef FunctionName) : Name(FunctionName) {}
159 
160   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
161     return F.getName() == Name ? PreservedAnalyses::none()
162                                : PreservedAnalyses::all();
163   }
164 
165   StringRef Name;
166 };
167 
168 std::unique_ptr<Module> parseIR(LLVMContext &Context, const char *IR) {
169   SMDiagnostic Err;
170   return parseAssemblyString(IR, Err, Context);
171 }
172 
173 class PassManagerTest : public ::testing::Test {
174 protected:
175   LLVMContext Context;
176   std::unique_ptr<Module> M;
177 
178 public:
179   PassManagerTest()
180       : M(parseIR(Context, "define void @f() {\n"
181                            "entry:\n"
182                            "  call void @g()\n"
183                            "  call void @h()\n"
184                            "  ret void\n"
185                            "}\n"
186                            "define void @g() {\n"
187                            "  ret void\n"
188                            "}\n"
189                            "define void @h() {\n"
190                            "  ret void\n"
191                            "}\n")) {}
192 };
193 
194 TEST(PreservedAnalysesTest, Basic) {
195   PreservedAnalyses PA1 = PreservedAnalyses();
196   {
197     auto PAC = PA1.getChecker<TestFunctionAnalysis>();
198     EXPECT_FALSE(PAC.preserved());
199     EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
200   }
201   {
202     auto PAC = PA1.getChecker<TestModuleAnalysis>();
203     EXPECT_FALSE(PAC.preserved());
204     EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Module>>());
205   }
206   auto PA2 = PreservedAnalyses::none();
207   {
208     auto PAC = PA2.getChecker<TestFunctionAnalysis>();
209     EXPECT_FALSE(PAC.preserved());
210     EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
211   }
212   auto PA3 = PreservedAnalyses::all();
213   {
214     auto PAC = PA3.getChecker<TestFunctionAnalysis>();
215     EXPECT_TRUE(PAC.preserved());
216     EXPECT_TRUE(PAC.preservedSet<AllAnalysesOn<Function>>());
217   }
218   PreservedAnalyses PA4 = PA1;
219   {
220     auto PAC = PA4.getChecker<TestFunctionAnalysis>();
221     EXPECT_FALSE(PAC.preserved());
222     EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
223   }
224   PA4 = PA3;
225   {
226     auto PAC = PA4.getChecker<TestFunctionAnalysis>();
227     EXPECT_TRUE(PAC.preserved());
228     EXPECT_TRUE(PAC.preservedSet<AllAnalysesOn<Function>>());
229   }
230   PA4 = std::move(PA2);
231   {
232     auto PAC = PA4.getChecker<TestFunctionAnalysis>();
233     EXPECT_FALSE(PAC.preserved());
234     EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
235   }
236   auto PA5 = PreservedAnalyses::allInSet<AllAnalysesOn<Function>>();
237   {
238     auto PAC = PA5.getChecker<TestFunctionAnalysis>();
239     EXPECT_FALSE(PAC.preserved());
240     EXPECT_TRUE(PAC.preservedSet<AllAnalysesOn<Function>>());
241     EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Module>>());
242   }
243 }
244 
245 TEST(PreservedAnalysesTest, Preserve) {
246   auto PA = PreservedAnalyses::none();
247   PA.preserve<TestFunctionAnalysis>();
248   EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>().preserved());
249   EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>().preserved());
250   PA.preserve<TestModuleAnalysis>();
251   EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>().preserved());
252   EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>().preserved());
253 
254   // Redundant calls are fine.
255   PA.preserve<TestFunctionAnalysis>();
256   EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>().preserved());
257   EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>().preserved());
258 }
259 
260 TEST(PreservedAnalysesTest, PreserveSets) {
261   auto PA = PreservedAnalyses::none();
262   PA.preserveSet<AllAnalysesOn<Function>>();
263   EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
264                   .preservedSet<AllAnalysesOn<Function>>());
265   EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>()
266                    .preservedSet<AllAnalysesOn<Module>>());
267   PA.preserveSet<AllAnalysesOn<Module>>();
268   EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
269                   .preservedSet<AllAnalysesOn<Function>>());
270   EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>()
271                   .preservedSet<AllAnalysesOn<Module>>());
272 
273   // Mixing is fine.
274   PA.preserve<TestFunctionAnalysis>();
275   EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
276                   .preservedSet<AllAnalysesOn<Function>>());
277   EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>()
278                   .preservedSet<AllAnalysesOn<Module>>());
279 
280   // Redundant calls are fine.
281   PA.preserveSet<AllAnalysesOn<Module>>();
282   EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
283                   .preservedSet<AllAnalysesOn<Function>>());
284   EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>()
285                   .preservedSet<AllAnalysesOn<Module>>());
286 }
287 
288 TEST(PreservedAnalysisTest, Intersect) {
289   // Setup the initial sets.
290   auto PA1 = PreservedAnalyses::none();
291   PA1.preserve<TestFunctionAnalysis>();
292   PA1.preserveSet<AllAnalysesOn<Module>>();
293   auto PA2 = PreservedAnalyses::none();
294   PA2.preserve<TestFunctionAnalysis>();
295   PA2.preserveSet<AllAnalysesOn<Function>>();
296   PA2.preserve<TestModuleAnalysis>();
297   PA2.preserveSet<AllAnalysesOn<Module>>();
298   auto PA3 = PreservedAnalyses::none();
299   PA3.preserve<TestModuleAnalysis>();
300   PA3.preserveSet<AllAnalysesOn<Function>>();
301 
302   // Self intersection is a no-op.
303   auto Intersected = PA1;
304   Intersected.intersect(PA1);
305   EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
306   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
307                    .preservedSet<AllAnalysesOn<Function>>());
308   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
309   EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
310                   .preservedSet<AllAnalysesOn<Module>>());
311 
312   // Intersecting with all is a no-op.
313   Intersected.intersect(PreservedAnalyses::all());
314   EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
315   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
316                    .preservedSet<AllAnalysesOn<Function>>());
317   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
318   EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
319                   .preservedSet<AllAnalysesOn<Module>>());
320 
321   // Intersecting a narrow set with a more broad set is the narrow set.
322   Intersected.intersect(PA2);
323   EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
324   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
325                    .preservedSet<AllAnalysesOn<Function>>());
326   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
327   EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
328                   .preservedSet<AllAnalysesOn<Module>>());
329 
330   // Intersecting a broad set with a more narrow set is the narrow set.
331   Intersected = PA2;
332   Intersected.intersect(PA1);
333   EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
334   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
335                    .preservedSet<AllAnalysesOn<Function>>());
336   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
337   EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
338                   .preservedSet<AllAnalysesOn<Module>>());
339 
340   // Intersecting with empty clears.
341   Intersected.intersect(PreservedAnalyses::none());
342   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
343   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
344                    .preservedSet<AllAnalysesOn<Function>>());
345   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
346   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>()
347                    .preservedSet<AllAnalysesOn<Module>>());
348 
349   // Intersecting non-overlapping clears.
350   Intersected = PA1;
351   Intersected.intersect(PA3);
352   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
353   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
354                    .preservedSet<AllAnalysesOn<Function>>());
355   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
356   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>()
357                    .preservedSet<AllAnalysesOn<Module>>());
358 
359   // Intersecting with moves works in when there is storage on both sides.
360   Intersected = PA1;
361   auto Tmp = PA2;
362   Intersected.intersect(std::move(Tmp));
363   EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
364   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
365                    .preservedSet<AllAnalysesOn<Function>>());
366   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
367   EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
368                   .preservedSet<AllAnalysesOn<Module>>());
369 
370   // Intersecting with move works for incoming all and existing all.
371   auto Tmp2 = PreservedAnalyses::all();
372   Intersected.intersect(std::move(Tmp2));
373   EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
374   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
375                    .preservedSet<AllAnalysesOn<Function>>());
376   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
377   EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
378                   .preservedSet<AllAnalysesOn<Module>>());
379   Intersected = PreservedAnalyses::all();
380   auto Tmp3 = PA1;
381   Intersected.intersect(std::move(Tmp3));
382   EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
383   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
384                    .preservedSet<AllAnalysesOn<Function>>());
385   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
386   EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
387                   .preservedSet<AllAnalysesOn<Module>>());
388 }
389 
390 TEST(PreservedAnalysisTest, Abandon) {
391   auto PA = PreservedAnalyses::none();
392 
393   // We can abandon things after they are preserved.
394   PA.preserve<TestFunctionAnalysis>();
395   PA.abandon<TestFunctionAnalysis>();
396   EXPECT_FALSE(PA.getChecker<TestFunctionAnalysis>().preserved());
397 
398   // Repeated is fine, and abandoning if they were never preserved is fine.
399   PA.abandon<TestFunctionAnalysis>();
400   EXPECT_FALSE(PA.getChecker<TestFunctionAnalysis>().preserved());
401   PA.abandon<TestModuleAnalysis>();
402   EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>().preserved());
403 
404   // Even if the sets are preserved, the abandoned analyses' checker won't
405   // return true for those sets.
406   PA.preserveSet<AllAnalysesOn<Function>>();
407   PA.preserveSet<AllAnalysesOn<Module>>();
408   EXPECT_FALSE(PA.getChecker<TestFunctionAnalysis>()
409                    .preservedSet<AllAnalysesOn<Function>>());
410   EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>()
411                    .preservedSet<AllAnalysesOn<Module>>());
412 
413   // But an arbitrary (opaque) analysis will still observe the sets as
414   // preserved. This also checks that we can use an explicit ID rather than
415   // a type.
416   AnalysisKey FakeKey, *FakeID = &FakeKey;
417   EXPECT_TRUE(PA.getChecker(FakeID).preservedSet<AllAnalysesOn<Function>>());
418   EXPECT_TRUE(PA.getChecker(FakeID).preservedSet<AllAnalysesOn<Module>>());
419 }
420 
421 TEST_F(PassManagerTest, Basic) {
422   FunctionAnalysisManager FAM;
423   int FunctionAnalysisRuns = 0;
424   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
425 
426   ModuleAnalysisManager MAM;
427   int ModuleAnalysisRuns = 0;
428   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
429   MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
430   FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
431 
432   MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
433   FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
434 
435   ModulePassManager MPM;
436 
437   // Count the runs over a Function.
438   int FunctionPassRunCount1 = 0;
439   int AnalyzedInstrCount1 = 0;
440   int AnalyzedFunctionCount1 = 0;
441   {
442     // Pointless scoped copy to test move assignment.
443     ModulePassManager NestedMPM;
444     FunctionPassManager FPM;
445     {
446       // Pointless scope to test move assignment.
447       FunctionPassManager NestedFPM;
448       NestedFPM.addPass(TestFunctionPass(FunctionPassRunCount1,
449                                          AnalyzedInstrCount1,
450                                          AnalyzedFunctionCount1, MAM));
451       FPM = std::move(NestedFPM);
452     }
453     NestedMPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
454     MPM = std::move(NestedMPM);
455   }
456 
457   // Count the runs over a module.
458   int ModulePassRunCount = 0;
459   MPM.addPass(TestModulePass(ModulePassRunCount));
460 
461   // Count the runs over a Function in a separate manager.
462   int FunctionPassRunCount2 = 0;
463   int AnalyzedInstrCount2 = 0;
464   int AnalyzedFunctionCount2 = 0;
465   {
466     FunctionPassManager FPM;
467     FPM.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2,
468                                  AnalyzedFunctionCount2, MAM));
469     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
470   }
471 
472   // A third function pass manager but with only preserving intervening passes
473   // and with a function pass that invalidates exactly one analysis.
474   MPM.addPass(TestPreservingModulePass());
475   int FunctionPassRunCount3 = 0;
476   int AnalyzedInstrCount3 = 0;
477   int AnalyzedFunctionCount3 = 0;
478   {
479     FunctionPassManager FPM;
480     FPM.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3,
481                                  AnalyzedFunctionCount3, MAM));
482     FPM.addPass(TestInvalidationFunctionPass("f"));
483     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
484   }
485 
486   // A fourth function pass manager but with only preserving intervening
487   // passes but triggering the module analysis.
488   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
489   int FunctionPassRunCount4 = 0;
490   int AnalyzedInstrCount4 = 0;
491   int AnalyzedFunctionCount4 = 0;
492   {
493     FunctionPassManager FPM;
494     FPM.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4,
495                                  AnalyzedFunctionCount4, MAM));
496     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
497   }
498 
499   // A fifth function pass manager which invalidates one function first but
500   // uses only cached results.
501   int FunctionPassRunCount5 = 0;
502   int AnalyzedInstrCount5 = 0;
503   int AnalyzedFunctionCount5 = 0;
504   {
505     FunctionPassManager FPM;
506     FPM.addPass(TestInvalidationFunctionPass("f"));
507     FPM.addPass(TestFunctionPass(FunctionPassRunCount5, AnalyzedInstrCount5,
508                                  AnalyzedFunctionCount5, MAM,
509                                  /*OnlyUseCachedResults=*/true));
510     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
511   }
512 
513   MPM.run(*M, MAM);
514 
515   // Validate module pass counters.
516   EXPECT_EQ(1, ModulePassRunCount);
517 
518   // Validate all function pass counter sets are the same.
519   EXPECT_EQ(3, FunctionPassRunCount1);
520   EXPECT_EQ(5, AnalyzedInstrCount1);
521   EXPECT_EQ(0, AnalyzedFunctionCount1);
522   EXPECT_EQ(3, FunctionPassRunCount2);
523   EXPECT_EQ(5, AnalyzedInstrCount2);
524   EXPECT_EQ(0, AnalyzedFunctionCount2);
525   EXPECT_EQ(3, FunctionPassRunCount3);
526   EXPECT_EQ(5, AnalyzedInstrCount3);
527   EXPECT_EQ(0, AnalyzedFunctionCount3);
528   EXPECT_EQ(3, FunctionPassRunCount4);
529   EXPECT_EQ(5, AnalyzedInstrCount4);
530   EXPECT_EQ(9, AnalyzedFunctionCount4);
531   EXPECT_EQ(3, FunctionPassRunCount5);
532   EXPECT_EQ(2, AnalyzedInstrCount5); // Only 'g' and 'h' were cached.
533   EXPECT_EQ(9, AnalyzedFunctionCount5);
534 
535   // Validate the analysis counters:
536   //   first run over 3 functions, then module pass invalidates
537   //   second run over 3 functions, nothing invalidates
538   //   third run over 0 functions, but 1 function invalidated
539   //   fourth run over 1 function
540   //   fifth run invalidates 1 function first, but runs over 0 functions
541   EXPECT_EQ(7, FunctionAnalysisRuns);
542 
543   EXPECT_EQ(1, ModuleAnalysisRuns);
544 }
545 
546 // A customized pass manager that passes extra arguments through the
547 // infrastructure.
548 typedef AnalysisManager<Function, int> CustomizedAnalysisManager;
549 typedef PassManager<Function, CustomizedAnalysisManager, int, int &>
550     CustomizedPassManager;
551 
552 class CustomizedAnalysis : public AnalysisInfoMixin<CustomizedAnalysis> {
553 public:
554   struct Result {
555     Result(int I) : I(I) {}
556     int I;
557   };
558 
559   Result run(Function &F, CustomizedAnalysisManager &AM, int I) {
560     return Result(I);
561   }
562 
563 private:
564   friend AnalysisInfoMixin<CustomizedAnalysis>;
565   static AnalysisKey Key;
566 };
567 
568 AnalysisKey CustomizedAnalysis::Key;
569 
570 struct CustomizedPass : PassInfoMixin<CustomizedPass> {
571   std::function<void(CustomizedAnalysis::Result &, int &)> Callback;
572 
573   template <typename CallbackT>
574   CustomizedPass(CallbackT Callback) : Callback(Callback) {}
575 
576   PreservedAnalyses run(Function &F, CustomizedAnalysisManager &AM, int I,
577                         int &O) {
578     Callback(AM.getResult<CustomizedAnalysis>(F, I), O);
579     return PreservedAnalyses::none();
580   }
581 };
582 
583 TEST_F(PassManagerTest, CustomizedPassManagerArgs) {
584   CustomizedAnalysisManager AM;
585   AM.registerPass([&] { return CustomizedAnalysis(); });
586   PassInstrumentationCallbacks PIC;
587   AM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
588 
589   CustomizedPassManager PM;
590 
591   // Add an instance of the customized pass that just accumulates the input
592   // after it is round-tripped through the analysis.
593   int Result = 0;
594   PM.addPass(
595       CustomizedPass([](CustomizedAnalysis::Result &R, int &O) { O += R.I; }));
596 
597   // Run this over every function with the input of 42.
598   for (Function &F : *M)
599     PM.run(F, AM, 42, Result);
600 
601   // And ensure that we accumulated the correct result.
602   EXPECT_EQ(42 * (int)M->size(), Result);
603 }
604 
605 /// A test analysis pass which caches in its result another analysis pass and
606 /// uses it to serve queries. This requires the result to invalidate itself
607 /// when its dependency is invalidated.
608 struct TestIndirectFunctionAnalysis
609     : public AnalysisInfoMixin<TestIndirectFunctionAnalysis> {
610   struct Result {
611     Result(TestFunctionAnalysis::Result &FDep, TestModuleAnalysis::Result &MDep)
612         : FDep(FDep), MDep(MDep) {}
613     TestFunctionAnalysis::Result &FDep;
614     TestModuleAnalysis::Result &MDep;
615 
616     bool invalidate(Function &F, const PreservedAnalyses &PA,
617                     FunctionAnalysisManager::Invalidator &Inv) {
618       auto PAC = PA.getChecker<TestIndirectFunctionAnalysis>();
619       return !(PAC.preserved() ||
620                PAC.preservedSet<AllAnalysesOn<Function>>()) ||
621              Inv.invalidate<TestFunctionAnalysis>(F, PA);
622     }
623   };
624 
625   TestIndirectFunctionAnalysis(int &Runs, ModuleAnalysisManager &MAM)
626       : Runs(Runs), MAM(MAM) {}
627 
628   /// Run the analysis pass over the function and return a result.
629   Result run(Function &F, FunctionAnalysisManager &AM) {
630     ++Runs;
631     auto &FDep = AM.getResult<TestFunctionAnalysis>(F);
632     auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
633     // For the test, we insist that the module analysis starts off in the
634     // cache. Getting a cached result that isn't stateless trigger an assert.
635     // Use MAM, for the purposes of this unittest.
636     auto &MDep = *MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
637     // And register the dependency as module analysis dependencies have to be
638     // pre-registered on the proxy.
639     MAMProxy.registerOuterAnalysisInvalidation<TestModuleAnalysis,
640                                                TestIndirectFunctionAnalysis>();
641     return Result(FDep, MDep);
642   }
643 
644 private:
645   friend AnalysisInfoMixin<TestIndirectFunctionAnalysis>;
646   static AnalysisKey Key;
647 
648   int &Runs;
649   ModuleAnalysisManager &MAM;
650 };
651 
652 AnalysisKey TestIndirectFunctionAnalysis::Key;
653 
654 /// A test analysis pass which chaches in its result the result from the above
655 /// indirect analysis pass.
656 ///
657 /// This allows us to ensure that whenever an analysis pass is invalidated due
658 /// to dependencies (especially dependencies across IR units that trigger
659 /// asynchronous invalidation) we correctly detect that this may in turn cause
660 /// other analysis to be invalidated.
661 struct TestDoublyIndirectFunctionAnalysis
662     : public AnalysisInfoMixin<TestDoublyIndirectFunctionAnalysis> {
663   struct Result {
664     Result(TestIndirectFunctionAnalysis::Result &IDep) : IDep(IDep) {}
665     TestIndirectFunctionAnalysis::Result &IDep;
666 
667     bool invalidate(Function &F, const PreservedAnalyses &PA,
668                     FunctionAnalysisManager::Invalidator &Inv) {
669       auto PAC = PA.getChecker<TestDoublyIndirectFunctionAnalysis>();
670       return !(PAC.preserved() ||
671                PAC.preservedSet<AllAnalysesOn<Function>>()) ||
672              Inv.invalidate<TestIndirectFunctionAnalysis>(F, PA);
673     }
674   };
675 
676   TestDoublyIndirectFunctionAnalysis(int &Runs) : Runs(Runs) {}
677 
678   /// Run the analysis pass over the function and return a result.
679   Result run(Function &F, FunctionAnalysisManager &AM) {
680     ++Runs;
681     auto &IDep = AM.getResult<TestIndirectFunctionAnalysis>(F);
682     return Result(IDep);
683   }
684 
685 private:
686   friend AnalysisInfoMixin<TestDoublyIndirectFunctionAnalysis>;
687   static AnalysisKey Key;
688 
689   int &Runs;
690 };
691 
692 AnalysisKey TestDoublyIndirectFunctionAnalysis::Key;
693 
694 struct LambdaPass : public PassInfoMixin<LambdaPass> {
695   using FuncT = std::function<PreservedAnalyses(Function &, FunctionAnalysisManager &)>;
696 
697   LambdaPass(FuncT Func) : Func(std::move(Func)) {}
698 
699   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
700     return Func(F, AM);
701   }
702 
703   FuncT Func;
704 };
705 
706 TEST_F(PassManagerTest, IndirectAnalysisInvalidation) {
707   FunctionAnalysisManager FAM;
708   ModuleAnalysisManager MAM;
709   int FunctionAnalysisRuns = 0, ModuleAnalysisRuns = 0,
710       IndirectAnalysisRuns = 0, DoublyIndirectAnalysisRuns = 0;
711   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
712   FAM.registerPass(
713       [&] { return TestIndirectFunctionAnalysis(IndirectAnalysisRuns, MAM); });
714   FAM.registerPass([&] {
715     return TestDoublyIndirectFunctionAnalysis(DoublyIndirectAnalysisRuns);
716   });
717 
718   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
719   MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
720   FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
721 
722   PassInstrumentationCallbacks PIC;
723   MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
724   FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
725 
726   int InstrCount = 0, FunctionCount = 0;
727   ModulePassManager MPM;
728   FunctionPassManager FPM;
729   // First just use the analysis to get the instruction count, and preserve
730   // everything.
731   FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
732     auto &DoublyIndirectResult =
733         AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
734     auto &IndirectResult = DoublyIndirectResult.IDep;
735     InstrCount += IndirectResult.FDep.InstructionCount;
736     FunctionCount += IndirectResult.MDep.FunctionCount;
737     return PreservedAnalyses::all();
738   }));
739   // Next, invalidate
740   //   - both analyses for "f",
741   //   - just the underlying (indirect) analysis for "g", and
742   //   - just the direct analysis for "h".
743   FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
744     auto &DoublyIndirectResult =
745         AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
746     auto &IndirectResult = DoublyIndirectResult.IDep;
747     InstrCount += IndirectResult.FDep.InstructionCount;
748     FunctionCount += IndirectResult.MDep.FunctionCount;
749     auto PA = PreservedAnalyses::none();
750     if (F.getName() == "g")
751       PA.preserve<TestFunctionAnalysis>();
752     else if (F.getName() == "h")
753       PA.preserve<TestIndirectFunctionAnalysis>();
754     return PA;
755   }));
756   // Finally, use the analysis again on each function, forcing re-computation
757   // for all of them.
758   FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
759     auto &DoublyIndirectResult =
760         AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
761     auto &IndirectResult = DoublyIndirectResult.IDep;
762     InstrCount += IndirectResult.FDep.InstructionCount;
763     FunctionCount += IndirectResult.MDep.FunctionCount;
764     return PreservedAnalyses::all();
765   }));
766 
767   // Create a second function pass manager. This will cause the module-level
768   // invalidation to occur, which will force yet another invalidation of the
769   // indirect function-level analysis as the module analysis it depends on gets
770   // invalidated.
771   FunctionPassManager FPM2;
772   FPM2.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
773     auto &DoublyIndirectResult =
774         AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
775     auto &IndirectResult = DoublyIndirectResult.IDep;
776     InstrCount += IndirectResult.FDep.InstructionCount;
777     FunctionCount += IndirectResult.MDep.FunctionCount;
778     return PreservedAnalyses::all();
779   }));
780 
781   // Add a requires pass to populate the module analysis and then our function
782   // pass pipeline.
783   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
784   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
785   // Now require the module analysis again (it will have been invalidated once)
786   // and then use it again from a function pass manager.
787   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
788   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM2)));
789   MPM.run(*M, MAM);
790 
791   // There are generally two possible runs for each of the three functions. But
792   // for one function, we only invalidate the indirect analysis so the base one
793   // only gets run five times.
794   EXPECT_EQ(5, FunctionAnalysisRuns);
795   // The module analysis pass should be run twice here.
796   EXPECT_EQ(2, ModuleAnalysisRuns);
797   // The indirect analysis is invalidated for each function (either directly or
798   // indirectly) and run twice for each.
799   EXPECT_EQ(9, IndirectAnalysisRuns);
800   EXPECT_EQ(9, DoublyIndirectAnalysisRuns);
801 
802   // There are five instructions in the module and we add the count four
803   // times.
804   EXPECT_EQ(5 * 4, InstrCount);
805 
806   // There are three functions and we count them four times for each of the
807   // three functions.
808   EXPECT_EQ(3 * 4 * 3, FunctionCount);
809 }
810 
811 // Run SimplifyCFGPass that makes CFG changes and reports PreservedAnalyses
812 // without CFGAnalyses. So the CFGChecker does not complain.
813 TEST_F(PassManagerTest, FunctionPassCFGChecker) {
814   LLVMContext Context;
815   // SimplifyCFG changes this function to
816   // define void @foo {next: ret void}
817   auto M = parseIR(Context, "define void @foo() {\n"
818                             "  br label %next\n"
819                             "next:\n"
820                             "  br label %exit\n"
821                             "exit:\n"
822                             "  ret void\n"
823                             "}\n");
824 
825   auto *F = M->getFunction("foo");
826   FunctionAnalysisManager FAM;
827   FunctionPassManager FPM;
828   PassInstrumentationCallbacks PIC;
829   StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ true);
830   SI.registerCallbacks(PIC, &FAM);
831   FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
832   FAM.registerPass([&] { return DominatorTreeAnalysis(); });
833   FAM.registerPass([&] { return AssumptionAnalysis(); });
834   FAM.registerPass([&] { return TargetIRAnalysis(); });
835 
836   FPM.addPass(SimplifyCFGPass());
837   FPM.run(*F, FAM);
838 }
839 
840 // FunctionPass that manually invalidates analyses and always returns
841 // PreservedAnalyses::all().
842 struct TestSimplifyCFGInvalidatingAnalysisPass
843     : PassInfoMixin<TestSimplifyCFGInvalidatingAnalysisPass> {
844   PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) {
845     // Run SimplifyCFG and if it changes CFG then invalidate the CFG analysis.
846     // This allows to return PreserveAnalysis::all().
847     PreservedAnalyses PA = CFGSimplifier.run(F, FAM);
848     FAM.invalidate(F, PA);
849     return PreservedAnalyses::all();
850   }
851 
852   SimplifyCFGPass CFGSimplifier;
853 };
854 
855 // Run TestSimplifyCFGInvalidatingAnalysisPass which changes CFG by running
856 // SimplifyCFGPass then manually invalidates analyses and always returns
857 // PreservedAnalyses::all(). CFGChecker does not complain because it resets
858 // its saved CFG snapshot when the analyses are invalidated manually.
859 TEST_F(PassManagerTest, FunctionPassCFGCheckerInvalidateAnalysis) {
860   LLVMContext Context;
861   // SimplifyCFG changes this function to
862   // define void @foo {next: ret void}
863   auto M = parseIR(Context, "define void @foo() {\n"
864                             "  br label %next\n"
865                             "next:\n"
866                             "  br label %exit\n"
867                             "exit:\n"
868                             "  ret void\n"
869                             "}\n");
870 
871   auto *F = M->getFunction("foo");
872   FunctionAnalysisManager FAM;
873   FunctionPassManager FPM;
874   PassInstrumentationCallbacks PIC;
875   StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ true);
876   SI.registerCallbacks(PIC, &FAM);
877   FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
878   FAM.registerPass([&] { return DominatorTreeAnalysis(); });
879   FAM.registerPass([&] { return AssumptionAnalysis(); });
880   FAM.registerPass([&] { return TargetIRAnalysis(); });
881 
882   FPM.addPass(TestSimplifyCFGInvalidatingAnalysisPass());
883   FPM.run(*F, FAM);
884 }
885 
886 // Wrap a FunctionPassManager running SimplifyCFG pass with another
887 // FunctionPassManager.
888 struct TestSimplifyCFGWrapperPass : PassInfoMixin<TestSimplifyCFGWrapperPass> {
889   TestSimplifyCFGWrapperPass(FunctionPassManager &InnerPM) : InnerPM(InnerPM) {}
890 
891   PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) {
892     // Here we simulate exactly what FunctionPassManager::run() does but
893     // instead of running all passes from InnerPM.Passes we run them in bulk
894     // by calling InnerPM.run().
895     PreservedAnalyses PA = PreservedAnalyses::all();
896     PassInstrumentation PI = FAM.getResult<PassInstrumentationAnalysis>(F);
897 
898     if (!PI.runBeforePass<Function>(InnerPM, F))
899       return PreservedAnalyses::all();
900 
901     PreservedAnalyses PassPA = InnerPM.run(F, FAM);
902     PI.runAfterPass(InnerPM, F, PassPA);
903     FAM.invalidate(F, PassPA);
904     PA.intersect(PassPA);
905     PA.preserveSet<AllAnalysesOn<Function>>();
906     return PA;
907   }
908 
909   FunctionPassManager &InnerPM;
910 };
911 
912 // Run TestSimplifyCFGWrapperPass which simulates behavior of
913 // FunctionPassManager::run() except that it runs all passes at once by calling
914 // an inner pass manager's passes with PassManager::run(). This is how one pass
915 // manager is expected to wrap another pass manager.
916 // SimplifyCFGPass, which is called by the inner pass manager, changes the CFG.
917 // The CFGChecker's AfterPassCallback, run right after SimplifyCFGPass, does not
918 // complain because CFGAnalyses is not in the PreservedAnalises set returned by
919 // SimplifyCFGPass. Then the CFG analysis is invalidated by the analysis manager
920 // according to the PreservedAnalises set. Further calls to CFGChecker's
921 // AfterPassCallback see that all analyses for the current function are
922 // preserved but there is no CFG snapshot available (i.e.
923 // AM.getCachedResult<PreservedCFGCheckerAnalysis>(F) returns nullptr).
924 TEST_F(PassManagerTest, FunctionPassCFGCheckerWrapped) {
925   LLVMContext Context;
926   // SimplifyCFG changes this function to
927   // define void @foo {next: ret void}
928   auto M = parseIR(Context, "define void @foo() {\n"
929                             "  br label %next\n"
930                             "next:\n"
931                             "  br label %exit\n"
932                             "exit:\n"
933                             "  ret void\n"
934                             "}\n");
935 
936   auto *F = M->getFunction("foo");
937   FunctionAnalysisManager FAM;
938   FunctionPassManager FPM;
939   PassInstrumentationCallbacks PIC;
940   StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ true);
941   SI.registerCallbacks(PIC, &FAM);
942   FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
943   FAM.registerPass([&] { return DominatorTreeAnalysis(); });
944   FAM.registerPass([&] { return AssumptionAnalysis(); });
945   FAM.registerPass([&] { return TargetIRAnalysis(); });
946 
947   FunctionPassManager InnerFPM;
948   InnerFPM.addPass(SimplifyCFGPass());
949 
950   FPM.addPass(TestSimplifyCFGWrapperPass(InnerFPM));
951   FPM.run(*F, FAM);
952 }
953 
954 #ifdef EXPENSIVE_CHECKS
955 
956 struct WrongFunctionPass : PassInfoMixin<WrongFunctionPass> {
957   PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) {
958     F.getEntryBlock().begin()->eraseFromParent();
959     return PreservedAnalyses::all();
960   }
961   static StringRef name() { return "WrongFunctionPass"; }
962 };
963 
964 TEST_F(PassManagerTest, FunctionAnalysisMissedInvalidation) {
965   LLVMContext Context;
966   auto M = parseIR(Context, "define void @foo() {\n"
967                             "  %a = add i32 0, 0\n"
968                             "  ret void\n"
969                             "}\n");
970 
971   FunctionAnalysisManager FAM;
972   PassInstrumentationCallbacks PIC;
973   StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ false);
974   SI.registerCallbacks(PIC, &FAM);
975   FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
976 
977   FunctionPassManager FPM;
978   FPM.addPass(WrongFunctionPass());
979 
980   auto *F = M->getFunction("foo");
981   EXPECT_DEATH(FPM.run(*F, FAM), "Function @foo changed by WrongFunctionPass without invalidating analyses");
982 }
983 
984 #endif
985 
986 }
987