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<FunctionAnalysisManagerCGSCCProxy>();
684     PA.preserve<TestFunctionAnalysis>();
685     return PA;
686   }));
687 
688   // And now a second CGSCC run which requires the SCC analysis again but find
689   // it in the cache.
690   FunctionPassManager FPM2(/*DebugLogging*/ true);
691   FPM2.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
692   CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
693 
694   ModulePassManager MPM(/*DebugLogging*/ true);
695   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
696   MPM.run(*M, MAM);
697   EXPECT_EQ(1, FunctionAnalysisRuns);
698 }
699 
700 // Note that there is no test for invalidating the call graph or other
701 // structure with an SCC pass because there is no mechanism to do that from
702 // withinsuch a pass. Instead, such a pass has to directly update the call
703 // graph structure.
704 
705 // Test that a madule pass invalidates function analyses when the CGSCC proxies
706 // and pass manager.
707 TEST_F(CGSCCPassManagerTest,
708        TestModulePassInvalidatesFunctionAnalysisNestedInCGSCC) {
709   MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
710 
711   int FunctionAnalysisRuns = 0;
712   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
713 
714   ModulePassManager MPM(/*DebugLogging*/ true);
715 
716   // First force the analysis to be run.
717   FunctionPassManager FPM1(/*DebugLogging*/ true);
718   FPM1.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
719   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
720   CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
721   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
722 
723   // Now run a module pass that preserves the LazyCallGraph and proxies but not
724   // the Function analysis.
725   MPM.addPass(LambdaModulePass([&](Module &M, ModuleAnalysisManager &) {
726     PreservedAnalyses PA;
727     PA.preserve<LazyCallGraphAnalysis>();
728     PA.preserve<CGSCCAnalysisManagerModuleProxy>();
729     PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
730     PA.preserve<FunctionAnalysisManagerModuleProxy>();
731     return PA;
732   }));
733 
734   // And now a second CGSCC run which requires the SCC analysis again. This
735   // will trigger re-running it.
736   FunctionPassManager FPM2(/*DebugLogging*/ true);
737   FPM2.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
738   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
739   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
740   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
741 
742   MPM.run(*M, MAM);
743   // Two runs and 6 functions.
744   EXPECT_EQ(2 * 6, FunctionAnalysisRuns);
745 }
746 
747 // Check that by marking the function pass and proxies as preserved, this
748 // propagates all the way through.
749 TEST_F(CGSCCPassManagerTest,
750        TestModulePassCanPreserveFunctionAnalysisNestedInCGSCC) {
751   MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
752 
753   int FunctionAnalysisRuns = 0;
754   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
755 
756   ModulePassManager MPM(/*DebugLogging*/ true);
757 
758   // First force the analysis to be run.
759   FunctionPassManager FPM1(/*DebugLogging*/ true);
760   FPM1.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
761   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
762   CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
763   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
764 
765   // Now run a module pass that preserves the LazyCallGraph, the proxy, and
766   // the Function analysis.
767   MPM.addPass(LambdaModulePass([&](Module &M, ModuleAnalysisManager &) {
768     PreservedAnalyses PA;
769     PA.preserve<LazyCallGraphAnalysis>();
770     PA.preserve<CGSCCAnalysisManagerModuleProxy>();
771     PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
772     PA.preserve<FunctionAnalysisManagerModuleProxy>();
773     PA.preserve<TestFunctionAnalysis>();
774     return PA;
775   }));
776 
777   // And now a second CGSCC run which requires the SCC analysis again. This
778   // will trigger re-running it.
779   FunctionPassManager FPM2(/*DebugLogging*/ true);
780   FPM2.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
781   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
782   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
783   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
784 
785   MPM.run(*M, MAM);
786   // One run and 6 functions.
787   EXPECT_EQ(6, FunctionAnalysisRuns);
788 }
789 
790 // Check that if the lazy call graph itself isn't preserved we still manage to
791 // invalidate everything.
792 TEST_F(CGSCCPassManagerTest,
793        TestModulePassInvalidatesFunctionAnalysisNestedInCGSCCOnCGChange) {
794   MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
795 
796   int FunctionAnalysisRuns = 0;
797   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
798 
799   ModulePassManager MPM(/*DebugLogging*/ true);
800 
801   // First force the analysis to be run.
802   FunctionPassManager FPM1(/*DebugLogging*/ true);
803   FPM1.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
804   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
805   CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
806   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
807 
808   // Now run a module pass that preserves the LazyCallGraph but not the
809   // Function analysis.
810   MPM.addPass(LambdaModulePass([&](Module &M, ModuleAnalysisManager &) {
811     PreservedAnalyses PA;
812     return PA;
813   }));
814 
815   // And now a second CGSCC run which requires the SCC analysis again. This
816   // will trigger re-running it.
817   FunctionPassManager FPM2(/*DebugLogging*/ true);
818   FPM2.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
819   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
820   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
821   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
822 
823   MPM.run(*M, MAM);
824   // Two runs and 6 functions.
825   EXPECT_EQ(2 * 6, FunctionAnalysisRuns);
826 }
827 
828 /// A test CGSCC-level analysis pass which caches in its result another
829 /// analysis pass and uses it to serve queries. This requires the result to
830 /// invalidate itself when its dependency is invalidated.
831 ///
832 /// FIXME: Currently this doesn't also depend on a function analysis, and if it
833 /// did we would fail to invalidate it correctly.
834 struct TestIndirectSCCAnalysis
835     : public AnalysisInfoMixin<TestIndirectSCCAnalysis> {
836   struct Result {
837     Result(TestSCCAnalysis::Result &SCCDep, TestModuleAnalysis::Result &MDep)
838         : SCCDep(SCCDep), MDep(MDep) {}
839     TestSCCAnalysis::Result &SCCDep;
840     TestModuleAnalysis::Result &MDep;
841 
842     bool invalidate(LazyCallGraph::SCC &C, const PreservedAnalyses &PA,
843                     CGSCCAnalysisManager::Invalidator &Inv) {
844       auto PAC = PA.getChecker<TestIndirectSCCAnalysis>();
845       return !(PAC.preserved() ||
846                PAC.preservedSet<AllAnalysesOn<LazyCallGraph::SCC>>()) ||
847              Inv.invalidate<TestSCCAnalysis>(C, PA);
848     }
849   };
850 
851   TestIndirectSCCAnalysis(int &Runs) : Runs(Runs) {}
852 
853   /// Run the analysis pass over the function and return a result.
854   Result run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
855              LazyCallGraph &CG) {
856     ++Runs;
857     auto &SCCDep = AM.getResult<TestSCCAnalysis>(C, CG);
858 
859     auto &ModuleProxy = AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG);
860     const ModuleAnalysisManager &MAM = ModuleProxy.getManager();
861     // For the test, we insist that the module analysis starts off in the
862     // cache.
863     auto &MDep = *MAM.getCachedResult<TestModuleAnalysis>(
864         *C.begin()->getFunction().getParent());
865     // Register the dependency as module analysis dependencies have to be
866     // pre-registered on the proxy.
867     ModuleProxy.registerOuterAnalysisInvalidation<TestModuleAnalysis,
868                                                   TestIndirectSCCAnalysis>();
869 
870     return Result(SCCDep, MDep);
871   }
872 
873 private:
874   friend AnalysisInfoMixin<TestIndirectSCCAnalysis>;
875   static AnalysisKey Key;
876 
877   int &Runs;
878 };
879 
880 AnalysisKey TestIndirectSCCAnalysis::Key;
881 
882 /// A test analysis pass which caches in its result the result from the above
883 /// indirect analysis pass.
884 ///
885 /// This allows us to ensure that whenever an analysis pass is invalidated due
886 /// to dependencies (especially dependencies across IR units that trigger
887 /// asynchronous invalidation) we correctly detect that this may in turn cause
888 /// other analysis to be invalidated.
889 struct TestDoublyIndirectSCCAnalysis
890     : public AnalysisInfoMixin<TestDoublyIndirectSCCAnalysis> {
891   struct Result {
892     Result(TestIndirectSCCAnalysis::Result &IDep) : IDep(IDep) {}
893     TestIndirectSCCAnalysis::Result &IDep;
894 
895     bool invalidate(LazyCallGraph::SCC &C, const PreservedAnalyses &PA,
896                     CGSCCAnalysisManager::Invalidator &Inv) {
897       auto PAC = PA.getChecker<TestDoublyIndirectSCCAnalysis>();
898       return !(PAC.preserved() ||
899                PAC.preservedSet<AllAnalysesOn<LazyCallGraph::SCC>>()) ||
900              Inv.invalidate<TestIndirectSCCAnalysis>(C, PA);
901     }
902   };
903 
904   TestDoublyIndirectSCCAnalysis(int &Runs) : Runs(Runs) {}
905 
906   /// Run the analysis pass over the function and return a result.
907   Result run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
908              LazyCallGraph &CG) {
909     ++Runs;
910     auto &IDep = AM.getResult<TestIndirectSCCAnalysis>(C, CG);
911     return Result(IDep);
912   }
913 
914 private:
915   friend AnalysisInfoMixin<TestDoublyIndirectSCCAnalysis>;
916   static AnalysisKey Key;
917 
918   int &Runs;
919 };
920 
921 AnalysisKey TestDoublyIndirectSCCAnalysis::Key;
922 
923 /// A test analysis pass which caches results from three different IR unit
924 /// layers and requires intermediate layers to correctly propagate the entire
925 /// distance.
926 struct TestIndirectFunctionAnalysis
927     : public AnalysisInfoMixin<TestIndirectFunctionAnalysis> {
928   struct Result {
929     Result(TestFunctionAnalysis::Result &FDep, TestModuleAnalysis::Result &MDep,
930            TestSCCAnalysis::Result &SCCDep)
931         : FDep(FDep), MDep(MDep), SCCDep(SCCDep) {}
932     TestFunctionAnalysis::Result &FDep;
933     TestModuleAnalysis::Result &MDep;
934     TestSCCAnalysis::Result &SCCDep;
935 
936     bool invalidate(Function &F, const PreservedAnalyses &PA,
937                     FunctionAnalysisManager::Invalidator &Inv) {
938       auto PAC = PA.getChecker<TestIndirectFunctionAnalysis>();
939       return !(PAC.preserved() ||
940                PAC.preservedSet<AllAnalysesOn<Function>>()) ||
941              Inv.invalidate<TestFunctionAnalysis>(F, PA);
942     }
943   };
944 
945   TestIndirectFunctionAnalysis(int &Runs) : Runs(Runs) {}
946 
947   /// Run the analysis pass over the function and return a result.
948   Result run(Function &F, FunctionAnalysisManager &AM) {
949     ++Runs;
950     auto &FDep = AM.getResult<TestFunctionAnalysis>(F);
951 
952     auto &ModuleProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
953     const ModuleAnalysisManager &MAM = ModuleProxy.getManager();
954     // For the test, we insist that the module analysis starts off in the
955     // cache.
956     auto &MDep = *MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
957     // Register the dependency as module analysis dependencies have to be
958     // pre-registered on the proxy.
959     ModuleProxy.registerOuterAnalysisInvalidation<
960         TestModuleAnalysis, TestIndirectFunctionAnalysis>();
961 
962     // For thet test we assume this is run inside a CGSCC pass manager.
963     const LazyCallGraph &CG =
964         *MAM.getCachedResult<LazyCallGraphAnalysis>(*F.getParent());
965     auto &CGSCCProxy = AM.getResult<CGSCCAnalysisManagerFunctionProxy>(F);
966     const CGSCCAnalysisManager &CGAM = CGSCCProxy.getManager();
967     // For the test, we insist that the CGSCC analysis starts off in the cache.
968     auto &SCCDep =
969         *CGAM.getCachedResult<TestSCCAnalysis>(*CG.lookupSCC(*CG.lookup(F)));
970     // Register the dependency as CGSCC analysis dependencies have to be
971     // pre-registered on the proxy.
972     CGSCCProxy.registerOuterAnalysisInvalidation<
973         TestSCCAnalysis, TestIndirectFunctionAnalysis>();
974 
975     return Result(FDep, MDep, SCCDep);
976   }
977 
978 private:
979   friend AnalysisInfoMixin<TestIndirectFunctionAnalysis>;
980   static AnalysisKey Key;
981 
982   int &Runs;
983 };
984 
985 AnalysisKey TestIndirectFunctionAnalysis::Key;
986 
987 TEST_F(CGSCCPassManagerTest, TestIndirectAnalysisInvalidation) {
988   int ModuleAnalysisRuns = 0;
989   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
990 
991   int SCCAnalysisRuns = 0, IndirectSCCAnalysisRuns = 0,
992       DoublyIndirectSCCAnalysisRuns = 0;
993   CGAM.registerPass([&] { return TestSCCAnalysis(SCCAnalysisRuns); });
994   CGAM.registerPass(
995       [&] { return TestIndirectSCCAnalysis(IndirectSCCAnalysisRuns); });
996   CGAM.registerPass([&] {
997     return TestDoublyIndirectSCCAnalysis(DoublyIndirectSCCAnalysisRuns);
998   });
999 
1000   int FunctionAnalysisRuns = 0, IndirectFunctionAnalysisRuns = 0;
1001   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
1002   FAM.registerPass([&] {
1003     return TestIndirectFunctionAnalysis(IndirectFunctionAnalysisRuns);
1004   });
1005 
1006   ModulePassManager MPM(/*DebugLogging*/ true);
1007 
1008   int FunctionCount = 0;
1009   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1010   // First just use the analysis to get the function count and preserve
1011   // everything.
1012   CGPM.addPass(
1013       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1014                         LazyCallGraph &CG, CGSCCUpdateResult &) {
1015         auto &DoublyIndirectResult =
1016             AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1017         auto &IndirectResult = DoublyIndirectResult.IDep;
1018         FunctionCount += IndirectResult.SCCDep.FunctionCount;
1019         return PreservedAnalyses::all();
1020       }));
1021   CGPM.addPass(createCGSCCToFunctionPassAdaptor(
1022       RequireAnalysisPass<TestIndirectFunctionAnalysis, Function>()));
1023 
1024   // Next, invalidate
1025   //   - both analyses for the (f) and (x) SCCs,
1026   //   - just the underlying (indirect) analysis for (g) SCC, and
1027   //   - just the direct analysis for (h1,h2,h3) SCC.
1028   CGPM.addPass(
1029       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1030                         LazyCallGraph &CG, CGSCCUpdateResult &) {
1031         auto &DoublyIndirectResult =
1032             AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1033         auto &IndirectResult = DoublyIndirectResult.IDep;
1034         FunctionCount += IndirectResult.SCCDep.FunctionCount;
1035         auto PA = PreservedAnalyses::none();
1036         PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
1037         PA.preserveSet<AllAnalysesOn<Function>>();
1038         if (C.getName() == "(g)")
1039           PA.preserve<TestSCCAnalysis>();
1040         else if (C.getName() == "(h3, h1, h2)")
1041           PA.preserve<TestIndirectSCCAnalysis>();
1042         return PA;
1043       }));
1044   // Finally, use the analysis again on each SCC (and function), forcing
1045   // re-computation for all of them.
1046   CGPM.addPass(
1047       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1048                         LazyCallGraph &CG, CGSCCUpdateResult &) {
1049         auto &DoublyIndirectResult =
1050             AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1051         auto &IndirectResult = DoublyIndirectResult.IDep;
1052         FunctionCount += IndirectResult.SCCDep.FunctionCount;
1053         return PreservedAnalyses::all();
1054       }));
1055   CGPM.addPass(createCGSCCToFunctionPassAdaptor(
1056       RequireAnalysisPass<TestIndirectFunctionAnalysis, Function>()));
1057 
1058   // Create a second CGSCC pass manager. This will cause the module-level
1059   // invalidation to occur, which will force yet another invalidation of the
1060   // indirect SCC-level analysis as the module analysis it depends on gets
1061   // invalidated.
1062   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
1063   CGPM2.addPass(
1064       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1065                         LazyCallGraph &CG, CGSCCUpdateResult &) {
1066         auto &DoublyIndirectResult =
1067             AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1068         auto &IndirectResult = DoublyIndirectResult.IDep;
1069         FunctionCount += IndirectResult.SCCDep.FunctionCount;
1070         return PreservedAnalyses::all();
1071       }));
1072   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(
1073       RequireAnalysisPass<TestIndirectFunctionAnalysis, Function>()));
1074 
1075   // Add a requires pass to populate the module analysis and then our CGSCC
1076   // pass pipeline.
1077   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1078   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1079   // Now require the module analysis again (it will have been invalidated once)
1080   // and then use it again from our second CGSCC pipeline..
1081   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1082   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
1083   MPM.run(*M, MAM);
1084 
1085   // There are generally two possible runs for each of the four SCCs. But
1086   // for one SCC, we only invalidate the indirect analysis so the base one
1087   // only gets run seven times.
1088   EXPECT_EQ(7, SCCAnalysisRuns);
1089   // The module analysis pass should be run twice here.
1090   EXPECT_EQ(2, ModuleAnalysisRuns);
1091   // The indirect analysis is invalidated (either directly or indirectly) three
1092   // times for each of four SCCs.
1093   EXPECT_EQ(3 * 4, IndirectSCCAnalysisRuns);
1094   EXPECT_EQ(3 * 4, DoublyIndirectSCCAnalysisRuns);
1095 
1096   // We run the indirect function analysis once per function the first time.
1097   // Then we re-run it for every SCC but "(g)". Then we re-run it for every
1098   // function again.
1099   EXPECT_EQ(6 + 5 + 6, IndirectFunctionAnalysisRuns);
1100 
1101   // Four passes count each of six functions once (via SCCs).
1102   EXPECT_EQ(4 * 6, FunctionCount);
1103 }
1104 
1105 TEST_F(CGSCCPassManagerTest, TestAnalysisInvalidationCGSCCUpdate) {
1106   int ModuleAnalysisRuns = 0;
1107   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
1108 
1109   int SCCAnalysisRuns = 0, IndirectSCCAnalysisRuns = 0,
1110       DoublyIndirectSCCAnalysisRuns = 0;
1111   CGAM.registerPass([&] { return TestSCCAnalysis(SCCAnalysisRuns); });
1112   CGAM.registerPass(
1113       [&] { return TestIndirectSCCAnalysis(IndirectSCCAnalysisRuns); });
1114   CGAM.registerPass([&] {
1115     return TestDoublyIndirectSCCAnalysis(DoublyIndirectSCCAnalysisRuns);
1116   });
1117 
1118   int FunctionAnalysisRuns = 0, IndirectFunctionAnalysisRuns = 0;
1119   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
1120   FAM.registerPass([&] {
1121     return TestIndirectFunctionAnalysis(IndirectFunctionAnalysisRuns);
1122   });
1123 
1124   ModulePassManager MPM(/*DebugLogging*/ true);
1125 
1126   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1127   // First just use the analysis to get the function count and preserve
1128   // everything.
1129   using RequireTestIndirectFunctionAnalysisPass =
1130       RequireAnalysisPass<TestIndirectFunctionAnalysis, Function>;
1131   using RequireTestDoublyIndirectSCCAnalysisPass =
1132       RequireAnalysisPass<TestDoublyIndirectSCCAnalysis, LazyCallGraph::SCC,
1133                           CGSCCAnalysisManager, LazyCallGraph &,
1134                           CGSCCUpdateResult &>;
1135   CGPM.addPass(RequireTestDoublyIndirectSCCAnalysisPass());
1136   CGPM.addPass(createCGSCCToFunctionPassAdaptor(
1137       RequireTestIndirectFunctionAnalysisPass()));
1138 
1139   // Next, we inject an SCC pass that invalidates everything for the `(h3, h1,
1140   // h2)` SCC but also deletes the call edge from `h2` to `h3` and updates the
1141   // CG. This should successfully invalidate (and force to be re-run) all the
1142   // analyses for that SCC and for the functions.
1143   CGPM.addPass(
1144       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1145                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
1146         (void)AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1147         if (C.getName() != "(h3, h1, h2)")
1148           return PreservedAnalyses::all();
1149 
1150         // Build the preserved set.
1151         auto PA = PreservedAnalyses::none();
1152         PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
1153         PA.preserve<TestIndirectSCCAnalysis>();
1154         PA.preserve<TestDoublyIndirectSCCAnalysis>();
1155 
1156         // Delete the call from `h2` to `h3`.
1157         auto &H2N = *llvm::find_if(
1158             C, [](LazyCallGraph::Node &N) { return N.getName() == "h2"; });
1159         auto &H2F = H2N.getFunction();
1160         auto &H3F = *cast<CallInst>(H2F.begin()->begin())->getCalledFunction();
1161         assert(H3F.getName() == "h3" && "Wrong called function!");
1162         H2F.begin()->begin()->eraseFromParent();
1163         // Insert a bitcast of `h3` so that we retain a ref edge to it.
1164         (void)CastInst::CreatePointerCast(&H3F,
1165                                           Type::getInt8PtrTy(H2F.getContext()),
1166                                           "dummy", &*H2F.begin()->begin());
1167 
1168         // Now update the call graph.
1169         auto &NewC = updateCGAndAnalysisManagerForFunctionPass(
1170             CG, C, H2N, AM, UR, /*DebugLogging*/ true);
1171         assert(&NewC != &C && "Should get a new SCC due to update!");
1172         (void)&NewC;
1173 
1174         return PA;
1175       }));
1176   // Now use the analysis again on each SCC and function, forcing
1177   // re-computation for all of them.
1178   CGPM.addPass(RequireTestDoublyIndirectSCCAnalysisPass());
1179   CGPM.addPass(createCGSCCToFunctionPassAdaptor(
1180       RequireTestIndirectFunctionAnalysisPass()));
1181 
1182   // Create another CGSCC pipeline that requires all the analyses again.
1183   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
1184   CGPM2.addPass(RequireTestDoublyIndirectSCCAnalysisPass());
1185   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(
1186       RequireTestIndirectFunctionAnalysisPass()));
1187 
1188   // Next we inject an SCC pass that finds the `(h2)` SCC, adds a call to `h3`
1189   // back to `h2`, and then invalidates everything for what will then be the
1190   // `(h3, h1, h2)` SCC again.
1191   CGSCCPassManager CGPM3(/*DebugLogging*/ true);
1192   CGPM3.addPass(
1193       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1194                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
1195         (void)AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1196         if (C.getName() != "(h2)")
1197           return PreservedAnalyses::all();
1198 
1199         // Build the preserved set.
1200         auto PA = PreservedAnalyses::none();
1201         PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
1202         PA.preserve<TestIndirectSCCAnalysis>();
1203         PA.preserve<TestDoublyIndirectSCCAnalysis>();
1204 
1205         // Delete the bitcast of `h3` that we added earlier.
1206         auto &H2N = *C.begin();
1207         auto &H2F = H2N.getFunction();
1208         auto &H3F = *cast<Function>(cast<BitCastInst>(H2F.begin()->begin())->getOperand(0));
1209         assert(H3F.getName() == "h3" && "Wrong called function!");
1210         H2F.begin()->begin()->eraseFromParent();
1211         // And insert a call to `h3`.
1212         (void)CallInst::Create(&H3F, {}, "", &*H2F.begin()->begin());
1213 
1214         // Now update the call graph.
1215         auto &NewC = updateCGAndAnalysisManagerForFunctionPass(
1216             CG, C, H2N, AM, UR, /*DebugLogging*/ true);
1217         assert(&NewC != &C && "Should get a new SCC due to update!");
1218         (void)&NewC;
1219 
1220         return PA;
1221       }));
1222   // Now use the analysis again on each SCC and function, forcing
1223   // re-computation for all of them.
1224   CGPM3.addPass(RequireTestDoublyIndirectSCCAnalysisPass());
1225   CGPM3.addPass(createCGSCCToFunctionPassAdaptor(
1226       RequireTestIndirectFunctionAnalysisPass()));
1227 
1228   // Create a second CGSCC pass manager. This will cause the module-level
1229   // invalidation to occur, which will force yet another invalidation of the
1230   // indirect SCC-level analysis as the module analysis it depends on gets
1231   // invalidated.
1232   CGSCCPassManager CGPM4(/*DebugLogging*/ true);
1233   CGPM4.addPass(RequireTestDoublyIndirectSCCAnalysisPass());
1234   CGPM4.addPass(createCGSCCToFunctionPassAdaptor(
1235       RequireTestIndirectFunctionAnalysisPass()));
1236 
1237   // Add a requires pass to populate the module analysis and then one of our
1238   // CGSCC pipelines. Repeat for all four CGSCC pipelines.
1239   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1240   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1241   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1242   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
1243   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1244   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM3)));
1245   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1246   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM4)));
1247   MPM.run(*M, MAM);
1248 
1249   // We run over four SCCs the first time. But then we split an SCC into three.
1250   // And then we merge those three back into one.
1251   EXPECT_EQ(4 + 3 + 1, SCCAnalysisRuns);
1252   // The module analysis pass should be run three times.
1253   EXPECT_EQ(3, ModuleAnalysisRuns);
1254   // We run over four SCCs the first time. Then over the two new ones. Then the
1255   // entire module is invalidated causing a full run over all seven. Then we
1256   // fold three SCCs back to one, and then run over the whole module again.
1257   EXPECT_EQ(4 + 2 + 7 + 1 + 4, IndirectSCCAnalysisRuns);
1258   EXPECT_EQ(4 + 2 + 7 + 1 + 4, DoublyIndirectSCCAnalysisRuns);
1259 
1260   // First we run over all six functions. Then we re-run it over three when we
1261   // split their SCCs. Then we re-run over the whole module. Then we re-run
1262   // over three functions merged back into a single SCC, and then over the
1263   // whole module again.
1264   EXPECT_EQ(6 + 2 + 6 + 3 + 6, FunctionAnalysisRuns);
1265 
1266   // Re run the function analysis twice over the entire module, and then re-run
1267   // it over the `(h3, h1, h2)` SCC due to invalidation. Then we re-un over
1268   // three functions merged back into a single SCC, and then over the whole
1269   // module.
1270   EXPECT_EQ(6 + 2 + 6 + 3 + 6, IndirectFunctionAnalysisRuns);
1271 }
1272 }
1273