1 //===- CGSCCPassManagerTest.cpp -------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/Analysis/CGSCCPassManager.h"
10 #include "llvm/Analysis/LazyCallGraph.h"
11 #include "llvm/Analysis/TargetLibraryInfo.h"
12 #include "llvm/AsmParser/Parser.h"
13 #include "llvm/IR/Function.h"
14 #include "llvm/IR/InstIterator.h"
15 #include "llvm/IR/LLVMContext.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/IR/PassManager.h"
18 #include "llvm/Support/SourceMgr.h"
19 #include "llvm/Transforms/Utils/CallGraphUpdater.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     bool invalidate(Module &, const PreservedAnalyses &PA,
32                     ModuleAnalysisManager::Invalidator &) {
33       // Check whether the analysis or all analyses on modules have been
34       // preserved.
35       auto PAC = PA.getChecker<TestModuleAnalysis>();
36       return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Module>>());
37     }
38   };
39 
40   TestModuleAnalysis(int &Runs) : Runs(Runs) {}
41 
42   Result run(Module &M, ModuleAnalysisManager &AM) {
43     ++Runs;
44     return Result(M.size());
45   }
46 
47 private:
48   friend AnalysisInfoMixin<TestModuleAnalysis>;
49   static AnalysisKey Key;
50 
51   int &Runs;
52 };
53 
54 AnalysisKey TestModuleAnalysis::Key;
55 
56 class TestSCCAnalysis : public AnalysisInfoMixin<TestSCCAnalysis> {
57 public:
58   struct Result {
59     Result(int Count) : FunctionCount(Count) {}
60     int FunctionCount;
61     bool invalidate(LazyCallGraph::SCC &, const PreservedAnalyses &PA,
62                     CGSCCAnalysisManager::Invalidator &) {
63       // Check whether the analysis or all analyses on SCCs have been
64       // preserved.
65       auto PAC = PA.getChecker<TestSCCAnalysis>();
66       return !(PAC.preserved() ||
67                PAC.preservedSet<AllAnalysesOn<LazyCallGraph::SCC>>());
68     }
69   };
70 
71   TestSCCAnalysis(int &Runs) : Runs(Runs) {}
72 
73   Result run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &) {
74     ++Runs;
75     return Result(C.size());
76   }
77 
78 private:
79   friend AnalysisInfoMixin<TestSCCAnalysis>;
80   static AnalysisKey Key;
81 
82   int &Runs;
83 };
84 
85 AnalysisKey TestSCCAnalysis::Key;
86 
87 class TestFunctionAnalysis : public AnalysisInfoMixin<TestFunctionAnalysis> {
88 public:
89   struct Result {
90     Result(int Count) : InstructionCount(Count) {}
91     int InstructionCount;
92     bool invalidate(Function &, const PreservedAnalyses &PA,
93                     FunctionAnalysisManager::Invalidator &) {
94       // Check whether the analysis or all analyses on functions have been
95       // preserved.
96       auto PAC = PA.getChecker<TestFunctionAnalysis>();
97       return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>());
98     }
99   };
100 
101   TestFunctionAnalysis(int &Runs) : Runs(Runs) {}
102 
103   Result run(Function &F, FunctionAnalysisManager &AM) {
104     ++Runs;
105     int Count = 0;
106     for (Instruction &I : instructions(F)) {
107       (void)I;
108       ++Count;
109     }
110     return Result(Count);
111   }
112 
113 private:
114   friend AnalysisInfoMixin<TestFunctionAnalysis>;
115   static AnalysisKey Key;
116 
117   int &Runs;
118 };
119 
120 AnalysisKey TestFunctionAnalysis::Key;
121 
122 class TestImmutableFunctionAnalysis
123     : public AnalysisInfoMixin<TestImmutableFunctionAnalysis> {
124 public:
125   struct Result {
126     bool invalidate(Function &, const PreservedAnalyses &,
127                     FunctionAnalysisManager::Invalidator &) {
128       return false;
129     }
130   };
131 
132   TestImmutableFunctionAnalysis(int &Runs) : Runs(Runs) {}
133 
134   Result run(Function &F, FunctionAnalysisManager &AM) {
135     ++Runs;
136     return Result();
137   }
138 
139 private:
140   friend AnalysisInfoMixin<TestImmutableFunctionAnalysis>;
141   static AnalysisKey Key;
142 
143   int &Runs;
144 };
145 
146 AnalysisKey TestImmutableFunctionAnalysis::Key;
147 
148 struct LambdaModulePass : public PassInfoMixin<LambdaModulePass> {
149   template <typename T>
150   LambdaModulePass(T &&Arg) : Func(std::forward<T>(Arg)) {}
151 
152   PreservedAnalyses run(Module &F, ModuleAnalysisManager &AM) {
153     return Func(F, AM);
154   }
155 
156   std::function<PreservedAnalyses(Module &, ModuleAnalysisManager &)> Func;
157 };
158 
159 struct LambdaSCCPass : public PassInfoMixin<LambdaSCCPass> {
160   template <typename T> LambdaSCCPass(T &&Arg) : Func(std::forward<T>(Arg)) {}
161 
162   PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
163                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
164     return Func(C, AM, CG, UR);
165   }
166 
167   std::function<PreservedAnalyses(LazyCallGraph::SCC &, CGSCCAnalysisManager &,
168                                   LazyCallGraph &, CGSCCUpdateResult &)>
169       Func;
170 };
171 
172 struct LambdaFunctionPass : public PassInfoMixin<LambdaFunctionPass> {
173   template <typename T>
174   LambdaFunctionPass(T &&Arg) : Func(std::forward<T>(Arg)) {}
175 
176   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
177     return Func(F, AM);
178   }
179 
180   std::function<PreservedAnalyses(Function &, FunctionAnalysisManager &)> Func;
181 };
182 
183 std::unique_ptr<Module> parseIR(const char *IR) {
184   // We just use a static context here. This is never called from multiple
185   // threads so it is harmless no matter how it is implemented. We just need
186   // the context to outlive the module which it does.
187   static LLVMContext C;
188   SMDiagnostic Err;
189   return parseAssemblyString(IR, Err, C);
190 }
191 
192 class CGSCCPassManagerTest : public ::testing::Test {
193 protected:
194   LLVMContext Context;
195   FunctionAnalysisManager FAM;
196   CGSCCAnalysisManager CGAM;
197   ModuleAnalysisManager MAM;
198 
199   std::unique_ptr<Module> M;
200 
201 public:
202   CGSCCPassManagerTest()
203       : FAM(/*DebugLogging*/ true), CGAM(/*DebugLogging*/ true),
204         MAM(/*DebugLogging*/ true),
205         M(parseIR(
206             // Define a module with the following call graph, where calls go
207             // out the bottom of nodes and enter the top:
208             //
209             // f
210             // |\   _
211             // | \ / |
212             // g  h1 |
213             // |  |  |
214             // |  h2 |
215             // |  |  |
216             // |  h3 |
217             // | / \_/
218             // |/
219             // x
220             //
221             "define void @f() {\n"
222             "entry:\n"
223             "  call void @g()\n"
224             "  call void @h1()\n"
225             "  ret void\n"
226             "}\n"
227             "define void @g() {\n"
228             "entry:\n"
229             "  call void @g()\n"
230             "  call void @x()\n"
231             "  ret void\n"
232             "}\n"
233             "define void @h1() {\n"
234             "entry:\n"
235             "  call void @h2()\n"
236             "  ret void\n"
237             "}\n"
238             "define void @h2() {\n"
239             "entry:\n"
240             "  call void @h3()\n"
241             "  call void @x()\n"
242             "  ret void\n"
243             "}\n"
244             "define void @h3() {\n"
245             "entry:\n"
246             "  call void @h1()\n"
247             "  ret void\n"
248             "}\n"
249             "define void @x() {\n"
250             "entry:\n"
251             "  ret void\n"
252             "}\n")) {
253     FAM.registerPass([&] { return TargetLibraryAnalysis(); });
254     MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
255     MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
256 
257     // Register required pass instrumentation analysis.
258     MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
259     CGAM.registerPass([&] { return PassInstrumentationAnalysis(); });
260     FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
261 
262     // Cross-register proxies.
263     MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
264     CGAM.registerPass([&] { return FunctionAnalysisManagerCGSCCProxy(); });
265     CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
266     FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
267     FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
268   }
269 };
270 
271 TEST_F(CGSCCPassManagerTest, Basic) {
272   int FunctionAnalysisRuns = 0;
273   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
274   int ImmutableFunctionAnalysisRuns = 0;
275   FAM.registerPass([&] {
276     return TestImmutableFunctionAnalysis(ImmutableFunctionAnalysisRuns);
277   });
278 
279   int SCCAnalysisRuns = 0;
280   CGAM.registerPass([&] { return TestSCCAnalysis(SCCAnalysisRuns); });
281 
282   int ModuleAnalysisRuns = 0;
283   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
284 
285   ModulePassManager MPM(/*DebugLogging*/ true);
286   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
287 
288   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
289   FunctionPassManager FPM1(/*DebugLogging*/ true);
290   int FunctionPassRunCount1 = 0;
291   FPM1.addPass(LambdaFunctionPass([&](Function &, FunctionAnalysisManager &) {
292     ++FunctionPassRunCount1;
293     return PreservedAnalyses::none();
294   }));
295   CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
296 
297   int SCCPassRunCount1 = 0;
298   int AnalyzedInstrCount1 = 0;
299   int AnalyzedSCCFunctionCount1 = 0;
300   int AnalyzedModuleFunctionCount1 = 0;
301   CGPM1.addPass(
302       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
303                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
304         ++SCCPassRunCount1;
305 
306         const ModuleAnalysisManager &MAM =
307             AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG).getManager();
308         FunctionAnalysisManager &FAM =
309             AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
310         if (TestModuleAnalysis::Result *TMA =
311                 MAM.getCachedResult<TestModuleAnalysis>(
312                     *C.begin()->getFunction().getParent()))
313           AnalyzedModuleFunctionCount1 += TMA->FunctionCount;
314 
315         TestSCCAnalysis::Result &AR = AM.getResult<TestSCCAnalysis>(C, CG);
316         AnalyzedSCCFunctionCount1 += AR.FunctionCount;
317         for (LazyCallGraph::Node &N : C) {
318           TestFunctionAnalysis::Result &FAR =
319               FAM.getResult<TestFunctionAnalysis>(N.getFunction());
320           AnalyzedInstrCount1 += FAR.InstructionCount;
321 
322           // Just ensure we get the immutable results.
323           (void)FAM.getResult<TestImmutableFunctionAnalysis>(N.getFunction());
324         }
325 
326         return PreservedAnalyses::all();
327       }));
328 
329   FunctionPassManager FPM2(/*DebugLogging*/ true);
330   int FunctionPassRunCount2 = 0;
331   FPM2.addPass(LambdaFunctionPass([&](Function &, FunctionAnalysisManager &) {
332     ++FunctionPassRunCount2;
333     return PreservedAnalyses::none();
334   }));
335   CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
336 
337   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
338 
339   FunctionPassManager FPM3(/*DebugLogging*/ true);
340   int FunctionPassRunCount3 = 0;
341   FPM3.addPass(LambdaFunctionPass([&](Function &, FunctionAnalysisManager &) {
342     ++FunctionPassRunCount3;
343     return PreservedAnalyses::none();
344   }));
345   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM3)));
346 
347   MPM.run(*M, MAM);
348 
349   EXPECT_EQ(4, SCCPassRunCount1);
350   EXPECT_EQ(6, FunctionPassRunCount1);
351   EXPECT_EQ(6, FunctionPassRunCount2);
352   EXPECT_EQ(6, FunctionPassRunCount3);
353 
354   EXPECT_EQ(1, ModuleAnalysisRuns);
355   EXPECT_EQ(4, SCCAnalysisRuns);
356   EXPECT_EQ(6, FunctionAnalysisRuns);
357   EXPECT_EQ(6, ImmutableFunctionAnalysisRuns);
358 
359   EXPECT_EQ(14, AnalyzedInstrCount1);
360   EXPECT_EQ(6, AnalyzedSCCFunctionCount1);
361   EXPECT_EQ(4 * 6, AnalyzedModuleFunctionCount1);
362 }
363 
364 // Test that an SCC pass which fails to preserve a module analysis does in fact
365 // invalidate that module analysis.
366 TEST_F(CGSCCPassManagerTest, TestSCCPassInvalidatesModuleAnalysis) {
367   int ModuleAnalysisRuns = 0;
368   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
369 
370   ModulePassManager MPM(/*DebugLogging*/ true);
371   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
372 
373   // The first CGSCC run we preserve everything and make sure that works and
374   // the module analysis is available in the second CGSCC run from the one
375   // required module pass above.
376   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
377   int CountFoundModuleAnalysis1 = 0;
378   CGPM1.addPass(
379       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
380                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
381         const auto &MAM =
382             AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG).getManager();
383         auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(
384             *C.begin()->getFunction().getParent());
385 
386         if (TMA)
387           ++CountFoundModuleAnalysis1;
388 
389         return PreservedAnalyses::all();
390       }));
391   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
392 
393   // The second CGSCC run checks that the module analysis got preserved the
394   // previous time and in one SCC fails to preserve it.
395   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
396   int CountFoundModuleAnalysis2 = 0;
397   CGPM2.addPass(
398       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
399                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
400         const auto &MAM =
401             AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG).getManager();
402         auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(
403             *C.begin()->getFunction().getParent());
404 
405         if (TMA)
406           ++CountFoundModuleAnalysis2;
407 
408         // Only fail to preserve analyses on one SCC and make sure that gets
409         // propagated.
410         return C.getName() == "(g)" ? PreservedAnalyses::none()
411                                   : PreservedAnalyses::all();
412       }));
413   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
414 
415   // The third CGSCC run should fail to find a cached module analysis as it
416   // should have been invalidated by the above CGSCC run.
417   CGSCCPassManager CGPM3(/*DebugLogging*/ true);
418   int CountFoundModuleAnalysis3 = 0;
419   CGPM3.addPass(
420       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
421                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
422         const auto &MAM =
423             AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG).getManager();
424         auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(
425             *C.begin()->getFunction().getParent());
426 
427         if (TMA)
428           ++CountFoundModuleAnalysis3;
429 
430         return PreservedAnalyses::none();
431       }));
432   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM3)));
433 
434   MPM.run(*M, MAM);
435 
436   EXPECT_EQ(1, ModuleAnalysisRuns);
437   EXPECT_EQ(4, CountFoundModuleAnalysis1);
438   EXPECT_EQ(4, CountFoundModuleAnalysis2);
439   EXPECT_EQ(0, CountFoundModuleAnalysis3);
440 }
441 
442 // Similar to the above, but test that this works for function passes embedded
443 // *within* a CGSCC layer.
444 TEST_F(CGSCCPassManagerTest, TestFunctionPassInsideCGSCCInvalidatesModuleAnalysis) {
445   int ModuleAnalysisRuns = 0;
446   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
447 
448   ModulePassManager MPM(/*DebugLogging*/ true);
449   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
450 
451   // The first run we preserve everything and make sure that works and the
452   // module analysis is available in the second run from the one required
453   // module pass above.
454   FunctionPassManager FPM1(/*DebugLogging*/ true);
455   // Start true and mark false if we ever failed to find a module analysis
456   // because we expect this to succeed for each SCC.
457   bool FoundModuleAnalysis1 = true;
458   FPM1.addPass(
459       LambdaFunctionPass([&](Function &F, FunctionAnalysisManager &AM) {
460         const auto &MAM =
461             AM.getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
462         auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
463 
464         if (!TMA)
465           FoundModuleAnalysis1 = false;
466 
467         return PreservedAnalyses::all();
468       }));
469   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
470   CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
471   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
472 
473   // The second run checks that the module analysis got preserved the previous
474   // time and in one function fails to preserve it.
475   FunctionPassManager FPM2(/*DebugLogging*/ true);
476   // Again, start true and mark false if we ever failed to find a module analysis
477   // because we expect this to succeed for each SCC.
478   bool FoundModuleAnalysis2 = true;
479   FPM2.addPass(
480       LambdaFunctionPass([&](Function &F, FunctionAnalysisManager &AM) {
481         const auto &MAM =
482             AM.getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
483         auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
484 
485         if (!TMA)
486           FoundModuleAnalysis2 = false;
487 
488         // Only fail to preserve analyses on one SCC and make sure that gets
489         // propagated.
490         return F.getName() == "h2" ? PreservedAnalyses::none()
491                                    : PreservedAnalyses::all();
492       }));
493   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
494   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
495   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
496 
497   // The third run should fail to find a cached module analysis as it should
498   // have been invalidated by the above run.
499   FunctionPassManager FPM3(/*DebugLogging*/ true);
500   // Start false and mark true if we ever *succeeded* to find a module
501   // analysis, as we expect this to fail for every function.
502   bool FoundModuleAnalysis3 = false;
503   FPM3.addPass(
504       LambdaFunctionPass([&](Function &F, FunctionAnalysisManager &AM) {
505         const auto &MAM =
506             AM.getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
507         auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
508 
509         if (TMA)
510           FoundModuleAnalysis3 = true;
511 
512         return PreservedAnalyses::none();
513       }));
514   CGSCCPassManager CGPM3(/*DebugLogging*/ true);
515   CGPM3.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM3)));
516   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM3)));
517 
518   MPM.run(*M, MAM);
519 
520   EXPECT_EQ(1, ModuleAnalysisRuns);
521   EXPECT_TRUE(FoundModuleAnalysis1);
522   EXPECT_TRUE(FoundModuleAnalysis2);
523   EXPECT_FALSE(FoundModuleAnalysis3);
524 }
525 
526 // Test that a Module pass which fails to preserve an SCC analysis in fact
527 // invalidates that analysis.
528 TEST_F(CGSCCPassManagerTest, TestModulePassInvalidatesSCCAnalysis) {
529   int SCCAnalysisRuns = 0;
530   CGAM.registerPass([&] { return TestSCCAnalysis(SCCAnalysisRuns); });
531 
532   ModulePassManager MPM(/*DebugLogging*/ true);
533 
534   // First force the analysis to be run.
535   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
536   CGPM1.addPass(RequireAnalysisPass<TestSCCAnalysis, LazyCallGraph::SCC,
537                                     CGSCCAnalysisManager, LazyCallGraph &,
538                                     CGSCCUpdateResult &>());
539   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
540 
541   // Now run a module pass that preserves the LazyCallGraph and the proxy but
542   // not the SCC analysis.
543   MPM.addPass(LambdaModulePass([&](Module &M, ModuleAnalysisManager &) {
544     PreservedAnalyses PA;
545     PA.preserve<LazyCallGraphAnalysis>();
546     PA.preserve<CGSCCAnalysisManagerModuleProxy>();
547     PA.preserve<FunctionAnalysisManagerModuleProxy>();
548     return PA;
549   }));
550 
551   // And now a second CGSCC run which requires the SCC analysis again. This
552   // will trigger re-running it.
553   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
554   CGPM2.addPass(RequireAnalysisPass<TestSCCAnalysis, LazyCallGraph::SCC,
555                                     CGSCCAnalysisManager, LazyCallGraph &,
556                                     CGSCCUpdateResult &>());
557   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
558 
559   MPM.run(*M, MAM);
560   // Two runs and four SCCs.
561   EXPECT_EQ(2 * 4, SCCAnalysisRuns);
562 }
563 
564 // Check that marking the SCC analysis preserved is sufficient to avoid
565 // invaliadtion. This should only run the analysis once for each SCC.
566 TEST_F(CGSCCPassManagerTest, TestModulePassCanPreserveSCCAnalysis) {
567   int SCCAnalysisRuns = 0;
568   CGAM.registerPass([&] { return TestSCCAnalysis(SCCAnalysisRuns); });
569 
570   ModulePassManager MPM(/*DebugLogging*/ true);
571 
572   // First force the analysis to be run.
573   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
574   CGPM1.addPass(RequireAnalysisPass<TestSCCAnalysis, LazyCallGraph::SCC,
575                                     CGSCCAnalysisManager, LazyCallGraph &,
576                                     CGSCCUpdateResult &>());
577   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
578 
579   // Now run a module pass that preserves each of the necessary components
580   // (but not everything).
581   MPM.addPass(LambdaModulePass([&](Module &M, ModuleAnalysisManager &) {
582     PreservedAnalyses PA;
583     PA.preserve<LazyCallGraphAnalysis>();
584     PA.preserve<CGSCCAnalysisManagerModuleProxy>();
585     PA.preserve<FunctionAnalysisManagerModuleProxy>();
586     PA.preserve<TestSCCAnalysis>();
587     return PA;
588   }));
589 
590   // And now a second CGSCC run which requires the SCC analysis again but find
591   // it in the cache.
592   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
593   CGPM2.addPass(RequireAnalysisPass<TestSCCAnalysis, LazyCallGraph::SCC,
594                                     CGSCCAnalysisManager, LazyCallGraph &,
595                                     CGSCCUpdateResult &>());
596   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
597 
598   MPM.run(*M, MAM);
599   // Four SCCs
600   EXPECT_EQ(4, SCCAnalysisRuns);
601 }
602 
603 // Check that even when the analysis is preserved, if the SCC information isn't
604 // we still nuke things because the SCC keys could change.
605 TEST_F(CGSCCPassManagerTest, TestModulePassInvalidatesSCCAnalysisOnCGChange) {
606   int SCCAnalysisRuns = 0;
607   CGAM.registerPass([&] { return TestSCCAnalysis(SCCAnalysisRuns); });
608 
609   ModulePassManager MPM(/*DebugLogging*/ true);
610 
611   // First force the analysis to be run.
612   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
613   CGPM1.addPass(RequireAnalysisPass<TestSCCAnalysis, LazyCallGraph::SCC,
614                                     CGSCCAnalysisManager, LazyCallGraph &,
615                                     CGSCCUpdateResult &>());
616   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
617 
618   // Now run a module pass that preserves the analysis but not the call
619   // graph or proxy.
620   MPM.addPass(LambdaModulePass([&](Module &M, ModuleAnalysisManager &) {
621     PreservedAnalyses PA;
622     PA.preserve<TestSCCAnalysis>();
623     return PA;
624   }));
625 
626   // And now a second CGSCC run which requires the SCC analysis again.
627   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
628   CGPM2.addPass(RequireAnalysisPass<TestSCCAnalysis, LazyCallGraph::SCC,
629                                     CGSCCAnalysisManager, LazyCallGraph &,
630                                     CGSCCUpdateResult &>());
631   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
632 
633   MPM.run(*M, MAM);
634   // Two runs and four SCCs.
635   EXPECT_EQ(2 * 4, SCCAnalysisRuns);
636 }
637 
638 // Test that an SCC pass which fails to preserve a Function analysis in fact
639 // invalidates that analysis.
640 TEST_F(CGSCCPassManagerTest, TestSCCPassInvalidatesFunctionAnalysis) {
641   int FunctionAnalysisRuns = 0;
642   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
643 
644   // Create a very simple module with a single function and SCC to make testing
645   // these issues much easier.
646   std::unique_ptr<Module> M = parseIR("declare void @g()\n"
647                                       "declare void @h()\n"
648                                       "define void @f() {\n"
649                                       "entry:\n"
650                                       "  call void @g()\n"
651                                       "  call void @h()\n"
652                                       "  ret void\n"
653                                       "}\n");
654 
655   CGSCCPassManager CGPM(/*DebugLogging*/ true);
656 
657   // First force the analysis to be run.
658   FunctionPassManager FPM1(/*DebugLogging*/ true);
659   FPM1.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
660   CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
661 
662   // Now run a module pass that preserves the LazyCallGraph and proxy but not
663   // the SCC analysis.
664   CGPM.addPass(LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &,
665                                  LazyCallGraph &, CGSCCUpdateResult &) {
666     PreservedAnalyses PA;
667     PA.preserve<LazyCallGraphAnalysis>();
668     return PA;
669   }));
670 
671   // And now a second CGSCC run which requires the SCC analysis again. This
672   // will trigger re-running it.
673   FunctionPassManager FPM2(/*DebugLogging*/ true);
674   FPM2.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
675   CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
676 
677   ModulePassManager MPM(/*DebugLogging*/ true);
678   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
679   MPM.run(*M, MAM);
680   EXPECT_EQ(2, FunctionAnalysisRuns);
681 }
682 
683 // Check that marking the SCC analysis preserved is sufficient. This should
684 // only run the analysis once the SCC.
685 TEST_F(CGSCCPassManagerTest, TestSCCPassCanPreserveFunctionAnalysis) {
686   int FunctionAnalysisRuns = 0;
687   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
688 
689   // Create a very simple module with a single function and SCC to make testing
690   // these issues much easier.
691   std::unique_ptr<Module> M = parseIR("declare void @g()\n"
692                                       "declare void @h()\n"
693                                       "define void @f() {\n"
694                                       "entry:\n"
695                                       "  call void @g()\n"
696                                       "  call void @h()\n"
697                                       "  ret void\n"
698                                       "}\n");
699 
700   CGSCCPassManager CGPM(/*DebugLogging*/ true);
701 
702   // First force the analysis to be run.
703   FunctionPassManager FPM1(/*DebugLogging*/ true);
704   FPM1.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
705   CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
706 
707   // Now run a module pass that preserves each of the necessary components
708   // (but
709   // not everything).
710   CGPM.addPass(LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &,
711                                  LazyCallGraph &, CGSCCUpdateResult &) {
712     PreservedAnalyses PA;
713     PA.preserve<LazyCallGraphAnalysis>();
714     PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
715     PA.preserve<TestFunctionAnalysis>();
716     return PA;
717   }));
718 
719   // And now a second CGSCC run which requires the SCC analysis again but find
720   // it in the cache.
721   FunctionPassManager FPM2(/*DebugLogging*/ true);
722   FPM2.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
723   CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
724 
725   ModulePassManager MPM(/*DebugLogging*/ true);
726   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
727   MPM.run(*M, MAM);
728   EXPECT_EQ(1, FunctionAnalysisRuns);
729 }
730 
731 // Note that there is no test for invalidating the call graph or other
732 // structure with an SCC pass because there is no mechanism to do that from
733 // withinsuch a pass. Instead, such a pass has to directly update the call
734 // graph structure.
735 
736 // Test that a madule pass invalidates function analyses when the CGSCC proxies
737 // and pass manager.
738 TEST_F(CGSCCPassManagerTest,
739        TestModulePassInvalidatesFunctionAnalysisNestedInCGSCC) {
740   MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
741 
742   int FunctionAnalysisRuns = 0;
743   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
744 
745   ModulePassManager MPM(/*DebugLogging*/ true);
746 
747   // First force the analysis to be run.
748   FunctionPassManager FPM1(/*DebugLogging*/ true);
749   FPM1.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
750   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
751   CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
752   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
753 
754   // Now run a module pass that preserves the LazyCallGraph and proxies but not
755   // the Function analysis.
756   MPM.addPass(LambdaModulePass([&](Module &M, ModuleAnalysisManager &) {
757     PreservedAnalyses PA;
758     PA.preserve<LazyCallGraphAnalysis>();
759     PA.preserve<CGSCCAnalysisManagerModuleProxy>();
760     PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
761     PA.preserve<FunctionAnalysisManagerModuleProxy>();
762     return PA;
763   }));
764 
765   // And now a second CGSCC run which requires the SCC analysis again. This
766   // will trigger re-running it.
767   FunctionPassManager FPM2(/*DebugLogging*/ true);
768   FPM2.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
769   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
770   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
771   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
772 
773   MPM.run(*M, MAM);
774   // Two runs and 6 functions.
775   EXPECT_EQ(2 * 6, FunctionAnalysisRuns);
776 }
777 
778 // Check that by marking the function pass and proxies as preserved, this
779 // propagates all the way through.
780 TEST_F(CGSCCPassManagerTest,
781        TestModulePassCanPreserveFunctionAnalysisNestedInCGSCC) {
782   MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
783 
784   int FunctionAnalysisRuns = 0;
785   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
786 
787   ModulePassManager MPM(/*DebugLogging*/ true);
788 
789   // First force the analysis to be run.
790   FunctionPassManager FPM1(/*DebugLogging*/ true);
791   FPM1.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
792   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
793   CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
794   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
795 
796   // Now run a module pass that preserves the LazyCallGraph, the proxy, and
797   // the Function analysis.
798   MPM.addPass(LambdaModulePass([&](Module &M, ModuleAnalysisManager &) {
799     PreservedAnalyses PA;
800     PA.preserve<LazyCallGraphAnalysis>();
801     PA.preserve<CGSCCAnalysisManagerModuleProxy>();
802     PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
803     PA.preserve<FunctionAnalysisManagerModuleProxy>();
804     PA.preserve<TestFunctionAnalysis>();
805     return PA;
806   }));
807 
808   // And now a second CGSCC run which requires the SCC analysis again. This
809   // will trigger re-running it.
810   FunctionPassManager FPM2(/*DebugLogging*/ true);
811   FPM2.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
812   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
813   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
814   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
815 
816   MPM.run(*M, MAM);
817   // One run and 6 functions.
818   EXPECT_EQ(6, FunctionAnalysisRuns);
819 }
820 
821 // Check that if the lazy call graph itself isn't preserved we still manage to
822 // invalidate everything.
823 TEST_F(CGSCCPassManagerTest,
824        TestModulePassInvalidatesFunctionAnalysisNestedInCGSCCOnCGChange) {
825   MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
826 
827   int FunctionAnalysisRuns = 0;
828   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
829 
830   ModulePassManager MPM(/*DebugLogging*/ true);
831 
832   // First force the analysis to be run.
833   FunctionPassManager FPM1(/*DebugLogging*/ true);
834   FPM1.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
835   CGSCCPassManager CGPM1(/*DebugLogging*/ true);
836   CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
837   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
838 
839   // Now run a module pass that preserves the LazyCallGraph but not the
840   // Function analysis.
841   MPM.addPass(LambdaModulePass([&](Module &M, ModuleAnalysisManager &) {
842     PreservedAnalyses PA;
843     return PA;
844   }));
845 
846   // And now a second CGSCC run which requires the SCC analysis again. This
847   // will trigger re-running it.
848   FunctionPassManager FPM2(/*DebugLogging*/ true);
849   FPM2.addPass(RequireAnalysisPass<TestFunctionAnalysis, Function>());
850   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
851   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
852   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
853 
854   MPM.run(*M, MAM);
855   // Two runs and 6 functions.
856   EXPECT_EQ(2 * 6, FunctionAnalysisRuns);
857 }
858 
859 /// A test CGSCC-level analysis pass which caches in its result another
860 /// analysis pass and uses it to serve queries. This requires the result to
861 /// invalidate itself when its dependency is invalidated.
862 ///
863 /// FIXME: Currently this doesn't also depend on a function analysis, and if it
864 /// did we would fail to invalidate it correctly.
865 struct TestIndirectSCCAnalysis
866     : public AnalysisInfoMixin<TestIndirectSCCAnalysis> {
867   struct Result {
868     Result(TestSCCAnalysis::Result &SCCDep, TestModuleAnalysis::Result &MDep)
869         : SCCDep(SCCDep), MDep(MDep) {}
870     TestSCCAnalysis::Result &SCCDep;
871     TestModuleAnalysis::Result &MDep;
872 
873     bool invalidate(LazyCallGraph::SCC &C, const PreservedAnalyses &PA,
874                     CGSCCAnalysisManager::Invalidator &Inv) {
875       auto PAC = PA.getChecker<TestIndirectSCCAnalysis>();
876       return !(PAC.preserved() ||
877                PAC.preservedSet<AllAnalysesOn<LazyCallGraph::SCC>>()) ||
878              Inv.invalidate<TestSCCAnalysis>(C, PA);
879     }
880   };
881 
882   TestIndirectSCCAnalysis(int &Runs) : Runs(Runs) {}
883 
884   /// Run the analysis pass over the function and return a result.
885   Result run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
886              LazyCallGraph &CG) {
887     ++Runs;
888     auto &SCCDep = AM.getResult<TestSCCAnalysis>(C, CG);
889 
890     auto &ModuleProxy = AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG);
891     const ModuleAnalysisManager &MAM = ModuleProxy.getManager();
892     // For the test, we insist that the module analysis starts off in the
893     // cache.
894     auto &MDep = *MAM.getCachedResult<TestModuleAnalysis>(
895         *C.begin()->getFunction().getParent());
896     // Register the dependency as module analysis dependencies have to be
897     // pre-registered on the proxy.
898     ModuleProxy.registerOuterAnalysisInvalidation<TestModuleAnalysis,
899                                                   TestIndirectSCCAnalysis>();
900 
901     return Result(SCCDep, MDep);
902   }
903 
904 private:
905   friend AnalysisInfoMixin<TestIndirectSCCAnalysis>;
906   static AnalysisKey Key;
907 
908   int &Runs;
909 };
910 
911 AnalysisKey TestIndirectSCCAnalysis::Key;
912 
913 /// A test analysis pass which caches in its result the result from the above
914 /// indirect analysis pass.
915 ///
916 /// This allows us to ensure that whenever an analysis pass is invalidated due
917 /// to dependencies (especially dependencies across IR units that trigger
918 /// asynchronous invalidation) we correctly detect that this may in turn cause
919 /// other analysis to be invalidated.
920 struct TestDoublyIndirectSCCAnalysis
921     : public AnalysisInfoMixin<TestDoublyIndirectSCCAnalysis> {
922   struct Result {
923     Result(TestIndirectSCCAnalysis::Result &IDep) : IDep(IDep) {}
924     TestIndirectSCCAnalysis::Result &IDep;
925 
926     bool invalidate(LazyCallGraph::SCC &C, const PreservedAnalyses &PA,
927                     CGSCCAnalysisManager::Invalidator &Inv) {
928       auto PAC = PA.getChecker<TestDoublyIndirectSCCAnalysis>();
929       return !(PAC.preserved() ||
930                PAC.preservedSet<AllAnalysesOn<LazyCallGraph::SCC>>()) ||
931              Inv.invalidate<TestIndirectSCCAnalysis>(C, PA);
932     }
933   };
934 
935   TestDoublyIndirectSCCAnalysis(int &Runs) : Runs(Runs) {}
936 
937   /// Run the analysis pass over the function and return a result.
938   Result run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
939              LazyCallGraph &CG) {
940     ++Runs;
941     auto &IDep = AM.getResult<TestIndirectSCCAnalysis>(C, CG);
942     return Result(IDep);
943   }
944 
945 private:
946   friend AnalysisInfoMixin<TestDoublyIndirectSCCAnalysis>;
947   static AnalysisKey Key;
948 
949   int &Runs;
950 };
951 
952 AnalysisKey TestDoublyIndirectSCCAnalysis::Key;
953 
954 /// A test analysis pass which caches results from three different IR unit
955 /// layers and requires intermediate layers to correctly propagate the entire
956 /// distance.
957 struct TestIndirectFunctionAnalysis
958     : public AnalysisInfoMixin<TestIndirectFunctionAnalysis> {
959   struct Result {
960     Result(TestFunctionAnalysis::Result &FDep, TestModuleAnalysis::Result &MDep,
961            TestSCCAnalysis::Result &SCCDep)
962         : FDep(FDep), MDep(MDep), SCCDep(SCCDep) {}
963     TestFunctionAnalysis::Result &FDep;
964     TestModuleAnalysis::Result &MDep;
965     TestSCCAnalysis::Result &SCCDep;
966 
967     bool invalidate(Function &F, const PreservedAnalyses &PA,
968                     FunctionAnalysisManager::Invalidator &Inv) {
969       auto PAC = PA.getChecker<TestIndirectFunctionAnalysis>();
970       return !(PAC.preserved() ||
971                PAC.preservedSet<AllAnalysesOn<Function>>()) ||
972              Inv.invalidate<TestFunctionAnalysis>(F, PA);
973     }
974   };
975 
976   TestIndirectFunctionAnalysis(int &Runs) : Runs(Runs) {}
977 
978   /// Run the analysis pass over the function and return a result.
979   Result run(Function &F, FunctionAnalysisManager &AM) {
980     ++Runs;
981     auto &FDep = AM.getResult<TestFunctionAnalysis>(F);
982 
983     auto &ModuleProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
984     const ModuleAnalysisManager &MAM = ModuleProxy.getManager();
985     // For the test, we insist that the module analysis starts off in the
986     // cache.
987     auto &MDep = *MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
988     // Register the dependency as module analysis dependencies have to be
989     // pre-registered on the proxy.
990     ModuleProxy.registerOuterAnalysisInvalidation<
991         TestModuleAnalysis, TestIndirectFunctionAnalysis>();
992 
993     // For thet test we assume this is run inside a CGSCC pass manager.
994     const LazyCallGraph &CG =
995         *MAM.getCachedResult<LazyCallGraphAnalysis>(*F.getParent());
996     auto &CGSCCProxy = AM.getResult<CGSCCAnalysisManagerFunctionProxy>(F);
997     const CGSCCAnalysisManager &CGAM = CGSCCProxy.getManager();
998     // For the test, we insist that the CGSCC analysis starts off in the cache.
999     auto &SCCDep =
1000         *CGAM.getCachedResult<TestSCCAnalysis>(*CG.lookupSCC(*CG.lookup(F)));
1001     // Register the dependency as CGSCC analysis dependencies have to be
1002     // pre-registered on the proxy.
1003     CGSCCProxy.registerOuterAnalysisInvalidation<
1004         TestSCCAnalysis, TestIndirectFunctionAnalysis>();
1005 
1006     return Result(FDep, MDep, SCCDep);
1007   }
1008 
1009 private:
1010   friend AnalysisInfoMixin<TestIndirectFunctionAnalysis>;
1011   static AnalysisKey Key;
1012 
1013   int &Runs;
1014 };
1015 
1016 AnalysisKey TestIndirectFunctionAnalysis::Key;
1017 
1018 TEST_F(CGSCCPassManagerTest, TestIndirectAnalysisInvalidation) {
1019   int ModuleAnalysisRuns = 0;
1020   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
1021 
1022   int SCCAnalysisRuns = 0, IndirectSCCAnalysisRuns = 0,
1023       DoublyIndirectSCCAnalysisRuns = 0;
1024   CGAM.registerPass([&] { return TestSCCAnalysis(SCCAnalysisRuns); });
1025   CGAM.registerPass(
1026       [&] { return TestIndirectSCCAnalysis(IndirectSCCAnalysisRuns); });
1027   CGAM.registerPass([&] {
1028     return TestDoublyIndirectSCCAnalysis(DoublyIndirectSCCAnalysisRuns);
1029   });
1030 
1031   int FunctionAnalysisRuns = 0, IndirectFunctionAnalysisRuns = 0;
1032   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
1033   FAM.registerPass([&] {
1034     return TestIndirectFunctionAnalysis(IndirectFunctionAnalysisRuns);
1035   });
1036 
1037   ModulePassManager MPM(/*DebugLogging*/ true);
1038 
1039   int FunctionCount = 0;
1040   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1041   // First just use the analysis to get the function count and preserve
1042   // everything.
1043   CGPM.addPass(
1044       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1045                         LazyCallGraph &CG, CGSCCUpdateResult &) {
1046         auto &DoublyIndirectResult =
1047             AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1048         auto &IndirectResult = DoublyIndirectResult.IDep;
1049         FunctionCount += IndirectResult.SCCDep.FunctionCount;
1050         return PreservedAnalyses::all();
1051       }));
1052   CGPM.addPass(createCGSCCToFunctionPassAdaptor(
1053       RequireAnalysisPass<TestIndirectFunctionAnalysis, Function>()));
1054 
1055   // Next, invalidate
1056   //   - both analyses for the (f) and (x) SCCs,
1057   //   - just the underlying (indirect) analysis for (g) SCC, and
1058   //   - just the direct analysis for (h1,h2,h3) SCC.
1059   CGPM.addPass(
1060       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1061                         LazyCallGraph &CG, CGSCCUpdateResult &) {
1062         auto &DoublyIndirectResult =
1063             AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1064         auto &IndirectResult = DoublyIndirectResult.IDep;
1065         FunctionCount += IndirectResult.SCCDep.FunctionCount;
1066         auto PA = PreservedAnalyses::none();
1067         PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
1068         PA.preserveSet<AllAnalysesOn<Function>>();
1069         if (C.getName() == "(g)")
1070           PA.preserve<TestSCCAnalysis>();
1071         else if (C.getName() == "(h3, h1, h2)")
1072           PA.preserve<TestIndirectSCCAnalysis>();
1073         return PA;
1074       }));
1075   // Finally, use the analysis again on each SCC (and function), forcing
1076   // re-computation for all of them.
1077   CGPM.addPass(
1078       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1079                         LazyCallGraph &CG, CGSCCUpdateResult &) {
1080         auto &DoublyIndirectResult =
1081             AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1082         auto &IndirectResult = DoublyIndirectResult.IDep;
1083         FunctionCount += IndirectResult.SCCDep.FunctionCount;
1084         return PreservedAnalyses::all();
1085       }));
1086   CGPM.addPass(createCGSCCToFunctionPassAdaptor(
1087       RequireAnalysisPass<TestIndirectFunctionAnalysis, Function>()));
1088 
1089   // Create a second CGSCC pass manager. This will cause the module-level
1090   // invalidation to occur, which will force yet another invalidation of the
1091   // indirect SCC-level analysis as the module analysis it depends on gets
1092   // invalidated.
1093   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
1094   CGPM2.addPass(
1095       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1096                         LazyCallGraph &CG, CGSCCUpdateResult &) {
1097         auto &DoublyIndirectResult =
1098             AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1099         auto &IndirectResult = DoublyIndirectResult.IDep;
1100         FunctionCount += IndirectResult.SCCDep.FunctionCount;
1101         return PreservedAnalyses::all();
1102       }));
1103   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(
1104       RequireAnalysisPass<TestIndirectFunctionAnalysis, Function>()));
1105 
1106   // Add a requires pass to populate the module analysis and then our CGSCC
1107   // pass pipeline.
1108   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1109   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1110   // Now require the module analysis again (it will have been invalidated once)
1111   // and then use it again from our second CGSCC pipeline..
1112   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1113   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
1114   MPM.run(*M, MAM);
1115 
1116   // There are generally two possible runs for each of the four SCCs. But
1117   // for one SCC, we only invalidate the indirect analysis so the base one
1118   // only gets run seven times.
1119   EXPECT_EQ(7, SCCAnalysisRuns);
1120   // The module analysis pass should be run twice here.
1121   EXPECT_EQ(2, ModuleAnalysisRuns);
1122   // The indirect analysis is invalidated (either directly or indirectly) three
1123   // times for each of four SCCs.
1124   EXPECT_EQ(3 * 4, IndirectSCCAnalysisRuns);
1125   EXPECT_EQ(3 * 4, DoublyIndirectSCCAnalysisRuns);
1126 
1127   // We run the indirect function analysis once per function the first time.
1128   // Then we re-run it for every SCC but "(g)". Then we re-run it for every
1129   // function again.
1130   EXPECT_EQ(6 + 5 + 6, IndirectFunctionAnalysisRuns);
1131 
1132   // Four passes count each of six functions once (via SCCs).
1133   EXPECT_EQ(4 * 6, FunctionCount);
1134 }
1135 
1136 TEST_F(CGSCCPassManagerTest, TestAnalysisInvalidationCGSCCUpdate) {
1137   int ModuleAnalysisRuns = 0;
1138   MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
1139 
1140   int SCCAnalysisRuns = 0, IndirectSCCAnalysisRuns = 0,
1141       DoublyIndirectSCCAnalysisRuns = 0;
1142   CGAM.registerPass([&] { return TestSCCAnalysis(SCCAnalysisRuns); });
1143   CGAM.registerPass(
1144       [&] { return TestIndirectSCCAnalysis(IndirectSCCAnalysisRuns); });
1145   CGAM.registerPass([&] {
1146     return TestDoublyIndirectSCCAnalysis(DoublyIndirectSCCAnalysisRuns);
1147   });
1148 
1149   int FunctionAnalysisRuns = 0, IndirectFunctionAnalysisRuns = 0;
1150   FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
1151   FAM.registerPass([&] {
1152     return TestIndirectFunctionAnalysis(IndirectFunctionAnalysisRuns);
1153   });
1154 
1155   ModulePassManager MPM(/*DebugLogging*/ true);
1156 
1157   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1158   // First just use the analysis to get the function count and preserve
1159   // everything.
1160   using RequireTestIndirectFunctionAnalysisPass =
1161       RequireAnalysisPass<TestIndirectFunctionAnalysis, Function>;
1162   using RequireTestDoublyIndirectSCCAnalysisPass =
1163       RequireAnalysisPass<TestDoublyIndirectSCCAnalysis, LazyCallGraph::SCC,
1164                           CGSCCAnalysisManager, LazyCallGraph &,
1165                           CGSCCUpdateResult &>;
1166   CGPM.addPass(RequireTestDoublyIndirectSCCAnalysisPass());
1167   CGPM.addPass(createCGSCCToFunctionPassAdaptor(
1168       RequireTestIndirectFunctionAnalysisPass()));
1169 
1170   // Next, we inject an SCC pass that invalidates everything for the `(h3, h1,
1171   // h2)` SCC but also deletes the call edge from `h2` to `h3` and updates the
1172   // CG. This should successfully invalidate (and force to be re-run) all the
1173   // analyses for that SCC and for the functions.
1174   CGPM.addPass(
1175       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1176                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
1177         (void)AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1178         if (C.getName() != "(h3, h1, h2)")
1179           return PreservedAnalyses::all();
1180 
1181         // Build the preserved set.
1182         auto PA = PreservedAnalyses::none();
1183         PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
1184         PA.preserve<TestIndirectSCCAnalysis>();
1185         PA.preserve<TestDoublyIndirectSCCAnalysis>();
1186 
1187         // Delete the call from `h2` to `h3`.
1188         auto &H2N = *llvm::find_if(
1189             C, [](LazyCallGraph::Node &N) { return N.getName() == "h2"; });
1190         auto &H2F = H2N.getFunction();
1191         auto &H3F = *cast<CallInst>(H2F.begin()->begin())->getCalledFunction();
1192         assert(H3F.getName() == "h3" && "Wrong called function!");
1193         H2F.begin()->begin()->eraseFromParent();
1194         // Insert a bitcast of `h3` so that we retain a ref edge to it.
1195         (void)CastInst::CreatePointerCast(&H3F,
1196                                           Type::getInt8PtrTy(H2F.getContext()),
1197                                           "dummy", &*H2F.begin()->begin());
1198 
1199         // Now update the call graph.
1200         auto &NewC =
1201             updateCGAndAnalysisManagerForFunctionPass(CG, C, H2N, AM, UR);
1202         assert(&NewC != &C && "Should get a new SCC due to update!");
1203         (void)&NewC;
1204 
1205         return PA;
1206       }));
1207   // Now use the analysis again on each SCC and function, forcing
1208   // re-computation for all of them.
1209   CGPM.addPass(RequireTestDoublyIndirectSCCAnalysisPass());
1210   CGPM.addPass(createCGSCCToFunctionPassAdaptor(
1211       RequireTestIndirectFunctionAnalysisPass()));
1212 
1213   // Create another CGSCC pipeline that requires all the analyses again.
1214   CGSCCPassManager CGPM2(/*DebugLogging*/ true);
1215   CGPM2.addPass(RequireTestDoublyIndirectSCCAnalysisPass());
1216   CGPM2.addPass(createCGSCCToFunctionPassAdaptor(
1217       RequireTestIndirectFunctionAnalysisPass()));
1218 
1219   // Next we inject an SCC pass that finds the `(h2)` SCC, adds a call to `h3`
1220   // back to `h2`, and then invalidates everything for what will then be the
1221   // `(h3, h1, h2)` SCC again.
1222   CGSCCPassManager CGPM3(/*DebugLogging*/ true);
1223   CGPM3.addPass(
1224       LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1225                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
1226         (void)AM.getResult<TestDoublyIndirectSCCAnalysis>(C, CG);
1227         if (C.getName() != "(h2)")
1228           return PreservedAnalyses::all();
1229 
1230         // Build the preserved set.
1231         auto PA = PreservedAnalyses::none();
1232         PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
1233         PA.preserve<TestIndirectSCCAnalysis>();
1234         PA.preserve<TestDoublyIndirectSCCAnalysis>();
1235 
1236         // Delete the bitcast of `h3` that we added earlier.
1237         auto &H2N = *C.begin();
1238         auto &H2F = H2N.getFunction();
1239         auto &H3F = *cast<Function>(cast<BitCastInst>(H2F.begin()->begin())->getOperand(0));
1240         assert(H3F.getName() == "h3" && "Wrong called function!");
1241         H2F.begin()->begin()->eraseFromParent();
1242         // And insert a call to `h3`.
1243         (void)CallInst::Create(&H3F, {}, "", &*H2F.begin()->begin());
1244 
1245         // Now update the call graph.
1246         auto &NewC =
1247             updateCGAndAnalysisManagerForFunctionPass(CG, C, H2N, AM, UR);
1248         assert(&NewC != &C && "Should get a new SCC due to update!");
1249         (void)&NewC;
1250 
1251         return PA;
1252       }));
1253   // Now use the analysis again on each SCC and function, forcing
1254   // re-computation for all of them.
1255   CGPM3.addPass(RequireTestDoublyIndirectSCCAnalysisPass());
1256   CGPM3.addPass(createCGSCCToFunctionPassAdaptor(
1257       RequireTestIndirectFunctionAnalysisPass()));
1258 
1259   // Create a second CGSCC pass manager. This will cause the module-level
1260   // invalidation to occur, which will force yet another invalidation of the
1261   // indirect SCC-level analysis as the module analysis it depends on gets
1262   // invalidated.
1263   CGSCCPassManager CGPM4(/*DebugLogging*/ true);
1264   CGPM4.addPass(RequireTestDoublyIndirectSCCAnalysisPass());
1265   CGPM4.addPass(createCGSCCToFunctionPassAdaptor(
1266       RequireTestIndirectFunctionAnalysisPass()));
1267 
1268   // Add a requires pass to populate the module analysis and then one of our
1269   // CGSCC pipelines. Repeat for all four CGSCC pipelines.
1270   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1271   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1272   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1273   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
1274   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1275   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM3)));
1276   MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
1277   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM4)));
1278   MPM.run(*M, MAM);
1279 
1280   // We run over four SCCs the first time. But then we split an SCC into three.
1281   // And then we merge those three back into one. However, this also
1282   // invalidates all three SCCs further down in the PO walk.
1283   EXPECT_EQ(4 + 3 + 1 + 3, SCCAnalysisRuns);
1284   // The module analysis pass should be run three times.
1285   EXPECT_EQ(3, ModuleAnalysisRuns);
1286   // We run over four SCCs the first time. Then over the two new ones. Then the
1287   // entire module is invalidated causing a full run over all seven. Then we
1288   // fold three SCCs back to one, re-compute for it and the two SCCs above it
1289   // in the graph, and then run over the whole module again.
1290   EXPECT_EQ(4 + 2 + 7 + 1 + 3 + 4, IndirectSCCAnalysisRuns);
1291   EXPECT_EQ(4 + 2 + 7 + 1 + 3 + 4, DoublyIndirectSCCAnalysisRuns);
1292 
1293   // First we run over all six functions. Then we re-run it over three when we
1294   // split their SCCs. Then we re-run over the whole module. Then we re-run
1295   // over three functions merged back into a single SCC, then those three
1296   // functions again, the two functions in SCCs above it in the graph, and then
1297   // over the whole module again.
1298   EXPECT_EQ(6 + 3 + 6 + 3 + 3 + 2 + 6, FunctionAnalysisRuns);
1299 
1300   // Re run the function analysis over the entire module, and then re-run it
1301   // over the `(h3, h1, h2)` SCC due to invalidation. Then we re-run it over
1302   // the entire module, then the three functions merged back into a single SCC,
1303   // those three functions again, then the two functions in SCCs above it in
1304   // the graph, and then over the whole module.
1305   EXPECT_EQ(6 + 3 + 6 + 3 + 3 + 2 + 6, IndirectFunctionAnalysisRuns);
1306 }
1307 
1308 // The (negative) tests below check for assertions so we only run them if NDEBUG
1309 // is not defined.
1310 #ifndef NDEBUG
1311 
1312 struct LambdaSCCPassNoPreserve : public PassInfoMixin<LambdaSCCPassNoPreserve> {
1313   template <typename T>
1314   LambdaSCCPassNoPreserve(T &&Arg) : Func(std::forward<T>(Arg)) {}
1315 
1316   PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
1317                         LazyCallGraph &CG, CGSCCUpdateResult &UR) {
1318     Func(C, AM, CG, UR);
1319     PreservedAnalyses PA;
1320     // We update the core CGSCC data structures and so can preserve the proxy to
1321     // the function analysis manager.
1322     PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
1323     return PA;
1324   }
1325 
1326   std::function<void(LazyCallGraph::SCC &, CGSCCAnalysisManager &,
1327                      LazyCallGraph &, CGSCCUpdateResult &)>
1328       Func;
1329 };
1330 
1331 TEST_F(CGSCCPassManagerTest, TestUpdateCGAndAnalysisManagerForPasses0) {
1332   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1333   CGPM.addPass(LambdaSCCPassNoPreserve(
1334       [&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG,
1335           CGSCCUpdateResult &UR) {
1336         if (C.getName() != "(h3, h1, h2)")
1337           return;
1338 
1339         Function *FnX = M->getFunction("x");
1340         Function *FnH1 = M->getFunction("h1");
1341         Function *FnH2 = M->getFunction("h2");
1342         Function *FnH3 = M->getFunction("h3");
1343         ASSERT_NE(FnX, nullptr);
1344         ASSERT_NE(FnH1, nullptr);
1345         ASSERT_NE(FnH2, nullptr);
1346         ASSERT_NE(FnH3, nullptr);
1347 
1348         // And insert a call to `h1`, `h2`, and `h3`.
1349         Instruction *IP = &FnH2->getEntryBlock().front();
1350         (void)CallInst::Create(FnH1, {}, "", IP);
1351         (void)CallInst::Create(FnH2, {}, "", IP);
1352         (void)CallInst::Create(FnH3, {}, "", IP);
1353 
1354         auto &H2N = *llvm::find_if(
1355             C, [](LazyCallGraph::Node &N) { return N.getName() == "h2"; });
1356         ASSERT_NO_FATAL_FAILURE(
1357             updateCGAndAnalysisManagerForCGSCCPass(CG, C, H2N, AM, UR));
1358       }));
1359 
1360   ModulePassManager MPM(/*DebugLogging*/ true);
1361   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1362   MPM.run(*M, MAM);
1363 }
1364 
1365 TEST_F(CGSCCPassManagerTest, TestUpdateCGAndAnalysisManagerForPasses1) {
1366   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1367   CGPM.addPass(LambdaSCCPassNoPreserve([&](LazyCallGraph::SCC &C,
1368                                            CGSCCAnalysisManager &AM,
1369                                            LazyCallGraph &CG,
1370                                            CGSCCUpdateResult &UR) {
1371     if (C.getName() != "(h3, h1, h2)")
1372       return;
1373 
1374     Function *FnX = M->getFunction("x");
1375     Function *FnH1 = M->getFunction("h1");
1376     Function *FnH2 = M->getFunction("h2");
1377     Function *FnH3 = M->getFunction("h3");
1378     ASSERT_NE(FnX, nullptr);
1379     ASSERT_NE(FnH1, nullptr);
1380     ASSERT_NE(FnH2, nullptr);
1381     ASSERT_NE(FnH3, nullptr);
1382 
1383     // And insert a call to `h1`, `h2`, and `h3`.
1384     Instruction *IP = &FnH2->getEntryBlock().front();
1385     (void)CallInst::Create(FnH1, {}, "", IP);
1386     (void)CallInst::Create(FnH2, {}, "", IP);
1387     (void)CallInst::Create(FnH3, {}, "", IP);
1388 
1389     auto &H2N = *llvm::find_if(
1390         C, [](LazyCallGraph::Node &N) { return N.getName() == "h2"; });
1391     ASSERT_DEATH(updateCGAndAnalysisManagerForFunctionPass(CG, C, H2N, AM, UR),
1392                  "Any new calls should be modeled as");
1393   }));
1394 
1395   ModulePassManager MPM(/*DebugLogging*/ true);
1396   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1397   MPM.run(*M, MAM);
1398 }
1399 
1400 TEST_F(CGSCCPassManagerTest, TestUpdateCGAndAnalysisManagerForPasses2) {
1401   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1402   CGPM.addPass(LambdaSCCPassNoPreserve(
1403       [&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG,
1404           CGSCCUpdateResult &UR) {
1405         if (C.getName() != "(f)")
1406           return;
1407 
1408         Function *FnF = M->getFunction("f");
1409         Function *FnH2 = M->getFunction("h2");
1410         ASSERT_NE(FnF, nullptr);
1411         ASSERT_NE(FnH2, nullptr);
1412 
1413         // And insert a call to `h2`
1414         Instruction *IP = &FnF->getEntryBlock().front();
1415         (void)CallInst::Create(FnH2, {}, "", IP);
1416 
1417         auto &FN = *llvm::find_if(
1418             C, [](LazyCallGraph::Node &N) { return N.getName() == "f"; });
1419         ASSERT_NO_FATAL_FAILURE(
1420             updateCGAndAnalysisManagerForCGSCCPass(CG, C, FN, AM, UR));
1421       }));
1422 
1423   ModulePassManager MPM(/*DebugLogging*/ true);
1424   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1425   MPM.run(*M, MAM);
1426 }
1427 
1428 TEST_F(CGSCCPassManagerTest, TestUpdateCGAndAnalysisManagerForPasses3) {
1429   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1430   CGPM.addPass(LambdaSCCPassNoPreserve([&](LazyCallGraph::SCC &C,
1431                                            CGSCCAnalysisManager &AM,
1432                                            LazyCallGraph &CG,
1433                                            CGSCCUpdateResult &UR) {
1434     if (C.getName() != "(f)")
1435       return;
1436 
1437     Function *FnF = M->getFunction("f");
1438     Function *FnH2 = M->getFunction("h2");
1439     ASSERT_NE(FnF, nullptr);
1440     ASSERT_NE(FnH2, nullptr);
1441 
1442     // And insert a call to `h2`
1443     Instruction *IP = &FnF->getEntryBlock().front();
1444     (void)CallInst::Create(FnH2, {}, "", IP);
1445 
1446     auto &FN = *llvm::find_if(
1447         C, [](LazyCallGraph::Node &N) { return N.getName() == "f"; });
1448     ASSERT_DEATH(updateCGAndAnalysisManagerForFunctionPass(CG, C, FN, AM, UR),
1449                  "Any new calls should be modeled as");
1450   }));
1451 
1452   ModulePassManager MPM(/*DebugLogging*/ true);
1453   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1454   MPM.run(*M, MAM);
1455 }
1456 
1457 TEST_F(CGSCCPassManagerTest, TestUpdateCGAndAnalysisManagerForPasses4) {
1458   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1459   CGPM.addPass(LambdaSCCPassNoPreserve(
1460       [&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG,
1461           CGSCCUpdateResult &UR) {
1462         if (C.getName() != "(f)")
1463           return;
1464 
1465         Function *FnF = M->getFunction("f");
1466         Function *FnewF = Function::Create(FnF->getFunctionType(),
1467                                            FnF->getLinkage(), "newF", *M);
1468         BasicBlock *BB = BasicBlock::Create(FnewF->getContext(), "", FnewF);
1469         ReturnInst::Create(FnewF->getContext(), BB);
1470 
1471         // Use the CallGraphUpdater to update the call graph for the new
1472         // function.
1473         CallGraphUpdater CGU;
1474         CGU.initialize(CG, C, AM, UR);
1475         CGU.registerOutlinedFunction(*FnewF);
1476 
1477         // And insert a call to `newF`
1478         Instruction *IP = &FnF->getEntryBlock().front();
1479         (void)CallInst::Create(FnewF, {}, "", IP);
1480 
1481         auto &FN = *llvm::find_if(
1482             C, [](LazyCallGraph::Node &N) { return N.getName() == "f"; });
1483 
1484         ASSERT_NO_FATAL_FAILURE(
1485             updateCGAndAnalysisManagerForCGSCCPass(CG, C, FN, AM, UR));
1486       }));
1487 
1488   ModulePassManager MPM(/*DebugLogging*/ true);
1489   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1490   MPM.run(*M, MAM);
1491 }
1492 
1493 TEST_F(CGSCCPassManagerTest, TestUpdateCGAndAnalysisManagerForPasses5) {
1494   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1495   CGPM.addPass(LambdaSCCPassNoPreserve([&](LazyCallGraph::SCC &C,
1496                                            CGSCCAnalysisManager &AM,
1497                                            LazyCallGraph &CG,
1498                                            CGSCCUpdateResult &UR) {
1499     if (C.getName() != "(f)")
1500       return;
1501 
1502     Function *FnF = M->getFunction("f");
1503     Function *FnewF =
1504         Function::Create(FnF->getFunctionType(), FnF->getLinkage(), "newF", *M);
1505     BasicBlock *BB = BasicBlock::Create(FnewF->getContext(), "", FnewF);
1506     ReturnInst::Create(FnewF->getContext(), BB);
1507 
1508     // Use the CallGraphUpdater to update the call graph for the new
1509     // function.
1510     CallGraphUpdater CGU;
1511     CGU.initialize(CG, C, AM, UR);
1512     CGU.registerOutlinedFunction(*FnewF);
1513 
1514     // And insert a call to `newF`
1515     Instruction *IP = &FnF->getEntryBlock().front();
1516     (void)CallInst::Create(FnewF, {}, "", IP);
1517 
1518     auto &FN = *llvm::find_if(
1519         C, [](LazyCallGraph::Node &N) { return N.getName() == "f"; });
1520 
1521     ASSERT_DEATH(updateCGAndAnalysisManagerForFunctionPass(CG, C, FN, AM, UR),
1522                  "Any new calls should be modeled as");
1523   }));
1524 
1525   ModulePassManager MPM(/*DebugLogging*/ true);
1526   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1527   MPM.run(*M, MAM);
1528 }
1529 
1530 TEST_F(CGSCCPassManagerTest, TestUpdateCGAndAnalysisManagerForPasses6) {
1531   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1532   CGPM.addPass(LambdaSCCPassNoPreserve(
1533       [&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG,
1534           CGSCCUpdateResult &UR) {
1535         if (C.getName() != "(h3, h1, h2)")
1536           return;
1537 
1538         Function *FnX = M->getFunction("x");
1539         Function *FnH1 = M->getFunction("h1");
1540         Function *FnH2 = M->getFunction("h2");
1541         Function *FnH3 = M->getFunction("h3");
1542         ASSERT_NE(FnX, nullptr);
1543         ASSERT_NE(FnH1, nullptr);
1544         ASSERT_NE(FnH2, nullptr);
1545         ASSERT_NE(FnH3, nullptr);
1546 
1547         // And insert a call to `h1`, `h2`, and `h3`.
1548         Instruction *IP = &FnH2->getEntryBlock().front();
1549         (void)CallInst::Create(FnH1, {}, "", IP);
1550         (void)CallInst::Create(FnH2, {}, "", IP);
1551         (void)CallInst::Create(FnH3, {}, "", IP);
1552 
1553         // Use the CallGraphUpdater to update the call graph for the new
1554         // function.
1555         CallGraphUpdater CGU;
1556         CGU.initialize(CG, C, AM, UR);
1557         ASSERT_NO_FATAL_FAILURE(CGU.reanalyzeFunction(*FnH2));
1558       }));
1559 
1560   ModulePassManager MPM(/*DebugLogging*/ true);
1561   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1562   MPM.run(*M, MAM);
1563 }
1564 
1565 TEST_F(CGSCCPassManagerTest, TestUpdateCGAndAnalysisManagerForPasses7) {
1566   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1567   CGPM.addPass(LambdaSCCPassNoPreserve(
1568       [&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG,
1569           CGSCCUpdateResult &UR) {
1570         if (C.getName() != "(f)")
1571           return;
1572 
1573         Function *FnF = M->getFunction("f");
1574         Function *FnH2 = M->getFunction("h2");
1575         ASSERT_NE(FnF, nullptr);
1576         ASSERT_NE(FnH2, nullptr);
1577 
1578         // And insert a call to `h2`
1579         Instruction *IP = &FnF->getEntryBlock().front();
1580         (void)CallInst::Create(FnH2, {}, "", IP);
1581 
1582         // Use the CallGraphUpdater to update the call graph for the new
1583         // function.
1584         CallGraphUpdater CGU;
1585         CGU.initialize(CG, C, AM, UR);
1586         ASSERT_NO_FATAL_FAILURE(CGU.reanalyzeFunction(*FnF));
1587       }));
1588 
1589   ModulePassManager MPM(/*DebugLogging*/ true);
1590   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1591   MPM.run(*M, MAM);
1592 }
1593 
1594 TEST_F(CGSCCPassManagerTest, TestUpdateCGAndAnalysisManagerForPasses8) {
1595   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1596   CGPM.addPass(LambdaSCCPassNoPreserve(
1597       [&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG,
1598           CGSCCUpdateResult &UR) {
1599         if (C.getName() != "(f)")
1600           return;
1601 
1602         Function *FnF = M->getFunction("f");
1603         Function *FnewF = Function::Create(FnF->getFunctionType(),
1604                                            FnF->getLinkage(), "newF", *M);
1605         BasicBlock *BB = BasicBlock::Create(FnewF->getContext(), "", FnewF);
1606         auto *RI = ReturnInst::Create(FnewF->getContext(), BB);
1607         while (FnF->getEntryBlock().size() > 1)
1608           FnF->getEntryBlock().front().moveBefore(RI);
1609         ASSERT_NE(FnF, nullptr);
1610 
1611         // Use the CallGraphUpdater to update the call graph.
1612         CallGraphUpdater CGU;
1613         CGU.initialize(CG, C, AM, UR);
1614         ASSERT_NO_FATAL_FAILURE(CGU.replaceFunctionWith(*FnF, *FnewF));
1615         ASSERT_TRUE(FnF->isDeclaration());
1616         ASSERT_EQ(FnF->getNumUses(), 0U);
1617       }));
1618 
1619   ModulePassManager MPM(/*DebugLogging*/ true);
1620   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1621   MPM.run(*M, MAM);
1622 }
1623 
1624 TEST_F(CGSCCPassManagerTest, TestUpdateCGAndAnalysisManagerForPasses9) {
1625   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1626   CGPM.addPass(LambdaSCCPassNoPreserve(
1627       [&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG,
1628           CGSCCUpdateResult &UR) {
1629         if (C.getName() != "(f)")
1630           return;
1631 
1632         Function *FnF = M->getFunction("f");
1633 
1634         // Use the CallGraphUpdater to update the call graph.
1635         {
1636           CallGraphUpdater CGU;
1637           CGU.initialize(CG, C, AM, UR);
1638           ASSERT_NO_FATAL_FAILURE(CGU.removeFunction(*FnF));
1639           ASSERT_EQ(M->getFunctionList().size(), 6U);
1640         }
1641         ASSERT_EQ(M->getFunctionList().size(), 5U);
1642       }));
1643 
1644   ModulePassManager MPM(/*DebugLogging*/ true);
1645   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1646   MPM.run(*M, MAM);
1647 }
1648 
1649 TEST_F(CGSCCPassManagerTest, TestUpdateCGAndAnalysisManagerForPasses10) {
1650   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1651   CGPM.addPass(LambdaSCCPassNoPreserve(
1652       [&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG,
1653           CGSCCUpdateResult &UR) {
1654         if (C.getName() != "(h3, h1, h2)")
1655           return;
1656 
1657         Function *FnX = M->getFunction("x");
1658         Function *FnH1 = M->getFunction("h1");
1659         Function *FnH2 = M->getFunction("h2");
1660         Function *FnH3 = M->getFunction("h3");
1661         ASSERT_NE(FnX, nullptr);
1662         ASSERT_NE(FnH1, nullptr);
1663         ASSERT_NE(FnH2, nullptr);
1664         ASSERT_NE(FnH3, nullptr);
1665 
1666         // And insert a call to `h1`, and `h3`.
1667         Instruction *IP = &FnH1->getEntryBlock().front();
1668         (void)CallInst::Create(FnH1, {}, "", IP);
1669         (void)CallInst::Create(FnH3, {}, "", IP);
1670 
1671         // Remove the `h2` call.
1672         ASSERT_TRUE(isa<CallBase>(IP));
1673         ASSERT_EQ(cast<CallBase>(IP)->getCalledFunction(), FnH2);
1674         IP->eraseFromParent();
1675 
1676         // Use the CallGraphUpdater to update the call graph.
1677         CallGraphUpdater CGU;
1678         CGU.initialize(CG, C, AM, UR);
1679         ASSERT_NO_FATAL_FAILURE(CGU.reanalyzeFunction(*FnH1));
1680         ASSERT_NO_FATAL_FAILURE(CGU.removeFunction(*FnH2));
1681       }));
1682 
1683   ModulePassManager MPM(/*DebugLogging*/ true);
1684   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1685   MPM.run(*M, MAM);
1686 }
1687 
1688 TEST_F(CGSCCPassManagerTest, TestInsertionOfNewRefSCC) {
1689   std::unique_ptr<Module> M = parseIR("define void @f() {\n"
1690                                       "entry:\n"
1691                                       "  call void @f()\n"
1692                                       "  ret void\n"
1693                                       "}\n");
1694 
1695   CGSCCPassManager CGPM(/*DebugLogging*/ true);
1696   CGPM.addPass(LambdaSCCPassNoPreserve(
1697       [&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG,
1698           CGSCCUpdateResult &UR) {
1699         for (auto &N : C) {
1700           auto &F = N.getFunction();
1701           if (F.getName() != "f")
1702             continue;
1703           auto *Call = dyn_cast<CallInst>(F.begin()->begin());
1704           if (!Call || Call->getCalledFunction()->getName() != "f")
1705             continue;
1706 
1707           // Create a new function 'g'.
1708           auto *G = Function::Create(F.getFunctionType(), F.getLinkage(),
1709                                      F.getAddressSpace(), "g", F.getParent());
1710           BasicBlock::Create(F.getParent()->getContext(), "entry", G);
1711           // Instruct the LazyCallGraph to create a new node for 'g', as the
1712           // single node in a new SCC, into the call graph. As a result
1713           // the call graph is composed of a single RefSCC with two SCCs:
1714           // [(f), (g)].
1715           CG.addNewFunctionIntoRefSCC(*G, C.getOuterRefSCC());
1716 
1717           // "Demote" the 'f -> f' call egde to a ref edge.
1718           // 1. Erase the call edge from 'f' to 'f'.
1719           Call->eraseFromParent();
1720           // 2. Insert a ref edge from 'f' to 'f'.
1721           (void)CastInst::CreatePointerCast(&F,
1722                                             Type::getInt8PtrTy(F.getContext()),
1723                                             "f.ref", &*F.begin()->begin());
1724 
1725           ASSERT_NO_FATAL_FAILURE(
1726               updateCGAndAnalysisManagerForCGSCCPass(CG, C, N, AM, UR))
1727               << "Updating the call graph with a demoted, self-referential "
1728                  "call edge 'f -> f', and a newly inserted ref edge 'f -> g', "
1729                  "caused a fatal failure";
1730         }
1731       }));
1732 
1733   ModulePassManager MPM(/*DebugLogging*/ true);
1734   MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
1735   MPM.run(*M, MAM);
1736 }
1737 
1738 #endif
1739 } // namespace
1740