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