mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-10 20:33:15 +00:00
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195525 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
43d67d01e2
commit
b88831b204
@ -460,6 +460,26 @@ public:
|
|||||||
return static_cast<const ResultModelT &>(ResultConcept).Result;
|
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.
|
/// \brief Register an analysis pass with the manager.
|
||||||
///
|
///
|
||||||
/// This provides an initialized and set-up analysis pass to the
|
/// This provides an initialized and set-up analysis pass to the
|
||||||
@ -495,6 +515,10 @@ private:
|
|||||||
const detail::AnalysisResultConcept<Module *> &getResultImpl(void *PassID,
|
const detail::AnalysisResultConcept<Module *> &getResultImpl(void *PassID,
|
||||||
Module *M);
|
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.
|
/// \brief Invalidate a module pass result.
|
||||||
void invalidateImpl(void *PassID, Module *M);
|
void invalidateImpl(void *PassID, Module *M);
|
||||||
|
|
||||||
@ -537,6 +561,26 @@ public:
|
|||||||
return static_cast<const ResultModelT &>(ResultConcept).Result;
|
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.
|
/// \brief Register an analysis pass with the manager.
|
||||||
///
|
///
|
||||||
/// This provides an initialized and set-up analysis pass to the
|
/// This provides an initialized and set-up analysis pass to the
|
||||||
@ -583,6 +627,10 @@ private:
|
|||||||
const detail::AnalysisResultConcept<Function *> &getResultImpl(void *PassID,
|
const detail::AnalysisResultConcept<Function *> &getResultImpl(void *PassID,
|
||||||
Function *F);
|
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.
|
/// \brief Invalidate a function pass result.
|
||||||
void invalidateImpl(void *PassID, Function *F);
|
void invalidateImpl(void *PassID, Function *F);
|
||||||
|
|
||||||
|
@ -53,6 +53,12 @@ ModuleAnalysisManager::getResultImpl(void *PassID, Module *M) {
|
|||||||
return *RI->second;
|
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) {
|
void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) {
|
||||||
ModuleAnalysisResults.erase(PassID);
|
ModuleAnalysisResults.erase(PassID);
|
||||||
}
|
}
|
||||||
@ -122,6 +128,13 @@ FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) {
|
|||||||
return *RI->second->second;
|
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) {
|
void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) {
|
||||||
FunctionAnalysisResultMapT::iterator RI =
|
FunctionAnalysisResultMapT::iterator RI =
|
||||||
FunctionAnalysisResults.find(std::make_pair(PassID, F));
|
FunctionAnalysisResults.find(std::make_pair(PassID, F));
|
||||||
|
@ -69,28 +69,46 @@ struct TestPreservingModulePass {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct TestMinPreservingModulePass {
|
struct TestMinPreservingModulePass {
|
||||||
PreservedAnalyses run(Module *M) {
|
PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) {
|
||||||
PreservedAnalyses PA;
|
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>();
|
PA.preserve<FunctionAnalysisManagerModuleProxy>();
|
||||||
return PA;
|
return PA;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TestFunctionPass {
|
struct TestFunctionPass {
|
||||||
TestFunctionPass(int &RunCount, int &AnalyzedInstrCount)
|
TestFunctionPass(int &RunCount, int &AnalyzedInstrCount,
|
||||||
: RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount) {}
|
bool OnlyUseCachedResults = false)
|
||||||
|
: RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount),
|
||||||
|
OnlyUseCachedResults(OnlyUseCachedResults) {}
|
||||||
|
|
||||||
PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM) {
|
PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM) {
|
||||||
++RunCount;
|
++RunCount;
|
||||||
|
|
||||||
|
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);
|
const TestAnalysisPass::Result &AR = AM->getResult<TestAnalysisPass>(F);
|
||||||
AnalyzedInstrCount += AR.InstructionCount;
|
AnalyzedInstrCount += AR.InstructionCount;
|
||||||
|
}
|
||||||
|
|
||||||
return PreservedAnalyses::all();
|
return PreservedAnalyses::all();
|
||||||
}
|
}
|
||||||
|
|
||||||
int &RunCount;
|
int &RunCount;
|
||||||
int &AnalyzedInstrCount;
|
int &AnalyzedInstrCount;
|
||||||
|
bool OnlyUseCachedResults;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A test function pass that invalidates all function analyses for a function
|
// 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));
|
FPM4.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4));
|
||||||
MPM.addPass(createModuleToFunctionPassAdaptor(FPM4));
|
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);
|
MPM.run(M.get(), &MAM);
|
||||||
|
|
||||||
// Validate module pass counters.
|
// Validate module pass counters.
|
||||||
@ -192,6 +219,8 @@ TEST_F(PassManagerTest, Basic) {
|
|||||||
EXPECT_EQ(5, AnalyzedInstrCount3);
|
EXPECT_EQ(5, AnalyzedInstrCount3);
|
||||||
EXPECT_EQ(3, FunctionPassRunCount4);
|
EXPECT_EQ(3, FunctionPassRunCount4);
|
||||||
EXPECT_EQ(5, AnalyzedInstrCount4);
|
EXPECT_EQ(5, AnalyzedInstrCount4);
|
||||||
|
EXPECT_EQ(3, FunctionPassRunCount5);
|
||||||
|
EXPECT_EQ(2, AnalyzedInstrCount5); // Only 'g' and 'h' were cached.
|
||||||
|
|
||||||
// Validate the analysis counters:
|
// Validate the analysis counters:
|
||||||
// first run over 3 functions, then module pass invalidates
|
// first run over 3 functions, then module pass invalidates
|
||||||
|
Loading…
x
Reference in New Issue
Block a user