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