[llvm] r195525 - [PM] Add support to the analysis managers to query explicitly for cached
Chandler Carruth
chandlerc at gmail.com
Fri Nov 22 16:38:43 PST 2013
Author: chandlerc
Date: Fri Nov 22 18:38:42 2013
New Revision: 195525
URL: http://llvm.org/viewvc/llvm-project?rev=195525&view=rev
Log:
[PM] Add support to the analysis managers to query explicitly for cached
results.
This is the last piece of infrastructure needed to effectively support
querying *up* the analysis layers. The next step will be to introduce
a proxy which provides access to those layers with appropriate use of
const to direct queries to the safe interface.
Modified:
llvm/trunk/include/llvm/IR/PassManager.h
llvm/trunk/lib/IR/PassManager.cpp
llvm/trunk/unittests/IR/PassManagerTest.cpp
Modified: llvm/trunk/include/llvm/IR/PassManager.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManager.h?rev=195525&r1=195524&r2=195525&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/PassManager.h (original)
+++ llvm/trunk/include/llvm/IR/PassManager.h Fri Nov 22 18:38:42 2013
@@ -460,6 +460,26 @@ public:
return static_cast<const ResultModelT &>(ResultConcept).Result;
}
+ /// \brief Get the cached result of an analysis pass for this module.
+ ///
+ /// This method never runs the analysis.
+ ///
+ /// \returns null if there is no cached result.
+ template <typename PassT>
+ const typename PassT::Result *getCachedResult(Module *M) const {
+ assert(ModuleAnalysisPasses.count(PassT::ID()) &&
+ "This analysis pass was not registered prior to being queried");
+
+ const detail::AnalysisResultConcept<Module *> *ResultConcept =
+ getCachedResultImpl(PassT::ID(), M);
+ if (!ResultConcept)
+ return 0;
+
+ typedef detail::AnalysisResultModel<Module *, PassT, typename PassT::Result>
+ ResultModelT;
+ return &static_cast<const ResultModelT *>(ResultConcept)->Result;
+ }
+
/// \brief Register an analysis pass with the manager.
///
/// This provides an initialized and set-up analysis pass to the
@@ -495,6 +515,10 @@ private:
const detail::AnalysisResultConcept<Module *> &getResultImpl(void *PassID,
Module *M);
+ /// \brief Get a cached module pass result or return null.
+ const detail::AnalysisResultConcept<Module *> *
+ getCachedResultImpl(void *PassID, Module *M) const;
+
/// \brief Invalidate a module pass result.
void invalidateImpl(void *PassID, Module *M);
@@ -537,6 +561,26 @@ public:
return static_cast<const ResultModelT &>(ResultConcept).Result;
}
+ /// \brief Get the cached result of an analysis pass for a function if
+ /// available.
+ ///
+ /// Does not run the analysis ever.
+ /// \returns null if a cached result is not available.
+ template <typename PassT>
+ const typename PassT::Result *getCachedResult(Function *F) {
+ assert(FunctionAnalysisPasses.count(PassT::ID()) &&
+ "This analysis pass was not registered prior to being queried");
+
+ const detail::AnalysisResultConcept<Function *> *ResultConcept =
+ getCachedResultImpl(PassT::ID(), F);
+ if (!ResultConcept)
+ return 0;
+
+ typedef detail::AnalysisResultModel<Function *, PassT,
+ typename PassT::Result> ResultModelT;
+ return &static_cast<const ResultModelT *>(ResultConcept)->Result;
+ }
+
/// \brief Register an analysis pass with the manager.
///
/// This provides an initialized and set-up analysis pass to the
@@ -583,6 +627,10 @@ private:
const detail::AnalysisResultConcept<Function *> &getResultImpl(void *PassID,
Function *F);
+ /// \brief Get a cached function pass result or return null.
+ const detail::AnalysisResultConcept<Function *> *
+ getCachedResultImpl(void *PassID, Function *F) const;
+
/// \brief Invalidate a function pass result.
void invalidateImpl(void *PassID, Function *F);
Modified: llvm/trunk/lib/IR/PassManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/PassManager.cpp?rev=195525&r1=195524&r2=195525&view=diff
==============================================================================
--- llvm/trunk/lib/IR/PassManager.cpp (original)
+++ llvm/trunk/lib/IR/PassManager.cpp Fri Nov 22 18:38:42 2013
@@ -53,6 +53,12 @@ ModuleAnalysisManager::getResultImpl(voi
return *RI->second;
}
+const detail::AnalysisResultConcept<Module *> *
+ModuleAnalysisManager::getCachedResultImpl(void *PassID, Module *M) const {
+ ModuleAnalysisResultMapT::const_iterator RI = ModuleAnalysisResults.find(PassID);
+ return RI == ModuleAnalysisResults.end() ? 0 : &*RI->second;
+}
+
void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) {
ModuleAnalysisResults.erase(PassID);
}
@@ -122,6 +128,13 @@ FunctionAnalysisManager::getResultImpl(v
return *RI->second->second;
}
+const detail::AnalysisResultConcept<Function *> *
+FunctionAnalysisManager::getCachedResultImpl(void *PassID, Function *F) const {
+ FunctionAnalysisResultMapT::const_iterator RI =
+ FunctionAnalysisResults.find(std::make_pair(PassID, F));
+ return RI == FunctionAnalysisResults.end() ? 0 : &*RI->second->second;
+}
+
void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) {
FunctionAnalysisResultMapT::iterator RI =
FunctionAnalysisResults.find(std::make_pair(PassID, F));
Modified: llvm/trunk/unittests/IR/PassManagerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/PassManagerTest.cpp?rev=195525&r1=195524&r2=195525&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/PassManagerTest.cpp (original)
+++ llvm/trunk/unittests/IR/PassManagerTest.cpp Fri Nov 22 18:38:42 2013
@@ -69,28 +69,46 @@ struct TestPreservingModulePass {
};
struct TestMinPreservingModulePass {
- PreservedAnalyses run(Module *M) {
+ PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) {
PreservedAnalyses PA;
+
+ // Check that we can get cached result objects for modules.
+ const FunctionAnalysisManagerModuleProxy::Result *R =
+ AM->getCachedResult<FunctionAnalysisManagerModuleProxy>(M);
+ (void)R; // FIXME: We should test this better by querying an actual analysis
+ // pass in interesting ways.
+
PA.preserve<FunctionAnalysisManagerModuleProxy>();
return PA;
}
};
struct TestFunctionPass {
- TestFunctionPass(int &RunCount, int &AnalyzedInstrCount)
- : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount) {}
+ TestFunctionPass(int &RunCount, int &AnalyzedInstrCount,
+ bool OnlyUseCachedResults = false)
+ : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount),
+ OnlyUseCachedResults(OnlyUseCachedResults) {}
PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM) {
++RunCount;
- const TestAnalysisPass::Result &AR = AM->getResult<TestAnalysisPass>(F);
- AnalyzedInstrCount += AR.InstructionCount;
+ if (OnlyUseCachedResults) {
+ // Hack to force the use of the cached interface.
+ if (const TestAnalysisPass::Result *AR =
+ AM->getCachedResult<TestAnalysisPass>(F))
+ AnalyzedInstrCount += AR->InstructionCount;
+ } else {
+ // Typical path just runs the analysis as needed.
+ const TestAnalysisPass::Result &AR = AM->getResult<TestAnalysisPass>(F);
+ AnalyzedInstrCount += AR.InstructionCount;
+ }
return PreservedAnalyses::all();
}
int &RunCount;
int &AnalyzedInstrCount;
+ bool OnlyUseCachedResults;
};
// A test function pass that invalidates all function analyses for a function
@@ -178,6 +196,15 @@ TEST_F(PassManagerTest, Basic) {
FPM4.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4));
MPM.addPass(createModuleToFunctionPassAdaptor(FPM4));
+ // A fifth function pass manager but which uses only cached results.
+ FunctionPassManager FPM5;
+ int FunctionPassRunCount5 = 0;
+ int AnalyzedInstrCount5 = 0;
+ FPM5.addPass(TestInvalidationFunctionPass("f"));
+ FPM5.addPass(TestFunctionPass(FunctionPassRunCount5, AnalyzedInstrCount5,
+ /*OnlyUseCachedResults=*/true));
+ MPM.addPass(createModuleToFunctionPassAdaptor(FPM5));
+
MPM.run(M.get(), &MAM);
// Validate module pass counters.
@@ -192,6 +219,8 @@ TEST_F(PassManagerTest, Basic) {
EXPECT_EQ(5, AnalyzedInstrCount3);
EXPECT_EQ(3, FunctionPassRunCount4);
EXPECT_EQ(5, AnalyzedInstrCount4);
+ EXPECT_EQ(3, FunctionPassRunCount5);
+ EXPECT_EQ(2, AnalyzedInstrCount5); // Only 'g' and 'h' were cached.
// Validate the analysis counters:
// first run over 3 functions, then module pass invalidates
More information about the llvm-commits
mailing list