[llvm] r282377 - [PM] Add a unittest for invalidating module analyses with an SCC pass.

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 25 21:01:56 PDT 2016


Author: chandlerc
Date: Sun Sep 25 23:01:55 2016
New Revision: 282377

URL: http://llvm.org/viewvc/llvm-project?rev=282377&view=rev
Log:
[PM] Add a unittest for invalidating module analyses with an SCC pass.

This reinstates r280447. Original commit log:
This wasn't really well explicitly tested with a nice unittest before.
It seems good to have reasonably broken out unittests for this kind of
functionality as I'm workin go other invalidation features to make sure
none of the existing ones regress.

This still has too much duplicated code, I plan to factor that out in
a subsequent commit to use common helpers for repeated parts of this.

Modified:
    llvm/trunk/unittests/Analysis/CGSCCPassManagerTest.cpp

Modified: llvm/trunk/unittests/Analysis/CGSCCPassManagerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Analysis/CGSCCPassManagerTest.cpp?rev=282377&r1=282376&r2=282377&view=diff
==============================================================================
--- llvm/trunk/unittests/Analysis/CGSCCPassManagerTest.cpp (original)
+++ llvm/trunk/unittests/Analysis/CGSCCPassManagerTest.cpp Sun Sep 25 23:01:55 2016
@@ -296,4 +296,93 @@ TEST_F(CGSCCPassManagerTest, Basic) {
   EXPECT_EQ(4 * 6, AnalyzedModuleFunctionCount1);
 }
 
+// Test that an SCC pass which fails to preserve a module analysis does in fact
+// invalidate that module analysis.
+TEST_F(CGSCCPassManagerTest, TestSCCPassInvalidatesModuleAnalysis) {
+  FunctionAnalysisManager FAM(/*DebugLogging*/ true);
+  CGSCCAnalysisManager CGAM(/*DebugLogging*/ true);
+  ModuleAnalysisManager MAM(/*DebugLogging*/ true);
+  MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
+  MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
+  CGAM.registerPass([&] { return FunctionAnalysisManagerCGSCCProxy(FAM); });
+  CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
+  FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
+  FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
+  MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
+
+  int ModuleAnalysisRuns = 0;
+  MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
+
+  ModulePassManager MPM(/*DebugLogging*/ true);
+  MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
+
+  // The first CGSCC run we preserve everything and make sure that works and
+  // the module analysis is available in the second CGSCC run from the one
+  // required module pass above.
+  CGSCCPassManager CGPM1(/*DebugLogging*/ true);
+  int CountFoundModuleAnalysis1 = 0;
+  CGPM1.addPass(
+      LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
+                        LazyCallGraph &CG, CGSCCUpdateResult &UR) {
+        const auto &MAM =
+            AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG).getManager();
+        auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(
+            *C.begin()->getFunction().getParent());
+
+        if (TMA)
+          ++CountFoundModuleAnalysis1;
+
+        return PreservedAnalyses::all();
+      }));
+  MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
+
+  // The second CGSCC run checks that the module analysis got preserved the
+  // previous time and in one SCC fails to preserve it.
+  CGSCCPassManager CGPM2(/*DebugLogging*/ true);
+  int CountFoundModuleAnalysis2 = 0;
+  CGPM2.addPass(
+      LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
+                        LazyCallGraph &CG, CGSCCUpdateResult &UR) {
+        const auto &MAM =
+            AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG).getManager();
+        auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(
+            *C.begin()->getFunction().getParent());
+
+        if (TMA)
+          ++CountFoundModuleAnalysis2;
+
+        // Only fail to preserve analyses on one SCC and make sure that gets
+        // propagated.
+        return C.getName() == "(g)" ? PreservedAnalyses::none()
+                                  : PreservedAnalyses::all();
+      }));
+  MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
+
+  // The third CGSCC run should fail to find a cached module analysis as it
+  // should have been invalidated by the above CGSCC run.
+  CGSCCPassManager CGPM3(/*DebugLogging*/ true);
+  int CountFoundModuleAnalysis3 = 0;
+  CGPM3.addPass(
+      LambdaSCCPass([&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
+                        LazyCallGraph &CG, CGSCCUpdateResult &UR) {
+        const auto &MAM =
+            AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG).getManager();
+        auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(
+            *C.begin()->getFunction().getParent());
+
+        if (TMA)
+          ++CountFoundModuleAnalysis3;
+
+        return PreservedAnalyses::none();
+      }));
+  MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM3)));
+
+  MPM.run(*M, MAM);
+
+  EXPECT_EQ(1, ModuleAnalysisRuns);
+  EXPECT_EQ(4, CountFoundModuleAnalysis1);
+  EXPECT_EQ(4, CountFoundModuleAnalysis2);
+  EXPECT_EQ(0, CountFoundModuleAnalysis3);
+}
+
 }




More information about the llvm-commits mailing list