[llvm] r282378 - [PM] Add a unittest covering the invalidation of a Module analysis from
Chandler Carruth via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 25 21:17:12 PDT 2016
Author: chandlerc
Date: Sun Sep 25 23:17:12 2016
New Revision: 282378
URL: http://llvm.org/viewvc/llvm-project?rev=282378&view=rev
Log:
[PM] Add a unittest covering the invalidation of a Module analysis from
a function pass nested inside of a CGSCC pass manager.
This is very similar to the previous unittest but makes sure the
invalidation logic works across all the layers here.
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=282378&r1=282377&r2=282378&view=diff
==============================================================================
--- llvm/trunk/unittests/Analysis/CGSCCPassManagerTest.cpp (original)
+++ llvm/trunk/unittests/Analysis/CGSCCPassManagerTest.cpp Sun Sep 25 23:17:12 2016
@@ -385,4 +385,99 @@ TEST_F(CGSCCPassManagerTest, TestSCCPass
EXPECT_EQ(0, CountFoundModuleAnalysis3);
}
+// Similar to the above, but test that this works for function passes embedded
+// *within* a CGSCC layer.
+TEST_F(CGSCCPassManagerTest, TestFunctionPassInsideCGSCCInvalidatesModuleAnalysis) {
+ 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 run we preserve everything and make sure that works and the
+ // module analysis is available in the second run from the one required
+ // module pass above.
+ FunctionPassManager FPM1(/*DebugLogging*/ true);
+ // Start true and mark false if we ever failed to find a module analysis
+ // because we expect this to succeed for each SCC.
+ bool FoundModuleAnalysis1 = true;
+ FPM1.addPass(
+ LambdaFunctionPass([&](Function &F, FunctionAnalysisManager &AM) {
+ const auto &MAM =
+ AM.getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
+ auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
+
+ if (!TMA)
+ FoundModuleAnalysis1 = false;
+
+ return PreservedAnalyses::all();
+ }));
+ CGSCCPassManager CGPM1(/*DebugLogging*/ true);
+ CGPM1.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM1)));
+ MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM1)));
+
+ // The second run checks that the module analysis got preserved the previous
+ // time and in one function fails to preserve it.
+ FunctionPassManager FPM2(/*DebugLogging*/ true);
+ // Again, start true and mark false if we ever failed to find a module analysis
+ // because we expect this to succeed for each SCC.
+ bool FoundModuleAnalysis2 = true;
+ FPM2.addPass(
+ LambdaFunctionPass([&](Function &F, FunctionAnalysisManager &AM) {
+ const auto &MAM =
+ AM.getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
+ auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
+
+ if (!TMA)
+ FoundModuleAnalysis2 = false;
+
+ // Only fail to preserve analyses on one SCC and make sure that gets
+ // propagated.
+ return F.getName() == "h2" ? PreservedAnalyses::none()
+ : PreservedAnalyses::all();
+ }));
+ CGSCCPassManager CGPM2(/*DebugLogging*/ true);
+ CGPM2.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM2)));
+ MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM2)));
+
+ // The third run should fail to find a cached module analysis as it should
+ // have been invalidated by the above run.
+ FunctionPassManager FPM3(/*DebugLogging*/ true);
+ // Start false and mark true if we ever *succeeded* to find a module
+ // analysis, as we expect this to fail for every function.
+ bool FoundModuleAnalysis3 = false;
+ FPM3.addPass(
+ LambdaFunctionPass([&](Function &F, FunctionAnalysisManager &AM) {
+ const auto &MAM =
+ AM.getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
+ auto *TMA = MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
+
+ if (TMA)
+ FoundModuleAnalysis3 = true;
+
+ return PreservedAnalyses::none();
+ }));
+ CGSCCPassManager CGPM3(/*DebugLogging*/ true);
+ CGPM3.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM3)));
+ MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM3)));
+
+ MPM.run(*M, MAM);
+
+ EXPECT_EQ(1, ModuleAnalysisRuns);
+ EXPECT_TRUE(FoundModuleAnalysis1);
+ EXPECT_TRUE(FoundModuleAnalysis2);
+ EXPECT_FALSE(FoundModuleAnalysis3);
+}
+
}
More information about the llvm-commits
mailing list