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