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