1 //===- CGSCCPassManagerTest.cpp -------------------------------------------===//
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/Analysis/CGSCCPassManager.h"
10 #include "llvm/Analysis/LazyCallGraph.h"
11 #include "llvm/Analysis/TargetLibraryInfo.h"
12 #include "llvm/AsmParser/Parser.h"
13 #include "llvm/IR/Function.h"
14 #include "llvm/IR/InstIterator.h"
15 #include "llvm/IR/LLVMContext.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/IR/PassManager.h"
18 #include "llvm/Support/SourceMgr.h"
19 #include "gtest/gtest.h"
20 
21 using namespace llvm;
22 
23 namespace {
24 
25 class TestModuleAnalysis : public AnalysisInfoMixin<TestModuleAnalysis> {
26 public:
27   struct Result {
28     Result(int Count) : FunctionCount(Count) {}
29     int FunctionCount;
30     bool invalidate(Module &, const PreservedAnalyses &PA,
31                     ModuleAnalysisManager::Invalidator &) {
32       // Check whether the analysis or all analyses on modules have been
33       // preserved.
34       auto PAC = PA.getChecker<TestModuleAnalysis>();
35       return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Module>>());
36     }
37   };
38 
39   TestModuleAnalysis(int &Runs) : Runs(Runs) {}
40 
41   Result run(Module &M, ModuleAnalysisManager &AM) {
42     ++Runs;
43     return Result(M.size());
44   }
45 
46 private:
47   friend AnalysisInfoMixin<TestModuleAnalysis>;
48   static AnalysisKey Key;
49 
50   int &Runs;
51 };
52 
53 AnalysisKey TestModuleAnalysis::Key;
54 
55 class TestSCCAnalysis : public AnalysisInfoMixin<TestSCCAnalysis> {
56 public:
57   struct Result {
58     Result(int Count) : FunctionCount(Count) {}
59     int FunctionCount;
60     bool invalidate(LazyCallGraph::SCC &, const PreservedAnalyses &PA,
61                     CGSCCAnalysisManager::Invalidator &) {
62       // Check whether the analysis or all analyses on SCCs have been
63       // preserved.
64       auto PAC = PA.getChecker<TestSCCAnalysis>();
65       return !(PAC.preserved() ||
66                PAC.preservedSet<AllAnalysesOn<LazyCallGraph::SCC>>());
67     }
68   };
69 
70   TestSCCAnalysis(int &Runs) : Runs(Runs) {}
71 
72   Result run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &) {
73     ++Runs;
74     return Result(C.size());
75   }
76 
77 private:
78   friend AnalysisInfoMixin<TestSCCAnalysis>;
79   static AnalysisKey Key;
80 
81   int &Runs;
82 };
83 
84 AnalysisKey TestSCCAnalysis::Key;
85 
86 class TestFunctionAnalysis : public AnalysisInfoMixin<TestFunctionAnalysis> {
87 public:
88   struct Result {
89     Result(int Count) : InstructionCount(Count) {}
90     int InstructionCount;
91     bool invalidate(Function &, const PreservedAnalyses &PA,
92                     FunctionAnalysisManager::Invalidator &) {
93       // Check whether the analysis or all analyses on functions have been
94       // preserved.
95       auto PAC = PA.getChecker<TestFunctionAnalysis>();
96       return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>());
97     }
98   };
99 
100   TestFunctionAnalysis(int &Runs) : Runs(Runs) {}
101 
102   Result run(Function &F, FunctionAnalysisManager &AM) {
103     ++Runs;
104     int Count = 0;
105     for (Instruction &I : instructions(F)) {
106       (void)I;
107       ++Count;
108     }
109     return Result(Count);
110   }
111 
112 private:
113   friend AnalysisInfoMixin<TestFunctionAnalysis>;
114   static AnalysisKey Key;
115 
116   int &Runs;
117 };
118 
119 AnalysisKey TestFunctionAnalysis::Key;
120 
121 class TestImmutableFunctionAnalysis
122     : public AnalysisInfoMixin<TestImmutableFunctionAnalysis> {
123 public:
124   struct Result {
125     bool invalidate(Function &, const PreservedAnalyses &,
126                     FunctionAnalysisManager::Invalidator &) {
127       return false;
128     }
129   };
130 
131   TestImmutableFunctionAnalysis(int &Runs) : Runs(Runs) {}
132 
133   Result run(Function &F, FunctionAnalysisManager &AM) {
134     ++Runs;
135     return Result();
136   }
137 
138 private:
139   friend AnalysisInfoMixin<TestImmutableFunctionAnalysis>;
140   static AnalysisKey Key;
141 
142   int &Runs;
143 };
144 
145 AnalysisKey TestImmutableFunctionAnalysis::Key;
146 
147 struct LambdaModulePass : public PassInfoMixin<LambdaModulePass> {
148   template <typename T>
149   LambdaModulePass(T &&Arg) : Func(std::forward<T>(Arg)) {}
150 
151   PreservedAnalyses run(Module &F, ModuleAnalysisManager &AM) {
152     return Func(F, AM);
153   }
154 
155   std::function<PreservedAnalyses(Module &, ModuleAnalysisManager &)> Func;
156 };
157 
158 struct LambdaSCCPass : public PassInfoMixin<LambdaSCCPass> {
159   template <typename T> LambdaSCCPass(T &&Arg) : Func(std::forward<T>(Arg)) {}
160 
161   PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
162                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
163     return Func(C, AM, CG, UR);
164   }
165 
166   std::function<PreservedAnalyses(LazyCallGraph::SCC &, CGSCCAnalysisManager &,
167                                   LazyCallGraph &, CGSCCUpdateResult &)>
168       Func;
169 };
170 
171 struct LambdaFunctionPass : public PassInfoMixin<LambdaFunctionPass> {
172   template <typename T>
173   LambdaFunctionPass(T &&Arg) : Func(std::forward<T>(Arg)) {}
174 
175   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
176     return Func(F, AM);
177   }
178 
179   std::function<PreservedAnalyses(Function &, FunctionAnalysisManager &)> Func;
180 };
181 
182 std::unique_ptr<Module> parseIR(const char *IR) {
183   // We just use a static context here. This is never called from multiple
184   // threads so it is harmless no matter how it is implemented. We just need
185   // the context to outlive the module which it does.
186   static LLVMContext C;
187   SMDiagnostic Err;
188   return parseAssemblyString(IR, Err, C);
189 }
190 
191 class CGSCCPassManagerTest : public ::testing::Test {
192 protected:
193   LLVMContext Context;
194   FunctionAnalysisManager FAM;
195   CGSCCAnalysisManager CGAM;
196   ModuleAnalysisManager MAM;
197 
198   std::unique_ptr<Module> M;
199 
200 public:
201   CGSCCPassManagerTest()
202       : FAM(/*DebugLogging*/ true), CGAM(/*DebugLogging*/ true),
203         MAM(/*DebugLogging*/ true),
204         M(parseIR(
205             // Define a module with the following call graph, where calls go
206             // out the bottom of nodes and enter the top:
207             //
208             // f
209             // |\   _
210             // | \ / |
211             // g  h1 |
212             // |  |  |
213             // |  h2 |
214             // |  |  |
215             // |  h3 |
216             // | / \_/
217             // |/
218             // x
219             //
220             "define void @f() {\n"
221             "entry:\n"
222             "  call void @g()\n"
223             "  call void @h1()\n"
224             "  ret void\n"
225             "}\n"
226             "define void @g() {\n"
227             "entry:\n"
228             "  call void @g()\n"
229             "  call void @x()\n"
230             "  ret void\n"
231             "}\n"
232             "define void @h1() {\n"
233             "entry:\n"
234             "  call void @h2()\n"
235             "  ret void\n"
236             "}\n"
237             "define void @h2() {\n"
238             "entry:\n"
239             "  call void @h3()\n"
240             "  call void @x()\n"
241             "  ret void\n"
242             "}\n"
243             "define void @h3() {\n"
244             "entry:\n"
245             "  call void @h1()\n"
246             "  ret void\n"
247             "}\n"
248             "define void @x() {\n"
249             "entry:\n"
250             "  ret void\n"
251             "}\n")) {
252     FAM.registerPass([&] { return TargetLibraryAnalysis(); });
253     MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
254     MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
255 
256     // Register required pass instrumentation analysis.
257     MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
258     CGAM.registerPass([&] { return PassInstrumentationAnalysis(); });
259     FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
260 
261     // Cross-register proxies.
262     MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
263     CGAM.registerPass([&] { return FunctionAnalysisManagerCGSCCProxy(); });
264     CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
265     FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
266     FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
267   }
268 };
269 
270 TEST_F(CGSCCPassManagerTest, Basic) {
271   int FunctionAnalysisRuns = 0;
272   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
273   int ImmutableFunctionAnalysisRuns = 0;
274   FAM.registerPass([&] {
275     return TestImmutableFunctionAnalysis(ImmutableFunctionAnalysisRuns);
276   });
277 
278   int SCCAnalysisRuns = 0;
279   CGAM.registerPass([&] { return TestSCCAnalysis(SCCAnalysisRuns); });
280 
281   int ModuleAnalysisRuns = 0;
282   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
283 
284   ModulePassManager MPM(/*DebugLogging*/ true);
285   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
286 
287   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
288   FunctionPassManager FPM1(/*DebugLogging*/ true);
289   int FunctionPassRunCount1 = 0;
290   FPM1.addPass(LambdaFunctionPass([&](Function &, FunctionAnalysisManager &) {
291     ++FunctionPassRunCount1;
292     return PreservedAnalyses::none();
293   }));
294   CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
295 
296   int SCCPassRunCount1 = 0;
297   int AnalyzedInstrCount1 = 0;
298   int AnalyzedSCCFunctionCount1 = 0;
299   int AnalyzedModuleFunctionCount1 = 0;
300   CGPM1.addPass(
301       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
302                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
303         ++SCCPassRunCount1;
304 
305         const ModuleAnalysisManager &MAM =
306             AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG).getManager();
307         FunctionAnalysisManager &FAM =
308             AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
309         if (TestModuleAnalysis::Result *TMA =
310                 MAM.getCachedResult<TestModuleAnalysis>(
311                     *C.begin()->getFunction().getParent()))
312           AnalyzedModuleFunctionCount1 += TMA->FunctionCount;
313 
314         TestSCCAnalysis::Result &AR = AM.getResult<TestSCCAnalysis>(C, CG);
315         AnalyzedSCCFunctionCount1 += AR.FunctionCount;
316         for (LazyCallGraph::Node &N : C) {
317           TestFunctionAnalysis::Result &FAR =
318               FAM.getResult<TestFunctionAnalysis>(N.getFunction());
319           AnalyzedInstrCount1 += FAR.InstructionCount;
320 
321           // Just ensure we get the immutable results.
322           (void)FAM.getResult<TestImmutableFunctionAnalysis>(N.getFunction());
323         }
324 
325         return PreservedAnalyses::all();
326       }));
327 
328   FunctionPassManager FPM2(/*DebugLogging*/ true);
329   int FunctionPassRunCount2 = 0;
330   FPM2.addPass(LambdaFunctionPass([&](Function &, FunctionAnalysisManager &) {
331     ++FunctionPassRunCount2;
332     return PreservedAnalyses::none();
333   }));
334   CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
335 
336   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
337 
338   FunctionPassManager FPM3(/*DebugLogging*/ true);
339   int FunctionPassRunCount3 = 0;
340   FPM3.addPass(LambdaFunctionPass([&](Function &, FunctionAnalysisManager &) {
341     ++FunctionPassRunCount3;
342     return PreservedAnalyses::none();
343   }));
344   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM3)));
345 
346   MPM.run(*M, MAM);
347 
348   EXPECT_EQ(4, SCCPassRunCount1);
349   EXPECT_EQ(6, FunctionPassRunCount1);
350   EXPECT_EQ(6, FunctionPassRunCount2);
351   EXPECT_EQ(6, FunctionPassRunCount3);
352 
353   EXPECT_EQ(1, ModuleAnalysisRuns);
354   EXPECT_EQ(4, SCCAnalysisRuns);
355   EXPECT_EQ(6, FunctionAnalysisRuns);
356   EXPECT_EQ(6, ImmutableFunctionAnalysisRuns);
357 
358   EXPECT_EQ(14, AnalyzedInstrCount1);
359   EXPECT_EQ(6, AnalyzedSCCFunctionCount1);
360   EXPECT_EQ(4 * 6, AnalyzedModuleFunctionCount1);
361 }
362 
363 // Test that an SCC pass which fails to preserve a module analysis does in fact
364 // invalidate that module analysis.
365 TEST_F(CGSCCPassManagerTest, TestSCCPassInvalidatesModuleAnalysis) {
366   int ModuleAnalysisRuns = 0;
367   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
368 
369   ModulePassManager MPM(/*DebugLogging*/ true);
370   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
371 
372   // The first CGSCC run we preserve everything and make sure that works and
373   // the module analysis is available in the second CGSCC run from the one
374   // required module pass above.
375   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
376   int CountFoundModuleAnalysis1 = 0;
377   CGPM1.addPass(
378       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
379                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
380         const auto &MAM =
381             AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG).getManager();
382         auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(
383             *C.begin()->getFunction().getParent());
384 
385         if (TMA)
386           ++CountFoundModuleAnalysis1;
387 
388         return PreservedAnalyses::all();
389       }));
390   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
391 
392   // The second CGSCC run checks that the module analysis got preserved the
393   // previous time and in one SCC fails to preserve it.
394   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
395   int CountFoundModuleAnalysis2 = 0;
396   CGPM2.addPass(
397       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
398                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
399         const auto &MAM =
400             AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG).getManager();
401         auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(
402             *C.begin()->getFunction().getParent());
403 
404         if (TMA)
405           ++CountFoundModuleAnalysis2;
406 
407         // Only fail to preserve analyses on one SCC and make sure that gets
408         // propagated.
409         return C.getName() == "(g)" ? PreservedAnalyses::none()
410                                   : PreservedAnalyses::all();
411       }));
412   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
413 
414   // The third CGSCC run should fail to find a cached module analysis as it
415   // should have been invalidated by the above CGSCC run.
416   CGSCCPassManager CGPM3(/*DebugLogging*/ true);
417   int CountFoundModuleAnalysis3 = 0;
418   CGPM3.addPass(
419       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
420                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
421         const auto &MAM =
422             AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG).getManager();
423         auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(
424             *C.begin()->getFunction().getParent());
425 
426         if (TMA)
427           ++CountFoundModuleAnalysis3;
428 
429         return PreservedAnalyses::none();
430       }));
431   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM3)));
432 
433   MPM.run(*M, MAM);
434 
435   EXPECT_EQ(1, ModuleAnalysisRuns);
436   EXPECT_EQ(4, CountFoundModuleAnalysis1);
437   EXPECT_EQ(4, CountFoundModuleAnalysis2);
438   EXPECT_EQ(0, CountFoundModuleAnalysis3);
439 }
440 
441 // Similar to the above, but test that this works for function passes embedded
442 // *within* a CGSCC layer.
443 TEST_F(CGSCCPassManagerTest, TestFunctionPassInsideCGSCCInvalidatesModuleAnalysis) {
444   int ModuleAnalysisRuns = 0;
445   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
446 
447   ModulePassManager MPM(/*DebugLogging*/ true);
448   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
449 
450   // The first run we preserve everything and make sure that works and the
451   // module analysis is available in the second run from the one required
452   // module pass above.
453   FunctionPassManager FPM1(/*DebugLogging*/ true);
454   // Start true and mark false if we ever failed to find a module analysis
455   // because we expect this to succeed for each SCC.
456   bool FoundModuleAnalysis1 = true;
457   FPM1.addPass(
458       LambdaFunctionPass([&](Function &F, FunctionAnalysisManager &AM) {
459         const auto &MAM =
460             AM.getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
461         auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
462 
463         if (!TMA)
464           FoundModuleAnalysis1 = false;
465 
466         return PreservedAnalyses::all();
467       }));
468   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
469   CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
470   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
471 
472   // The second run checks that the module analysis got preserved the previous
473   // time and in one function fails to preserve it.
474   FunctionPassManager FPM2(/*DebugLogging*/ true);
475   // Again, start true and mark false if we ever failed to find a module analysis
476   // because we expect this to succeed for each SCC.
477   bool FoundModuleAnalysis2 = true;
478   FPM2.addPass(
479       LambdaFunctionPass([&](Function &F, FunctionAnalysisManager &AM) {
480         const auto &MAM =
481             AM.getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
482         auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
483 
484         if (!TMA)
485           FoundModuleAnalysis2 = false;
486 
487         // Only fail to preserve analyses on one SCC and make sure that gets
488         // propagated.
489         return F.getName() == "h2" ? PreservedAnalyses::none()
490                                    : PreservedAnalyses::all();
491       }));
492   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
493   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
494   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
495 
496   // The third run should fail to find a cached module analysis as it should
497   // have been invalidated by the above run.
498   FunctionPassManager FPM3(/*DebugLogging*/ true);
499   // Start false and mark true if we ever *succeeded* to find a module
500   // analysis, as we expect this to fail for every function.
501   bool FoundModuleAnalysis3 = false;
502   FPM3.addPass(
503       LambdaFunctionPass([&](Function &F, FunctionAnalysisManager &AM) {
504         const auto &MAM =
505             AM.getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
506         auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
507 
508         if (TMA)
509           FoundModuleAnalysis3 = true;
510 
511         return PreservedAnalyses::none();
512       }));
513   CGSCCPassManager CGPM3(/*DebugLogging*/ true);
514   CGPM3.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM3)));
515   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM3)));
516 
517   MPM.run(*M, MAM);
518 
519   EXPECT_EQ(1, ModuleAnalysisRuns);
520   EXPECT_TRUE(FoundModuleAnalysis1);
521   EXPECT_TRUE(FoundModuleAnalysis2);
522   EXPECT_FALSE(FoundModuleAnalysis3);
523 }
524 
525 // Test that a Module pass which fails to preserve an SCC analysis in fact
526 // invalidates that analysis.
527 TEST_F(CGSCCPassManagerTest, TestModulePassInvalidatesSCCAnalysis) {
528   int SCCAnalysisRuns = 0;
529   CGAM.registerPass([&] { return TestSCCAnalysis(SCCAnalysisRuns); });
530 
531   ModulePassManager MPM(/*DebugLogging*/ true);
532 
533   // First force the analysis to be run.
534   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
535   CGPM1.addPass(RequireAnalysisPass<TestSCCAnalysis, LazyCallGraph::SCC,
536                                     CGSCCAnalysisManager, LazyCallGraph &,
537                                     CGSCCUpdateResult &>());
538   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
539 
540   // Now run a module pass that preserves the LazyCallGraph and the proxy but
541   // not the SCC analysis.
542   MPM.addPass(LambdaModulePass([&](Module &M, ModuleAnalysisManager &) {
543     PreservedAnalyses PA;
544     PA.preserve<LazyCallGraphAnalysis>();
545     PA.preserve<CGSCCAnalysisManagerModuleProxy>();
546     PA.preserve<FunctionAnalysisManagerModuleProxy>();
547     return PA;
548   }));
549 
550   // And now a second CGSCC run which requires the SCC analysis again. This
551   // will trigger re-running it.
552   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
553   CGPM2.addPass(RequireAnalysisPass<TestSCCAnalysis, LazyCallGraph::SCC,
554                                     CGSCCAnalysisManager, LazyCallGraph &,
555                                     CGSCCUpdateResult &>());
556   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
557 
558   MPM.run(*M, MAM);
559   // Two runs and four SCCs.
560   EXPECT_EQ(2 * 4, SCCAnalysisRuns);
561 }
562 
563 // Check that marking the SCC analysis preserved is sufficient to avoid
564 // invaliadtion. This should only run the analysis once for each SCC.
565 TEST_F(CGSCCPassManagerTest, TestModulePassCanPreserveSCCAnalysis) {
566   int SCCAnalysisRuns = 0;
567   CGAM.registerPass([&] { return TestSCCAnalysis(SCCAnalysisRuns); });
568 
569   ModulePassManager MPM(/*DebugLogging*/ true);
570 
571   // First force the analysis to be run.
572   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
573   CGPM1.addPass(RequireAnalysisPass<TestSCCAnalysis, LazyCallGraph::SCC,
574                                     CGSCCAnalysisManager, LazyCallGraph &,
575                                     CGSCCUpdateResult &>());
576   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
577 
578   // Now run a module pass that preserves each of the necessary components
579   // (but not everything).
580   MPM.addPass(LambdaModulePass([&](Module &M, ModuleAnalysisManager &) {
581     PreservedAnalyses PA;
582     PA.preserve<LazyCallGraphAnalysis>();
583     PA.preserve<CGSCCAnalysisManagerModuleProxy>();
584     PA.preserve<FunctionAnalysisManagerModuleProxy>();
585     PA.preserve<TestSCCAnalysis>();
586     return PA;
587   }));
588 
589   // And now a second CGSCC run which requires the SCC analysis again but find
590   // it in the cache.
591   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
592   CGPM2.addPass(RequireAnalysisPass<TestSCCAnalysis, LazyCallGraph::SCC,
593                                     CGSCCAnalysisManager, LazyCallGraph &,
594                                     CGSCCUpdateResult &>());
595   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
596 
597   MPM.run(*M, MAM);
598   // Four SCCs
599   EXPECT_EQ(4, SCCAnalysisRuns);
600 }
601 
602 // Check that even when the analysis is preserved, if the SCC information isn't
603 // we still nuke things because the SCC keys could change.
604 TEST_F(CGSCCPassManagerTest, TestModulePassInvalidatesSCCAnalysisOnCGChange) {
605   int SCCAnalysisRuns = 0;
606   CGAM.registerPass([&] { return TestSCCAnalysis(SCCAnalysisRuns); });
607 
608   ModulePassManager MPM(/*DebugLogging*/ true);
609 
610   // First force the analysis to be run.
611   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
612   CGPM1.addPass(RequireAnalysisPass<TestSCCAnalysis, LazyCallGraph::SCC,
613                                     CGSCCAnalysisManager, LazyCallGraph &,
614                                     CGSCCUpdateResult &>());
615   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
616 
617   // Now run a module pass that preserves the analysis but not the call
618   // graph or proxy.
619   MPM.addPass(LambdaModulePass([&](Module &M, ModuleAnalysisManager &) {
620     PreservedAnalyses PA;
621     PA.preserve<TestSCCAnalysis>();
622     return PA;
623   }));
624 
625   // And now a second CGSCC run which requires the SCC analysis again.
626   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
627   CGPM2.addPass(RequireAnalysisPass<TestSCCAnalysis, LazyCallGraph::SCC,
628                                     CGSCCAnalysisManager, LazyCallGraph &,
629                                     CGSCCUpdateResult &>());
630   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
631 
632   MPM.run(*M, MAM);
633   // Two runs and four SCCs.
634   EXPECT_EQ(2 * 4, SCCAnalysisRuns);
635 }
636 
637 // Test that an SCC pass which fails to preserve a Function analysis in fact
638 // invalidates that analysis.
639 TEST_F(CGSCCPassManagerTest, TestSCCPassInvalidatesFunctionAnalysis) {
640   int FunctionAnalysisRuns = 0;
641   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
642 
643   // Create a very simple module with a single function and SCC to make testing
644   // these issues much easier.
645   std::unique_ptr<Module> M = parseIR("declare void @g()\n"
646                                       "declare void @h()\n"
647                                       "define void @f() {\n"
648                                       "entry:\n"
649                                       "  call void @g()\n"
650                                       "  call void @h()\n"
651                                       "  ret void\n"
652                                       "}\n");
653 
654   CGSCCPassManager CGPM(/*DebugLogging*/ true);
655 
656   // First force the analysis to be run.
657   FunctionPassManager FPM1(/*DebugLogging*/ true);
658   FPM1.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
659   CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
660 
661   // Now run a module pass that preserves the LazyCallGraph and proxy but not
662   // the SCC analysis.
663   CGPM.addPass(LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &,
664                                  LazyCallGraph &, CGSCCUpdateResult &) {
665     PreservedAnalyses PA;
666     PA.preserve<LazyCallGraphAnalysis>();
667     return PA;
668   }));
669 
670   // And now a second CGSCC run which requires the SCC analysis again. This
671   // will trigger re-running it.
672   FunctionPassManager FPM2(/*DebugLogging*/ true);
673   FPM2.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
674   CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
675 
676   ModulePassManager MPM(/*DebugLogging*/ true);
677   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
678   MPM.run(*M, MAM);
679   EXPECT_EQ(2, FunctionAnalysisRuns);
680 }
681 
682 // Check that marking the SCC analysis preserved is sufficient. This should
683 // only run the analysis once the SCC.
684 TEST_F(CGSCCPassManagerTest, TestSCCPassCanPreserveFunctionAnalysis) {
685   int FunctionAnalysisRuns = 0;
686   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
687 
688   // Create a very simple module with a single function and SCC to make testing
689   // these issues much easier.
690   std::unique_ptr<Module> M = parseIR("declare void @g()\n"
691                                       "declare void @h()\n"
692                                       "define void @f() {\n"
693                                       "entry:\n"
694                                       "  call void @g()\n"
695                                       "  call void @h()\n"
696                                       "  ret void\n"
697                                       "}\n");
698 
699   CGSCCPassManager CGPM(/*DebugLogging*/ true);
700 
701   // First force the analysis to be run.
702   FunctionPassManager FPM1(/*DebugLogging*/ true);
703   FPM1.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
704   CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
705 
706   // Now run a module pass that preserves each of the necessary components
707   // (but
708   // not everything).
709   CGPM.addPass(LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &,
710                                  LazyCallGraph &, CGSCCUpdateResult &) {
711     PreservedAnalyses PA;
712     PA.preserve<LazyCallGraphAnalysis>();
713     PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
714     PA.preserve<TestFunctionAnalysis>();
715     return PA;
716   }));
717 
718   // And now a second CGSCC run which requires the SCC analysis again but find
719   // it in the cache.
720   FunctionPassManager FPM2(/*DebugLogging*/ true);
721   FPM2.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
722   CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
723 
724   ModulePassManager MPM(/*DebugLogging*/ true);
725   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
726   MPM.run(*M, MAM);
727   EXPECT_EQ(1, FunctionAnalysisRuns);
728 }
729 
730 // Note that there is no test for invalidating the call graph or other
731 // structure with an SCC pass because there is no mechanism to do that from
732 // withinsuch a pass. Instead, such a pass has to directly update the call
733 // graph structure.
734 
735 // Test that a madule pass invalidates function analyses when the CGSCC proxies
736 // and pass manager.
737 TEST_F(CGSCCPassManagerTest,
738        TestModulePassInvalidatesFunctionAnalysisNestedInCGSCC) {
739   MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
740 
741   int FunctionAnalysisRuns = 0;
742   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
743 
744   ModulePassManager MPM(/*DebugLogging*/ true);
745 
746   // First force the analysis to be run.
747   FunctionPassManager FPM1(/*DebugLogging*/ true);
748   FPM1.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
749   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
750   CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
751   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
752 
753   // Now run a module pass that preserves the LazyCallGraph and proxies but not
754   // the Function analysis.
755   MPM.addPass(LambdaModulePass([&](Module &M, ModuleAnalysisManager &) {
756     PreservedAnalyses PA;
757     PA.preserve<LazyCallGraphAnalysis>();
758     PA.preserve<CGSCCAnalysisManagerModuleProxy>();
759     PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
760     PA.preserve<FunctionAnalysisManagerModuleProxy>();
761     return PA;
762   }));
763 
764   // And now a second CGSCC run which requires the SCC analysis again. This
765   // will trigger re-running it.
766   FunctionPassManager FPM2(/*DebugLogging*/ true);
767   FPM2.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
768   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
769   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
770   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
771 
772   MPM.run(*M, MAM);
773   // Two runs and 6 functions.
774   EXPECT_EQ(2 * 6, FunctionAnalysisRuns);
775 }
776 
777 // Check that by marking the function pass and proxies as preserved, this
778 // propagates all the way through.
779 TEST_F(CGSCCPassManagerTest,
780        TestModulePassCanPreserveFunctionAnalysisNestedInCGSCC) {
781   MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
782 
783   int FunctionAnalysisRuns = 0;
784   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
785 
786   ModulePassManager MPM(/*DebugLogging*/ true);
787 
788   // First force the analysis to be run.
789   FunctionPassManager FPM1(/*DebugLogging*/ true);
790   FPM1.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
791   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
792   CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
793   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
794 
795   // Now run a module pass that preserves the LazyCallGraph, the proxy, and
796   // the Function analysis.
797   MPM.addPass(LambdaModulePass([&](Module &M, ModuleAnalysisManager &) {
798     PreservedAnalyses PA;
799     PA.preserve<LazyCallGraphAnalysis>();
800     PA.preserve<CGSCCAnalysisManagerModuleProxy>();
801     PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
802     PA.preserve<FunctionAnalysisManagerModuleProxy>();
803     PA.preserve<TestFunctionAnalysis>();
804     return PA;
805   }));
806 
807   // And now a second CGSCC run which requires the SCC analysis again. This
808   // will trigger re-running it.
809   FunctionPassManager FPM2(/*DebugLogging*/ true);
810   FPM2.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
811   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
812   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
813   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
814 
815   MPM.run(*M, MAM);
816   // One run and 6 functions.
817   EXPECT_EQ(6, FunctionAnalysisRuns);
818 }
819 
820 // Check that if the lazy call graph itself isn't preserved we still manage to
821 // invalidate everything.
822 TEST_F(CGSCCPassManagerTest,
823        TestModulePassInvalidatesFunctionAnalysisNestedInCGSCCOnCGChange) {
824   MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
825 
826   int FunctionAnalysisRuns = 0;
827   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
828 
829   ModulePassManager MPM(/*DebugLogging*/ true);
830 
831   // First force the analysis to be run.
832   FunctionPassManager FPM1(/*DebugLogging*/ true);
833   FPM1.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
834   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
835   CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
836   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
837 
838   // Now run a module pass that preserves the LazyCallGraph but not the
839   // Function analysis.
840   MPM.addPass(LambdaModulePass([&](Module &M, ModuleAnalysisManager &) {
841     PreservedAnalyses PA;
842     return PA;
843   }));
844 
845   // And now a second CGSCC run which requires the SCC analysis again. This
846   // will trigger re-running it.
847   FunctionPassManager FPM2(/*DebugLogging*/ true);
848   FPM2.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
849   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
850   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
851   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
852 
853   MPM.run(*M, MAM);
854   // Two runs and 6 functions.
855   EXPECT_EQ(2 * 6, FunctionAnalysisRuns);
856 }
857 
858 /// A test CGSCC-level analysis pass which caches in its result another
859 /// analysis pass and uses it to serve queries. This requires the result to
860 /// invalidate itself when its dependency is invalidated.
861 ///
862 /// FIXME: Currently this doesn't also depend on a function analysis, and if it
863 /// did we would fail to invalidate it correctly.
864 struct TestIndirectSCCAnalysis
865     : public AnalysisInfoMixin<TestIndirectSCCAnalysis> {
866   struct Result {
867     Result(TestSCCAnalysis::Result &SCCDep, TestModuleAnalysis::Result &MDep)
868         : SCCDep(SCCDep), MDep(MDep) {}
869     TestSCCAnalysis::Result &SCCDep;
870     TestModuleAnalysis::Result &MDep;
871 
872     bool invalidate(LazyCallGraph::SCC &C, const PreservedAnalyses &PA,
873                     CGSCCAnalysisManager::Invalidator &Inv) {
874       auto PAC = PA.getChecker<TestIndirectSCCAnalysis>();
875       return !(PAC.preserved() ||
876                PAC.preservedSet<AllAnalysesOn<LazyCallGraph::SCC>>()) ||
877              Inv.invalidate<TestSCCAnalysis>(C, PA);
878     }
879   };
880 
881   TestIndirectSCCAnalysis(int &Runs) : Runs(Runs) {}
882 
883   /// Run the analysis pass over the function and return a result.
884   Result run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
885              LazyCallGraph &CG) {
886     ++Runs;
887     auto &SCCDep = AM.getResult<TestSCCAnalysis>(C, CG);
888 
889     auto &ModuleProxy = AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG);
890     const ModuleAnalysisManager &MAM = ModuleProxy.getManager();
891     // For the test, we insist that the module analysis starts off in the
892     // cache.
893     auto &MDep = *MAM.getCachedResult<TestModuleAnalysis>(
894         *C.begin()->getFunction().getParent());
895     // Register the dependency as module analysis dependencies have to be
896     // pre-registered on the proxy.
897     ModuleProxy.registerOuterAnalysisInvalidation<TestModuleAnalysis,
898                                                   TestIndirectSCCAnalysis>();
899 
900     return Result(SCCDep, MDep);
901   }
902 
903 private:
904   friend AnalysisInfoMixin<TestIndirectSCCAnalysis>;
905   static AnalysisKey Key;
906 
907   int &Runs;
908 };
909 
910 AnalysisKey TestIndirectSCCAnalysis::Key;
911 
912 /// A test analysis pass which caches in its result the result from the above
913 /// indirect analysis pass.
914 ///
915 /// This allows us to ensure that whenever an analysis pass is invalidated due
916 /// to dependencies (especially dependencies across IR units that trigger
917 /// asynchronous invalidation) we correctly detect that this may in turn cause
918 /// other analysis to be invalidated.
919 struct TestDoublyIndirectSCCAnalysis
920     : public AnalysisInfoMixin<TestDoublyIndirectSCCAnalysis> {
921   struct Result {
922     Result(TestIndirectSCCAnalysis::Result &IDep) : IDep(IDep) {}
923     TestIndirectSCCAnalysis::Result &IDep;
924 
925     bool invalidate(LazyCallGraph::SCC &C, const PreservedAnalyses &PA,
926                     CGSCCAnalysisManager::Invalidator &Inv) {
927       auto PAC = PA.getChecker<TestDoublyIndirectSCCAnalysis>();
928       return !(PAC.preserved() ||
929                PAC.preservedSet<AllAnalysesOn<LazyCallGraph::SCC>>()) ||
930              Inv.invalidate<TestIndirectSCCAnalysis>(C, PA);
931     }
932   };
933 
934   TestDoublyIndirectSCCAnalysis(int &Runs) : Runs(Runs) {}
935 
936   /// Run the analysis pass over the function and return a result.
937   Result run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
938              LazyCallGraph &CG) {
939     ++Runs;
940     auto &IDep = AM.getResult<TestIndirectSCCAnalysis>(C, CG);
941     return Result(IDep);
942   }
943 
944 private:
945   friend AnalysisInfoMixin<TestDoublyIndirectSCCAnalysis>;
946   static AnalysisKey Key;
947 
948   int &Runs;
949 };
950 
951 AnalysisKey TestDoublyIndirectSCCAnalysis::Key;
952 
953 /// A test analysis pass which caches results from three different IR unit
954 /// layers and requires intermediate layers to correctly propagate the entire
955 /// distance.
956 struct TestIndirectFunctionAnalysis
957     : public AnalysisInfoMixin<TestIndirectFunctionAnalysis> {
958   struct Result {
959     Result(TestFunctionAnalysis::Result &FDep, TestModuleAnalysis::Result &MDep,
960            TestSCCAnalysis::Result &SCCDep)
961         : FDep(FDep), MDep(MDep), SCCDep(SCCDep) {}
962     TestFunctionAnalysis::Result &FDep;
963     TestModuleAnalysis::Result &MDep;
964     TestSCCAnalysis::Result &SCCDep;
965 
966     bool invalidate(Function &F, const PreservedAnalyses &PA,
967                     FunctionAnalysisManager::Invalidator &Inv) {
968       auto PAC = PA.getChecker<TestIndirectFunctionAnalysis>();
969       return !(PAC.preserved() ||
970                PAC.preservedSet<AllAnalysesOn<Function>>()) ||
971              Inv.invalidate<TestFunctionAnalysis>(F, PA);
972     }
973   };
974 
975   TestIndirectFunctionAnalysis(int &Runs) : Runs(Runs) {}
976 
977   /// Run the analysis pass over the function and return a result.
978   Result run(Function &F, FunctionAnalysisManager &AM) {
979     ++Runs;
980     auto &FDep = AM.getResult<TestFunctionAnalysis>(F);
981 
982     auto &ModuleProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
983     const ModuleAnalysisManager &MAM = ModuleProxy.getManager();
984     // For the test, we insist that the module analysis starts off in the
985     // cache.
986     auto &MDep = *MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
987     // Register the dependency as module analysis dependencies have to be
988     // pre-registered on the proxy.
989     ModuleProxy.registerOuterAnalysisInvalidation<
990         TestModuleAnalysis, TestIndirectFunctionAnalysis>();
991 
992     // For thet test we assume this is run inside a CGSCC pass manager.
993     const LazyCallGraph &CG =
994         *MAM.getCachedResult<LazyCallGraphAnalysis>(*F.getParent());
995     auto &CGSCCProxy = AM.getResult<CGSCCAnalysisManagerFunctionProxy>(F);
996     const CGSCCAnalysisManager &CGAM = CGSCCProxy.getManager();
997     // For the test, we insist that the CGSCC analysis starts off in the cache.
998     auto &SCCDep =
999         *CGAM.getCachedResult<TestSCCAnalysis>(*CG.lookupSCC(*CG.lookup(F)));
1000     // Register the dependency as CGSCC analysis dependencies have to be
1001     // pre-registered on the proxy.
1002     CGSCCProxy.registerOuterAnalysisInvalidation<
1003         TestSCCAnalysis, TestIndirectFunctionAnalysis>();
1004 
1005     return Result(FDep, MDep, SCCDep);
1006   }
1007 
1008 private:
1009   friend AnalysisInfoMixin<TestIndirectFunctionAnalysis>;
1010   static AnalysisKey Key;
1011 
1012   int &Runs;
1013 };
1014 
1015 AnalysisKey TestIndirectFunctionAnalysis::Key;
1016 
1017 TEST_F(CGSCCPassManagerTest, TestIndirectAnalysisInvalidation) {
1018   int ModuleAnalysisRuns = 0;
1019   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
1020 
1021   int SCCAnalysisRuns = 0, IndirectSCCAnalysisRuns = 0,
1022       DoublyIndirectSCCAnalysisRuns = 0;
1023   CGAM.registerPass([&] { return TestSCCAnalysis(SCCAnalysisRuns); });
1024   CGAM.registerPass(
1025       [&] { return TestIndirectSCCAnalysis(IndirectSCCAnalysisRuns); });
1026   CGAM.registerPass([&] {
1027     return TestDoublyIndirectSCCAnalysis(DoublyIndirectSCCAnalysisRuns);
1028   });
1029 
1030   int FunctionAnalysisRuns = 0, IndirectFunctionAnalysisRuns = 0;
1031   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
1032   FAM.registerPass([&] {
1033     return TestIndirectFunctionAnalysis(IndirectFunctionAnalysisRuns);
1034   });
1035 
1036   ModulePassManager MPM(/*DebugLogging*/ true);
1037 
1038   int FunctionCount = 0;
1039   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1040   // First just use the analysis to get the function count and preserve
1041   // everything.
1042   CGPM.addPass(
1043       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1044                         LazyCallGraph &CG, CGSCCUpdateResult &) {
1045         auto &DoublyIndirectResult =
1046             AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1047         auto &IndirectResult = DoublyIndirectResult.IDep;
1048         FunctionCount += IndirectResult.SCCDep.FunctionCount;
1049         return PreservedAnalyses::all();
1050       }));
1051   CGPM.addPass(createCGSCCToFunctionPassAdaptor(
1052       RequireAnalysisPass<TestIndirectFunctionAnalysis, Function>()));
1053 
1054   // Next, invalidate
1055   //   - both analyses for the (f) and (x) SCCs,
1056   //   - just the underlying (indirect) analysis for (g) SCC, and
1057   //   - just the direct analysis for (h1,h2,h3) SCC.
1058   CGPM.addPass(
1059       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1060                         LazyCallGraph &CG, CGSCCUpdateResult &) {
1061         auto &DoublyIndirectResult =
1062             AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1063         auto &IndirectResult = DoublyIndirectResult.IDep;
1064         FunctionCount += IndirectResult.SCCDep.FunctionCount;
1065         auto PA = PreservedAnalyses::none();
1066         PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
1067         PA.preserveSet<AllAnalysesOn<Function>>();
1068         if (C.getName() == "(g)")
1069           PA.preserve<TestSCCAnalysis>();
1070         else if (C.getName() == "(h3, h1, h2)")
1071           PA.preserve<TestIndirectSCCAnalysis>();
1072         return PA;
1073       }));
1074   // Finally, use the analysis again on each SCC (and function), forcing
1075   // re-computation for all of them.
1076   CGPM.addPass(
1077       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1078                         LazyCallGraph &CG, CGSCCUpdateResult &) {
1079         auto &DoublyIndirectResult =
1080             AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1081         auto &IndirectResult = DoublyIndirectResult.IDep;
1082         FunctionCount += IndirectResult.SCCDep.FunctionCount;
1083         return PreservedAnalyses::all();
1084       }));
1085   CGPM.addPass(createCGSCCToFunctionPassAdaptor(
1086       RequireAnalysisPass<TestIndirectFunctionAnalysis, Function>()));
1087 
1088   // Create a second CGSCC pass manager. This will cause the module-level
1089   // invalidation to occur, which will force yet another invalidation of the
1090   // indirect SCC-level analysis as the module analysis it depends on gets
1091   // invalidated.
1092   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
1093   CGPM2.addPass(
1094       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1095                         LazyCallGraph &CG, CGSCCUpdateResult &) {
1096         auto &DoublyIndirectResult =
1097             AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1098         auto &IndirectResult = DoublyIndirectResult.IDep;
1099         FunctionCount += IndirectResult.SCCDep.FunctionCount;
1100         return PreservedAnalyses::all();
1101       }));
1102   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(
1103       RequireAnalysisPass<TestIndirectFunctionAnalysis, Function>()));
1104 
1105   // Add a requires pass to populate the module analysis and then our CGSCC
1106   // pass pipeline.
1107   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1108   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1109   // Now require the module analysis again (it will have been invalidated once)
1110   // and then use it again from our second CGSCC pipeline..
1111   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1112   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
1113   MPM.run(*M, MAM);
1114 
1115   // There are generally two possible runs for each of the four SCCs. But
1116   // for one SCC, we only invalidate the indirect analysis so the base one
1117   // only gets run seven times.
1118   EXPECT_EQ(7, SCCAnalysisRuns);
1119   // The module analysis pass should be run twice here.
1120   EXPECT_EQ(2, ModuleAnalysisRuns);
1121   // The indirect analysis is invalidated (either directly or indirectly) three
1122   // times for each of four SCCs.
1123   EXPECT_EQ(3 * 4, IndirectSCCAnalysisRuns);
1124   EXPECT_EQ(3 * 4, DoublyIndirectSCCAnalysisRuns);
1125 
1126   // We run the indirect function analysis once per function the first time.
1127   // Then we re-run it for every SCC but "(g)". Then we re-run it for every
1128   // function again.
1129   EXPECT_EQ(6 + 5 + 6, IndirectFunctionAnalysisRuns);
1130 
1131   // Four passes count each of six functions once (via SCCs).
1132   EXPECT_EQ(4 * 6, FunctionCount);
1133 }
1134 
1135 TEST_F(CGSCCPassManagerTest, TestAnalysisInvalidationCGSCCUpdate) {
1136   int ModuleAnalysisRuns = 0;
1137   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
1138 
1139   int SCCAnalysisRuns = 0, IndirectSCCAnalysisRuns = 0,
1140       DoublyIndirectSCCAnalysisRuns = 0;
1141   CGAM.registerPass([&] { return TestSCCAnalysis(SCCAnalysisRuns); });
1142   CGAM.registerPass(
1143       [&] { return TestIndirectSCCAnalysis(IndirectSCCAnalysisRuns); });
1144   CGAM.registerPass([&] {
1145     return TestDoublyIndirectSCCAnalysis(DoublyIndirectSCCAnalysisRuns);
1146   });
1147 
1148   int FunctionAnalysisRuns = 0, IndirectFunctionAnalysisRuns = 0;
1149   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
1150   FAM.registerPass([&] {
1151     return TestIndirectFunctionAnalysis(IndirectFunctionAnalysisRuns);
1152   });
1153 
1154   ModulePassManager MPM(/*DebugLogging*/ true);
1155 
1156   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1157   // First just use the analysis to get the function count and preserve
1158   // everything.
1159   using RequireTestIndirectFunctionAnalysisPass =
1160       RequireAnalysisPass<TestIndirectFunctionAnalysis, Function>;
1161   using RequireTestDoublyIndirectSCCAnalysisPass =
1162       RequireAnalysisPass<TestDoublyIndirectSCCAnalysis, LazyCallGraph::SCC,
1163                           CGSCCAnalysisManager, LazyCallGraph &,
1164                           CGSCCUpdateResult &>;
1165   CGPM.addPass(RequireTestDoublyIndirectSCCAnalysisPass());
1166   CGPM.addPass(createCGSCCToFunctionPassAdaptor(
1167       RequireTestIndirectFunctionAnalysisPass()));
1168 
1169   // Next, we inject an SCC pass that invalidates everything for the `(h3, h1,
1170   // h2)` SCC but also deletes the call edge from `h2` to `h3` and updates the
1171   // CG. This should successfully invalidate (and force to be re-run) all the
1172   // analyses for that SCC and for the functions.
1173   CGPM.addPass(
1174       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1175                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
1176         (void)AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1177         if (C.getName() != "(h3, h1, h2)")
1178           return PreservedAnalyses::all();
1179 
1180         // Build the preserved set.
1181         auto PA = PreservedAnalyses::none();
1182         PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
1183         PA.preserve<TestIndirectSCCAnalysis>();
1184         PA.preserve<TestDoublyIndirectSCCAnalysis>();
1185 
1186         // Delete the call from `h2` to `h3`.
1187         auto &H2N = *llvm::find_if(
1188             C, [](LazyCallGraph::Node &N) { return N.getName() == "h2"; });
1189         auto &H2F = H2N.getFunction();
1190         auto &H3F = *cast<CallInst>(H2F.begin()->begin())->getCalledFunction();
1191         assert(H3F.getName() == "h3" && "Wrong called function!");
1192         H2F.begin()->begin()->eraseFromParent();
1193         // Insert a bitcast of `h3` so that we retain a ref edge to it.
1194         (void)CastInst::CreatePointerCast(&H3F,
1195                                           Type::getInt8PtrTy(H2F.getContext()),
1196                                           "dummy", &*H2F.begin()->begin());
1197 
1198         // Now update the call graph.
1199         auto &NewC =
1200             updateCGAndAnalysisManagerForFunctionPass(CG, C, H2N, AM, UR);
1201         assert(&NewC != &C && "Should get a new SCC due to update!");
1202         (void)&NewC;
1203 
1204         return PA;
1205       }));
1206   // Now use the analysis again on each SCC and function, forcing
1207   // re-computation for all of them.
1208   CGPM.addPass(RequireTestDoublyIndirectSCCAnalysisPass());
1209   CGPM.addPass(createCGSCCToFunctionPassAdaptor(
1210       RequireTestIndirectFunctionAnalysisPass()));
1211 
1212   // Create another CGSCC pipeline that requires all the analyses again.
1213   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
1214   CGPM2.addPass(RequireTestDoublyIndirectSCCAnalysisPass());
1215   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(
1216       RequireTestIndirectFunctionAnalysisPass()));
1217 
1218   // Next we inject an SCC pass that finds the `(h2)` SCC, adds a call to `h3`
1219   // back to `h2`, and then invalidates everything for what will then be the
1220   // `(h3, h1, h2)` SCC again.
1221   CGSCCPassManager CGPM3(/*DebugLogging*/ true);
1222   CGPM3.addPass(
1223       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1224                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
1225         (void)AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1226         if (C.getName() != "(h2)")
1227           return PreservedAnalyses::all();
1228 
1229         // Build the preserved set.
1230         auto PA = PreservedAnalyses::none();
1231         PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
1232         PA.preserve<TestIndirectSCCAnalysis>();
1233         PA.preserve<TestDoublyIndirectSCCAnalysis>();
1234 
1235         // Delete the bitcast of `h3` that we added earlier.
1236         auto &H2N = *C.begin();
1237         auto &H2F = H2N.getFunction();
1238         auto &H3F = *cast<Function>(cast<BitCastInst>(H2F.begin()->begin())->getOperand(0));
1239         assert(H3F.getName() == "h3" && "Wrong called function!");
1240         H2F.begin()->begin()->eraseFromParent();
1241         // And insert a call to `h3`.
1242         (void)CallInst::Create(&H3F, {}, "", &*H2F.begin()->begin());
1243 
1244         // Now update the call graph.
1245         auto &NewC =
1246             updateCGAndAnalysisManagerForFunctionPass(CG, C, H2N, AM, UR);
1247         assert(&NewC != &C && "Should get a new SCC due to update!");
1248         (void)&NewC;
1249 
1250         return PA;
1251       }));
1252   // Now use the analysis again on each SCC and function, forcing
1253   // re-computation for all of them.
1254   CGPM3.addPass(RequireTestDoublyIndirectSCCAnalysisPass());
1255   CGPM3.addPass(createCGSCCToFunctionPassAdaptor(
1256       RequireTestIndirectFunctionAnalysisPass()));
1257 
1258   // Create a second CGSCC pass manager. This will cause the module-level
1259   // invalidation to occur, which will force yet another invalidation of the
1260   // indirect SCC-level analysis as the module analysis it depends on gets
1261   // invalidated.
1262   CGSCCPassManager CGPM4(/*DebugLogging*/ true);
1263   CGPM4.addPass(RequireTestDoublyIndirectSCCAnalysisPass());
1264   CGPM4.addPass(createCGSCCToFunctionPassAdaptor(
1265       RequireTestIndirectFunctionAnalysisPass()));
1266 
1267   // Add a requires pass to populate the module analysis and then one of our
1268   // CGSCC pipelines. Repeat for all four CGSCC pipelines.
1269   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1270   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1271   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1272   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
1273   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1274   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM3)));
1275   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1276   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM4)));
1277   MPM.run(*M, MAM);
1278 
1279   // We run over four SCCs the first time. But then we split an SCC into three.
1280   // And then we merge those three back into one. However, this also
1281   // invalidates all three SCCs further down in the PO walk.
1282   EXPECT_EQ(4 + 3 + 1 + 3, SCCAnalysisRuns);
1283   // The module analysis pass should be run three times.
1284   EXPECT_EQ(3, ModuleAnalysisRuns);
1285   // We run over four SCCs the first time. Then over the two new ones. Then the
1286   // entire module is invalidated causing a full run over all seven. Then we
1287   // fold three SCCs back to one, re-compute for it and the two SCCs above it
1288   // in the graph, and then run over the whole module again.
1289   EXPECT_EQ(4 + 2 + 7 + 1 + 3 + 4, IndirectSCCAnalysisRuns);
1290   EXPECT_EQ(4 + 2 + 7 + 1 + 3 + 4, DoublyIndirectSCCAnalysisRuns);
1291 
1292   // First we run over all six functions. Then we re-run it over three when we
1293   // split their SCCs. Then we re-run over the whole module. Then we re-run
1294   // over three functions merged back into a single SCC, then those three
1295   // functions again, the two functions in SCCs above it in the graph, and then
1296   // over the whole module again.
1297   EXPECT_EQ(6 + 3 + 6 + 3 + 3 + 2 + 6, FunctionAnalysisRuns);
1298 
1299   // Re run the function analysis over the entire module, and then re-run it
1300   // over the `(h3, h1, h2)` SCC due to invalidation. Then we re-run it over
1301   // the entire module, then the three functions merged back into a single SCC,
1302   // those three functions again, then the two functions in SCCs above it in
1303   // the graph, and then over the whole module.
1304   EXPECT_EQ(6 + 3 + 6 + 3 + 3 + 2 + 6, IndirectFunctionAnalysisRuns);
1305 }
1306 }
1307