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/AsmParser/Parser.h"
11 #include "llvm/IR/Function.h"
12 #include "llvm/IR/LLVMContext.h"
13 #include "llvm/IR/Module.h"
14 #include "llvm/Support/SourceMgr.h"
15 #include "gtest/gtest.h"
16 
17 using namespace llvm;
18 
19 namespace {
20 
21 class TestFunctionAnalysis : public AnalysisInfoMixin<TestFunctionAnalysis> {
22 public:
23   struct Result {
Result__anon504273110111::TestFunctionAnalysis::Result24     Result(int Count) : InstructionCount(Count) {}
25     int InstructionCount;
26   };
27 
TestFunctionAnalysis(int & Runs)28   TestFunctionAnalysis(int &Runs) : Runs(Runs) {}
29 
30   /// Run the analysis pass over the function and return a result.
run(Function & F,FunctionAnalysisManager & AM)31   Result run(Function &F, FunctionAnalysisManager &AM) {
32     ++Runs;
33     int Count = 0;
34     for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI)
35       for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
36            ++II)
37         ++Count;
38     return Result(Count);
39   }
40 
41 private:
42   friend AnalysisInfoMixin<TestFunctionAnalysis>;
43   static AnalysisKey Key;
44 
45   int &Runs;
46 };
47 
48 AnalysisKey TestFunctionAnalysis::Key;
49 
50 class TestModuleAnalysis : public AnalysisInfoMixin<TestModuleAnalysis> {
51 public:
52   struct Result {
Result__anon504273110111::TestModuleAnalysis::Result53     Result(int Count) : FunctionCount(Count) {}
54     int FunctionCount;
55   };
56 
TestModuleAnalysis(int & Runs)57   TestModuleAnalysis(int &Runs) : Runs(Runs) {}
58 
run(Module & M,ModuleAnalysisManager & AM)59   Result run(Module &M, ModuleAnalysisManager &AM) {
60     ++Runs;
61     int Count = 0;
62     for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
63       ++Count;
64     return Result(Count);
65   }
66 
67 private:
68   friend AnalysisInfoMixin<TestModuleAnalysis>;
69   static AnalysisKey Key;
70 
71   int &Runs;
72 };
73 
74 AnalysisKey TestModuleAnalysis::Key;
75 
76 struct TestModulePass : PassInfoMixin<TestModulePass> {
TestModulePass__anon504273110111::TestModulePass77   TestModulePass(int &RunCount) : RunCount(RunCount) {}
78 
run__anon504273110111::TestModulePass79   PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
80     ++RunCount;
81     return PreservedAnalyses::none();
82   }
83 
84   int &RunCount;
85 };
86 
87 struct TestPreservingModulePass : PassInfoMixin<TestPreservingModulePass> {
run__anon504273110111::TestPreservingModulePass88   PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
89     return PreservedAnalyses::all();
90   }
91 };
92 
93 struct TestFunctionPass : PassInfoMixin<TestFunctionPass> {
TestFunctionPass__anon504273110111::TestFunctionPass94   TestFunctionPass(int &RunCount, int &AnalyzedInstrCount,
95                    int &AnalyzedFunctionCount,
96                    bool OnlyUseCachedResults = false)
97       : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount),
98         AnalyzedFunctionCount(AnalyzedFunctionCount),
99         OnlyUseCachedResults(OnlyUseCachedResults) {}
100 
run__anon504273110111::TestFunctionPass101   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
102     ++RunCount;
103 
104     const ModuleAnalysisManager &MAM =
105         AM.getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
106     if (TestModuleAnalysis::Result *TMA =
107             MAM.getCachedResult<TestModuleAnalysis>(*F.getParent()))
108       AnalyzedFunctionCount += TMA->FunctionCount;
109 
110     if (OnlyUseCachedResults) {
111       // Hack to force the use of the cached interface.
112       if (TestFunctionAnalysis::Result *AR =
113               AM.getCachedResult<TestFunctionAnalysis>(F))
114         AnalyzedInstrCount += AR->InstructionCount;
115     } else {
116       // Typical path just runs the analysis as needed.
117       TestFunctionAnalysis::Result &AR = AM.getResult<TestFunctionAnalysis>(F);
118       AnalyzedInstrCount += AR.InstructionCount;
119     }
120 
121     return PreservedAnalyses::all();
122   }
123 
124   int &RunCount;
125   int &AnalyzedInstrCount;
126   int &AnalyzedFunctionCount;
127   bool OnlyUseCachedResults;
128 };
129 
130 // A test function pass that invalidates all function analyses for a function
131 // with a specific name.
132 struct TestInvalidationFunctionPass
133     : PassInfoMixin<TestInvalidationFunctionPass> {
TestInvalidationFunctionPass__anon504273110111::TestInvalidationFunctionPass134   TestInvalidationFunctionPass(StringRef FunctionName) : Name(FunctionName) {}
135 
run__anon504273110111::TestInvalidationFunctionPass136   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
137     return F.getName() == Name ? PreservedAnalyses::none()
138                                : PreservedAnalyses::all();
139   }
140 
141   StringRef Name;
142 };
143 
parseIR(LLVMContext & Context,const char * IR)144 std::unique_ptr<Module> parseIR(LLVMContext &Context, const char *IR) {
145   SMDiagnostic Err;
146   return parseAssemblyString(IR, Err, Context);
147 }
148 
149 class PassManagerTest : public ::testing::Test {
150 protected:
151   LLVMContext Context;
152   std::unique_ptr<Module> M;
153 
154 public:
PassManagerTest()155   PassManagerTest()
156       : M(parseIR(Context, "define void @f() {\n"
157                            "entry:\n"
158                            "  call void @g()\n"
159                            "  call void @h()\n"
160                            "  ret void\n"
161                            "}\n"
162                            "define void @g() {\n"
163                            "  ret void\n"
164                            "}\n"
165                            "define void @h() {\n"
166                            "  ret void\n"
167                            "}\n")) {}
168 };
169 
TEST(PreservedAnalysesTest,Basic)170 TEST(PreservedAnalysesTest, Basic) {
171   PreservedAnalyses PA1 = PreservedAnalyses();
172   {
173     auto PAC = PA1.getChecker<TestFunctionAnalysis>();
174     EXPECT_FALSE(PAC.preserved());
175     EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
176   }
177   {
178     auto PAC = PA1.getChecker<TestModuleAnalysis>();
179     EXPECT_FALSE(PAC.preserved());
180     EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Module>>());
181   }
182   auto PA2 = PreservedAnalyses::none();
183   {
184     auto PAC = PA2.getChecker<TestFunctionAnalysis>();
185     EXPECT_FALSE(PAC.preserved());
186     EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
187   }
188   auto PA3 = PreservedAnalyses::all();
189   {
190     auto PAC = PA3.getChecker<TestFunctionAnalysis>();
191     EXPECT_TRUE(PAC.preserved());
192     EXPECT_TRUE(PAC.preservedSet<AllAnalysesOn<Function>>());
193   }
194   PreservedAnalyses PA4 = PA1;
195   {
196     auto PAC = PA4.getChecker<TestFunctionAnalysis>();
197     EXPECT_FALSE(PAC.preserved());
198     EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
199   }
200   PA4 = PA3;
201   {
202     auto PAC = PA4.getChecker<TestFunctionAnalysis>();
203     EXPECT_TRUE(PAC.preserved());
204     EXPECT_TRUE(PAC.preservedSet<AllAnalysesOn<Function>>());
205   }
206   PA4 = std::move(PA2);
207   {
208     auto PAC = PA4.getChecker<TestFunctionAnalysis>();
209     EXPECT_FALSE(PAC.preserved());
210     EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
211   }
212   auto PA5 = PreservedAnalyses::allInSet<AllAnalysesOn<Function>>();
213   {
214     auto PAC = PA5.getChecker<TestFunctionAnalysis>();
215     EXPECT_FALSE(PAC.preserved());
216     EXPECT_TRUE(PAC.preservedSet<AllAnalysesOn<Function>>());
217     EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Module>>());
218   }
219 }
220 
TEST(PreservedAnalysesTest,Preserve)221 TEST(PreservedAnalysesTest, Preserve) {
222   auto PA = PreservedAnalyses::none();
223   PA.preserve<TestFunctionAnalysis>();
224   EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>().preserved());
225   EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>().preserved());
226   PA.preserve<TestModuleAnalysis>();
227   EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>().preserved());
228   EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>().preserved());
229 
230   // Redundant calls are fine.
231   PA.preserve<TestFunctionAnalysis>();
232   EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>().preserved());
233   EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>().preserved());
234 }
235 
TEST(PreservedAnalysesTest,PreserveSets)236 TEST(PreservedAnalysesTest, PreserveSets) {
237   auto PA = PreservedAnalyses::none();
238   PA.preserveSet<AllAnalysesOn<Function>>();
239   EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
240                   .preservedSet<AllAnalysesOn<Function>>());
241   EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>()
242                    .preservedSet<AllAnalysesOn<Module>>());
243   PA.preserveSet<AllAnalysesOn<Module>>();
244   EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
245                   .preservedSet<AllAnalysesOn<Function>>());
246   EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>()
247                   .preservedSet<AllAnalysesOn<Module>>());
248 
249   // Mixing is fine.
250   PA.preserve<TestFunctionAnalysis>();
251   EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
252                   .preservedSet<AllAnalysesOn<Function>>());
253   EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>()
254                   .preservedSet<AllAnalysesOn<Module>>());
255 
256   // Redundant calls are fine.
257   PA.preserveSet<AllAnalysesOn<Module>>();
258   EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
259                   .preservedSet<AllAnalysesOn<Function>>());
260   EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>()
261                   .preservedSet<AllAnalysesOn<Module>>());
262 }
263 
TEST(PreservedAnalysisTest,Intersect)264 TEST(PreservedAnalysisTest, Intersect) {
265   // Setup the initial sets.
266   auto PA1 = PreservedAnalyses::none();
267   PA1.preserve<TestFunctionAnalysis>();
268   PA1.preserveSet<AllAnalysesOn<Module>>();
269   auto PA2 = PreservedAnalyses::none();
270   PA2.preserve<TestFunctionAnalysis>();
271   PA2.preserveSet<AllAnalysesOn<Function>>();
272   PA2.preserve<TestModuleAnalysis>();
273   PA2.preserveSet<AllAnalysesOn<Module>>();
274   auto PA3 = PreservedAnalyses::none();
275   PA3.preserve<TestModuleAnalysis>();
276   PA3.preserveSet<AllAnalysesOn<Function>>();
277 
278   // Self intersection is a no-op.
279   auto Intersected = PA1;
280   Intersected.intersect(PA1);
281   EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
282   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
283                    .preservedSet<AllAnalysesOn<Function>>());
284   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
285   EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
286                   .preservedSet<AllAnalysesOn<Module>>());
287 
288   // Intersecting with all is a no-op.
289   Intersected.intersect(PreservedAnalyses::all());
290   EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
291   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
292                    .preservedSet<AllAnalysesOn<Function>>());
293   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
294   EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
295                   .preservedSet<AllAnalysesOn<Module>>());
296 
297   // Intersecting a narrow set with a more broad set is the narrow set.
298   Intersected.intersect(PA2);
299   EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
300   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
301                    .preservedSet<AllAnalysesOn<Function>>());
302   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
303   EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
304                   .preservedSet<AllAnalysesOn<Module>>());
305 
306   // Intersecting a broad set with a more narrow set is the narrow set.
307   Intersected = PA2;
308   Intersected.intersect(PA1);
309   EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
310   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
311                    .preservedSet<AllAnalysesOn<Function>>());
312   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
313   EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
314                   .preservedSet<AllAnalysesOn<Module>>());
315 
316   // Intersecting with empty clears.
317   Intersected.intersect(PreservedAnalyses::none());
318   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
319   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
320                    .preservedSet<AllAnalysesOn<Function>>());
321   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
322   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>()
323                    .preservedSet<AllAnalysesOn<Module>>());
324 
325   // Intersecting non-overlapping clears.
326   Intersected = PA1;
327   Intersected.intersect(PA3);
328   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
329   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
330                    .preservedSet<AllAnalysesOn<Function>>());
331   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
332   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>()
333                    .preservedSet<AllAnalysesOn<Module>>());
334 
335   // Intersecting with moves works in when there is storage on both sides.
336   Intersected = PA1;
337   auto Tmp = PA2;
338   Intersected.intersect(std::move(Tmp));
339   EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
340   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
341                    .preservedSet<AllAnalysesOn<Function>>());
342   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
343   EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
344                   .preservedSet<AllAnalysesOn<Module>>());
345 
346   // Intersecting with move works for incoming all and existing all.
347   auto Tmp2 = PreservedAnalyses::all();
348   Intersected.intersect(std::move(Tmp2));
349   EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
350   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
351                    .preservedSet<AllAnalysesOn<Function>>());
352   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
353   EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
354                   .preservedSet<AllAnalysesOn<Module>>());
355   Intersected = PreservedAnalyses::all();
356   auto Tmp3 = PA1;
357   Intersected.intersect(std::move(Tmp3));
358   EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
359   EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
360                    .preservedSet<AllAnalysesOn<Function>>());
361   EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
362   EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
363                   .preservedSet<AllAnalysesOn<Module>>());
364 }
365 
TEST(PreservedAnalysisTest,Abandon)366 TEST(PreservedAnalysisTest, Abandon) {
367   auto PA = PreservedAnalyses::none();
368 
369   // We can abandon things after they are preserved.
370   PA.preserve<TestFunctionAnalysis>();
371   PA.abandon<TestFunctionAnalysis>();
372   EXPECT_FALSE(PA.getChecker<TestFunctionAnalysis>().preserved());
373 
374   // Repeated is fine, and abandoning if they were never preserved is fine.
375   PA.abandon<TestFunctionAnalysis>();
376   EXPECT_FALSE(PA.getChecker<TestFunctionAnalysis>().preserved());
377   PA.abandon<TestModuleAnalysis>();
378   EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>().preserved());
379 
380   // Even if the sets are preserved, the abandoned analyses' checker won't
381   // return true for those sets.
382   PA.preserveSet<AllAnalysesOn<Function>>();
383   PA.preserveSet<AllAnalysesOn<Module>>();
384   EXPECT_FALSE(PA.getChecker<TestFunctionAnalysis>()
385                    .preservedSet<AllAnalysesOn<Function>>());
386   EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>()
387                    .preservedSet<AllAnalysesOn<Module>>());
388 
389   // But an arbitrary (opaque) analysis will still observe the sets as
390   // preserved. This also checks that we can use an explicit ID rather than
391   // a type.
392   AnalysisKey FakeKey, *FakeID = &FakeKey;
393   EXPECT_TRUE(PA.getChecker(FakeID).preservedSet<AllAnalysesOn<Function>>());
394   EXPECT_TRUE(PA.getChecker(FakeID).preservedSet<AllAnalysesOn<Module>>());
395 }
396 
TEST_F(PassManagerTest,Basic)397 TEST_F(PassManagerTest, Basic) {
398   FunctionAnalysisManager FAM(/*DebugLogging*/ true);
399   int FunctionAnalysisRuns = 0;
400   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
401 
402   ModuleAnalysisManager MAM(/*DebugLogging*/ true);
403   int ModuleAnalysisRuns = 0;
404   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
405   MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
406   FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
407 
408   MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
409   FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
410 
411   ModulePassManager MPM;
412 
413   // Count the runs over a Function.
414   int FunctionPassRunCount1 = 0;
415   int AnalyzedInstrCount1 = 0;
416   int AnalyzedFunctionCount1 = 0;
417   {
418     // Pointless scoped copy to test move assignment.
419     ModulePassManager NestedMPM(/*DebugLogging*/ true);
420     FunctionPassManager FPM;
421     {
422       // Pointless scope to test move assignment.
423       FunctionPassManager NestedFPM(/*DebugLogging*/ true);
424       NestedFPM.addPass(TestFunctionPass(
425           FunctionPassRunCount1, AnalyzedInstrCount1, AnalyzedFunctionCount1));
426       FPM = std::move(NestedFPM);
427     }
428     NestedMPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
429     MPM = std::move(NestedMPM);
430   }
431 
432   // Count the runs over a module.
433   int ModulePassRunCount = 0;
434   MPM.addPass(TestModulePass(ModulePassRunCount));
435 
436   // Count the runs over a Function in a separate manager.
437   int FunctionPassRunCount2 = 0;
438   int AnalyzedInstrCount2 = 0;
439   int AnalyzedFunctionCount2 = 0;
440   {
441     FunctionPassManager FPM(/*DebugLogging*/ true);
442     FPM.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2,
443                                  AnalyzedFunctionCount2));
444     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
445   }
446 
447   // A third function pass manager but with only preserving intervening passes
448   // and with a function pass that invalidates exactly one analysis.
449   MPM.addPass(TestPreservingModulePass());
450   int FunctionPassRunCount3 = 0;
451   int AnalyzedInstrCount3 = 0;
452   int AnalyzedFunctionCount3 = 0;
453   {
454     FunctionPassManager FPM(/*DebugLogging*/ true);
455     FPM.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3,
456                                  AnalyzedFunctionCount3));
457     FPM.addPass(TestInvalidationFunctionPass("f"));
458     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
459   }
460 
461   // A fourth function pass manager but with only preserving intervening
462   // passes but triggering the module analysis.
463   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
464   int FunctionPassRunCount4 = 0;
465   int AnalyzedInstrCount4 = 0;
466   int AnalyzedFunctionCount4 = 0;
467   {
468     FunctionPassManager FPM;
469     FPM.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4,
470                                  AnalyzedFunctionCount4));
471     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
472   }
473 
474   // A fifth function pass manager which invalidates one function first but
475   // uses only cached results.
476   int FunctionPassRunCount5 = 0;
477   int AnalyzedInstrCount5 = 0;
478   int AnalyzedFunctionCount5 = 0;
479   {
480     FunctionPassManager FPM(/*DebugLogging*/ true);
481     FPM.addPass(TestInvalidationFunctionPass("f"));
482     FPM.addPass(TestFunctionPass(FunctionPassRunCount5, AnalyzedInstrCount5,
483                                  AnalyzedFunctionCount5,
484                                  /*OnlyUseCachedResults=*/true));
485     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
486   }
487 
488   MPM.run(*M, MAM);
489 
490   // Validate module pass counters.
491   EXPECT_EQ(1, ModulePassRunCount);
492 
493   // Validate all function pass counter sets are the same.
494   EXPECT_EQ(3, FunctionPassRunCount1);
495   EXPECT_EQ(5, AnalyzedInstrCount1);
496   EXPECT_EQ(0, AnalyzedFunctionCount1);
497   EXPECT_EQ(3, FunctionPassRunCount2);
498   EXPECT_EQ(5, AnalyzedInstrCount2);
499   EXPECT_EQ(0, AnalyzedFunctionCount2);
500   EXPECT_EQ(3, FunctionPassRunCount3);
501   EXPECT_EQ(5, AnalyzedInstrCount3);
502   EXPECT_EQ(0, AnalyzedFunctionCount3);
503   EXPECT_EQ(3, FunctionPassRunCount4);
504   EXPECT_EQ(5, AnalyzedInstrCount4);
505   EXPECT_EQ(9, AnalyzedFunctionCount4);
506   EXPECT_EQ(3, FunctionPassRunCount5);
507   EXPECT_EQ(2, AnalyzedInstrCount5); // Only 'g' and 'h' were cached.
508   EXPECT_EQ(9, AnalyzedFunctionCount5);
509 
510   // Validate the analysis counters:
511   //   first run over 3 functions, then module pass invalidates
512   //   second run over 3 functions, nothing invalidates
513   //   third run over 0 functions, but 1 function invalidated
514   //   fourth run over 1 function
515   //   fifth run invalidates 1 function first, but runs over 0 functions
516   EXPECT_EQ(7, FunctionAnalysisRuns);
517 
518   EXPECT_EQ(1, ModuleAnalysisRuns);
519 }
520 
521 // A customized pass manager that passes extra arguments through the
522 // infrastructure.
523 typedef AnalysisManager<Function, int> CustomizedAnalysisManager;
524 typedef PassManager<Function, CustomizedAnalysisManager, int, int &>
525     CustomizedPassManager;
526 
527 class CustomizedAnalysis : public AnalysisInfoMixin<CustomizedAnalysis> {
528 public:
529   struct Result {
Result__anon504273110111::CustomizedAnalysis::Result530     Result(int I) : I(I) {}
531     int I;
532   };
533 
run(Function & F,CustomizedAnalysisManager & AM,int I)534   Result run(Function &F, CustomizedAnalysisManager &AM, int I) {
535     return Result(I);
536   }
537 
538 private:
539   friend AnalysisInfoMixin<CustomizedAnalysis>;
540   static AnalysisKey Key;
541 };
542 
543 AnalysisKey CustomizedAnalysis::Key;
544 
545 struct CustomizedPass : PassInfoMixin<CustomizedPass> {
546   std::function<void(CustomizedAnalysis::Result &, int &)> Callback;
547 
548   template <typename CallbackT>
CustomizedPass__anon504273110111::CustomizedPass549   CustomizedPass(CallbackT Callback) : Callback(Callback) {}
550 
run__anon504273110111::CustomizedPass551   PreservedAnalyses run(Function &F, CustomizedAnalysisManager &AM, int I,
552                         int &O) {
553     Callback(AM.getResult<CustomizedAnalysis>(F, I), O);
554     return PreservedAnalyses::none();
555   }
556 };
557 
TEST_F(PassManagerTest,CustomizedPassManagerArgs)558 TEST_F(PassManagerTest, CustomizedPassManagerArgs) {
559   CustomizedAnalysisManager AM;
560   AM.registerPass([&] { return CustomizedAnalysis(); });
561   PassInstrumentationCallbacks PIC;
562   AM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
563 
564   CustomizedPassManager PM;
565 
566   // Add an instance of the customized pass that just accumulates the input
567   // after it is round-tripped through the analysis.
568   int Result = 0;
569   PM.addPass(
570       CustomizedPass([](CustomizedAnalysis::Result &R, int &O) { O += R.I; }));
571 
572   // Run this over every function with the input of 42.
573   for (Function &F : *M)
574     PM.run(F, AM, 42, Result);
575 
576   // And ensure that we accumulated the correct result.
577   EXPECT_EQ(42 * (int)M->size(), Result);
578 }
579 
580 /// A test analysis pass which caches in its result another analysis pass and
581 /// uses it to serve queries. This requires the result to invalidate itself
582 /// when its dependency is invalidated.
583 struct TestIndirectFunctionAnalysis
584     : public AnalysisInfoMixin<TestIndirectFunctionAnalysis> {
585   struct Result {
Result__anon504273110111::TestIndirectFunctionAnalysis::Result586     Result(TestFunctionAnalysis::Result &FDep, TestModuleAnalysis::Result &MDep)
587         : FDep(FDep), MDep(MDep) {}
588     TestFunctionAnalysis::Result &FDep;
589     TestModuleAnalysis::Result &MDep;
590 
invalidate__anon504273110111::TestIndirectFunctionAnalysis::Result591     bool invalidate(Function &F, const PreservedAnalyses &PA,
592                     FunctionAnalysisManager::Invalidator &Inv) {
593       auto PAC = PA.getChecker<TestIndirectFunctionAnalysis>();
594       return !(PAC.preserved() ||
595                PAC.preservedSet<AllAnalysesOn<Function>>()) ||
596              Inv.invalidate<TestFunctionAnalysis>(F, PA);
597     }
598   };
599 
TestIndirectFunctionAnalysis__anon504273110111::TestIndirectFunctionAnalysis600   TestIndirectFunctionAnalysis(int &Runs) : Runs(Runs) {}
601 
602   /// Run the analysis pass over the function and return a result.
run__anon504273110111::TestIndirectFunctionAnalysis603   Result run(Function &F, FunctionAnalysisManager &AM) {
604     ++Runs;
605     auto &FDep = AM.getResult<TestFunctionAnalysis>(F);
606     auto &Proxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
607     const ModuleAnalysisManager &MAM = Proxy.getManager();
608     // For the test, we insist that the module analysis starts off in the
609     // cache.
610     auto &MDep = *MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
611     // And register the dependency as module analysis dependencies have to be
612     // pre-registered on the proxy.
613     Proxy.registerOuterAnalysisInvalidation<TestModuleAnalysis,
614                                             TestIndirectFunctionAnalysis>();
615     return Result(FDep, MDep);
616   }
617 
618 private:
619   friend AnalysisInfoMixin<TestIndirectFunctionAnalysis>;
620   static AnalysisKey Key;
621 
622   int &Runs;
623 };
624 
625 AnalysisKey TestIndirectFunctionAnalysis::Key;
626 
627 /// A test analysis pass which chaches in its result the result from the above
628 /// indirect analysis pass.
629 ///
630 /// This allows us to ensure that whenever an analysis pass is invalidated due
631 /// to dependencies (especially dependencies across IR units that trigger
632 /// asynchronous invalidation) we correctly detect that this may in turn cause
633 /// other analysis to be invalidated.
634 struct TestDoublyIndirectFunctionAnalysis
635     : public AnalysisInfoMixin<TestDoublyIndirectFunctionAnalysis> {
636   struct Result {
Result__anon504273110111::TestDoublyIndirectFunctionAnalysis::Result637     Result(TestIndirectFunctionAnalysis::Result &IDep) : IDep(IDep) {}
638     TestIndirectFunctionAnalysis::Result &IDep;
639 
invalidate__anon504273110111::TestDoublyIndirectFunctionAnalysis::Result640     bool invalidate(Function &F, const PreservedAnalyses &PA,
641                     FunctionAnalysisManager::Invalidator &Inv) {
642       auto PAC = PA.getChecker<TestDoublyIndirectFunctionAnalysis>();
643       return !(PAC.preserved() ||
644                PAC.preservedSet<AllAnalysesOn<Function>>()) ||
645              Inv.invalidate<TestIndirectFunctionAnalysis>(F, PA);
646     }
647   };
648 
TestDoublyIndirectFunctionAnalysis__anon504273110111::TestDoublyIndirectFunctionAnalysis649   TestDoublyIndirectFunctionAnalysis(int &Runs) : Runs(Runs) {}
650 
651   /// Run the analysis pass over the function and return a result.
run__anon504273110111::TestDoublyIndirectFunctionAnalysis652   Result run(Function &F, FunctionAnalysisManager &AM) {
653     ++Runs;
654     auto &IDep = AM.getResult<TestIndirectFunctionAnalysis>(F);
655     return Result(IDep);
656   }
657 
658 private:
659   friend AnalysisInfoMixin<TestDoublyIndirectFunctionAnalysis>;
660   static AnalysisKey Key;
661 
662   int &Runs;
663 };
664 
665 AnalysisKey TestDoublyIndirectFunctionAnalysis::Key;
666 
667 struct LambdaPass : public PassInfoMixin<LambdaPass> {
668   using FuncT = std::function<PreservedAnalyses(Function &, FunctionAnalysisManager &)>;
669 
LambdaPass__anon504273110111::LambdaPass670   LambdaPass(FuncT Func) : Func(std::move(Func)) {}
671 
run__anon504273110111::LambdaPass672   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
673     return Func(F, AM);
674   }
675 
676   FuncT Func;
677 };
678 
TEST_F(PassManagerTest,IndirectAnalysisInvalidation)679 TEST_F(PassManagerTest, IndirectAnalysisInvalidation) {
680   FunctionAnalysisManager FAM(/*DebugLogging*/ true);
681   int FunctionAnalysisRuns = 0, ModuleAnalysisRuns = 0,
682       IndirectAnalysisRuns = 0, DoublyIndirectAnalysisRuns = 0;
683   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
684   FAM.registerPass(
685       [&] { return TestIndirectFunctionAnalysis(IndirectAnalysisRuns); });
686   FAM.registerPass([&] {
687     return TestDoublyIndirectFunctionAnalysis(DoublyIndirectAnalysisRuns);
688   });
689 
690   ModuleAnalysisManager MAM(/*DebugLogging*/ true);
691   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
692   MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
693   FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
694 
695   PassInstrumentationCallbacks PIC;
696   MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
697   FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
698 
699   int InstrCount = 0, FunctionCount = 0;
700   ModulePassManager MPM(/*DebugLogging*/ true);
701   FunctionPassManager FPM(/*DebugLogging*/ true);
702   // First just use the analysis to get the instruction count, and preserve
703   // everything.
704   FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
705     auto &DoublyIndirectResult =
706         AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
707     auto &IndirectResult = DoublyIndirectResult.IDep;
708     InstrCount += IndirectResult.FDep.InstructionCount;
709     FunctionCount += IndirectResult.MDep.FunctionCount;
710     return PreservedAnalyses::all();
711   }));
712   // Next, invalidate
713   //   - both analyses for "f",
714   //   - just the underlying (indirect) analysis for "g", and
715   //   - just the direct analysis for "h".
716   FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
717     auto &DoublyIndirectResult =
718         AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
719     auto &IndirectResult = DoublyIndirectResult.IDep;
720     InstrCount += IndirectResult.FDep.InstructionCount;
721     FunctionCount += IndirectResult.MDep.FunctionCount;
722     auto PA = PreservedAnalyses::none();
723     if (F.getName() == "g")
724       PA.preserve<TestFunctionAnalysis>();
725     else if (F.getName() == "h")
726       PA.preserve<TestIndirectFunctionAnalysis>();
727     return PA;
728   }));
729   // Finally, use the analysis again on each function, forcing re-computation
730   // for all of them.
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 
740   // Create a second function pass manager. This will cause the module-level
741   // invalidation to occur, which will force yet another invalidation of the
742   // indirect function-level analysis as the module analysis it depends on gets
743   // invalidated.
744   FunctionPassManager FPM2(/*DebugLogging*/ true);
745   FPM2.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
746     auto &DoublyIndirectResult =
747         AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
748     auto &IndirectResult = DoublyIndirectResult.IDep;
749     InstrCount += IndirectResult.FDep.InstructionCount;
750     FunctionCount += IndirectResult.MDep.FunctionCount;
751     return PreservedAnalyses::all();
752   }));
753 
754   // Add a requires pass to populate the module analysis and then our function
755   // pass pipeline.
756   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
757   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
758   // Now require the module analysis again (it will have been invalidated once)
759   // and then use it again from a function pass manager.
760   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
761   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM2)));
762   MPM.run(*M, MAM);
763 
764   // There are generally two possible runs for each of the three functions. But
765   // for one function, we only invalidate the indirect analysis so the base one
766   // only gets run five times.
767   EXPECT_EQ(5, FunctionAnalysisRuns);
768   // The module analysis pass should be run twice here.
769   EXPECT_EQ(2, ModuleAnalysisRuns);
770   // The indirect analysis is invalidated for each function (either directly or
771   // indirectly) and run twice for each.
772   EXPECT_EQ(9, IndirectAnalysisRuns);
773   EXPECT_EQ(9, DoublyIndirectAnalysisRuns);
774 
775   // There are five instructions in the module and we add the count four
776   // times.
777   EXPECT_EQ(5 * 4, InstrCount);
778 
779   // There are three functions and we count them four times for each of the
780   // three functions.
781   EXPECT_EQ(3 * 4 * 3, FunctionCount);
782 }
783 }
784