[PM] Fold all three analysis managers into a single AnalysisManager

template.

This consolidates three copies of nearly the same core logic. It adds
"complexity" to the ModuleAnalysisManager in that it makes it possible
to share a ModuleAnalysisManager across multiple modules... But it does
so by deleting *all of the code*, so I'm OK with that. This will
naturally make fixing bugs in this code much simpler, etc.

The only down side here is that we have to use 'typename' and 'this->'
in various places, and the implementation is lifted into the header.
I'll take that for the code size reduction.

The convenient names are still typedef-ed and used throughout so that
users can largely ignore this aspect of the implementation.

The follow-up change to this will do the exact same refactoring for the
PassManagers. =D

It turns out that the interesting different code is almost entirely in
the adaptors. At the end, that should be essentially all that is left.

llvm-svn: 225757
This commit is contained in:
Chandler Carruth 2015-01-13 02:51:47 +00:00
parent 36d0b2b49f
commit 7ad6d620b7
8 changed files with 219 additions and 515 deletions

View File

@ -26,7 +26,13 @@
namespace llvm {
class CGSCCAnalysisManager;
/// \brief The CGSCC analysis manager.
///
/// See the documentation for the AnalysisManager template for detail
/// documentation. This typedef serves as a convenient way to refer to this
/// construct in the adaptors and proxies used to integrate this into the larger
/// pass manager infrastructure.
typedef AnalysisManager<LazyCallGraph::SCC> CGSCCAnalysisManager;
class CGSCCPassManager {
public:
@ -67,92 +73,6 @@ private:
std::vector<std::unique_ptr<CGSCCPassConcept>> Passes;
};
/// \brief A function analysis manager to coordinate and cache analyses run over
/// a module.
class CGSCCAnalysisManager
: public detail::AnalysisManagerBase<CGSCCAnalysisManager,
LazyCallGraph::SCC> {
friend class detail::AnalysisManagerBase<CGSCCAnalysisManager,
LazyCallGraph::SCC>;
typedef detail::AnalysisManagerBase<CGSCCAnalysisManager, LazyCallGraph::SCC>
BaseT;
typedef BaseT::ResultConceptT ResultConceptT;
typedef BaseT::PassConceptT PassConceptT;
public:
// Most public APIs are inherited from the CRTP base class.
// We have to explicitly define all the special member functions because MSVC
// refuses to generate them.
CGSCCAnalysisManager() {}
CGSCCAnalysisManager(CGSCCAnalysisManager &&Arg)
: BaseT(std::move(static_cast<BaseT &>(Arg))),
CGSCCAnalysisResults(std::move(Arg.CGSCCAnalysisResults)) {}
CGSCCAnalysisManager &operator=(CGSCCAnalysisManager &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
CGSCCAnalysisResults = std::move(RHS.CGSCCAnalysisResults);
return *this;
}
/// \brief Returns true if the analysis manager has an empty results cache.
bool empty() const;
/// \brief Clear the function analysis result cache.
///
/// This routine allows cleaning up when the set of functions itself has
/// potentially changed, and thus we can't even look up a a result and
/// invalidate it directly. Notably, this does *not* call invalidate
/// functions as there is nothing to be done for them.
void clear();
private:
CGSCCAnalysisManager(const CGSCCAnalysisManager &) LLVM_DELETED_FUNCTION;
CGSCCAnalysisManager &
operator=(const CGSCCAnalysisManager &) LLVM_DELETED_FUNCTION;
/// \brief Get a function pass result, running the pass if necessary.
ResultConceptT &getResultImpl(void *PassID, LazyCallGraph::SCC &C);
/// \brief Get a cached function pass result or return null.
ResultConceptT *getCachedResultImpl(void *PassID,
LazyCallGraph::SCC &C) const;
/// \brief Invalidate a function pass result.
void invalidateImpl(void *PassID, LazyCallGraph::SCC &C);
/// \brief Invalidate the results for a function..
PreservedAnalyses invalidateImpl(LazyCallGraph::SCC &C, PreservedAnalyses PA);
/// \brief List of function analysis pass IDs and associated concept pointers.
///
/// Requires iterators to be valid across appending new entries and arbitrary
/// erases. Provides both the pass ID and concept pointer such that it is
/// half of a bijection and provides storage for the actual result concept.
typedef std::list<std::pair<
void *,
std::unique_ptr<detail::AnalysisResultConcept<LazyCallGraph::SCC>>>>
CGSCCAnalysisResultListT;
/// \brief Map type from function pointer to our custom list type.
typedef DenseMap<LazyCallGraph::SCC *, CGSCCAnalysisResultListT>
CGSCCAnalysisResultListMapT;
/// \brief Map from function to a list of function analysis results.
///
/// Provides linear time removal of all analysis results for a function and
/// the ultimate storage for a particular cached analysis result.
CGSCCAnalysisResultListMapT CGSCCAnalysisResultLists;
/// \brief Map type from a pair of analysis ID and function pointer to an
/// iterator into a particular result list.
typedef DenseMap<std::pair<void *, LazyCallGraph::SCC *>,
CGSCCAnalysisResultListT::iterator> CGSCCAnalysisResultMapT;
/// \brief Map from an analysis ID and function to a particular cached
/// analysis result.
CGSCCAnalysisResultMapT CGSCCAnalysisResults;
};
/// \brief A module analysis which acts as a proxy for a CGSCC analysis
/// manager.
///

View File

@ -46,11 +46,11 @@
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/Allocator.h"
#include <iterator>
namespace llvm {
class ModuleAnalysisManager;
class PreservedAnalyses;
class raw_ostream;

View File

@ -248,6 +248,12 @@ public:
/// @returns the module identifier as a string
const std::string &getModuleIdentifier() const { return ModuleID; }
/// \brief Get a short "name" for the module.
///
/// This is useful for debugging or logging. It is essentially a convenience
/// wrapper around getModuleIdentifier().
StringRef getName() const { return ModuleID; }
/// Get the data layout string for the module's target platform. This is
/// equivalent to getDataLayout()->getStringRepresentation().
const std::string &getDataLayoutStr() const { return DataLayoutStr; }

View File

@ -44,6 +44,8 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManagerInternal.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/type_traits.h"
#include <list>
#include <memory>
@ -54,6 +56,13 @@ namespace llvm {
class Module;
class Function;
namespace detail {
// Declare our debug option here so we can refer to it from templates.
extern cl::opt<bool> DebugPM;
} // End detail namespace
/// \brief An abstract set of preserved analyses following a transformation pass
/// run.
///
@ -160,8 +169,11 @@ private:
SmallPtrSet<void *, 2> PreservedPassIDs;
};
// We define the pass managers prior to the analysis managers that they use.
class ModuleAnalysisManager;
// Forward declare the analysis manager template and two typedefs used in the
// pass managers.
template <typename IRUnitT> class AnalysisManager;
typedef AnalysisManager<Module> ModuleAnalysisManager;
typedef AnalysisManager<Function> FunctionAnalysisManager;
/// \brief Manages a sequence of passes over Modules of IR.
///
@ -218,9 +230,6 @@ private:
std::vector<std::unique_ptr<ModulePassConcept>> Passes;
};
// We define the pass managers prior to the analysis managers that they use.
class FunctionAnalysisManager;
/// \brief Manages a sequence of passes over a Function of IR.
///
/// A function pass manager contains a sequence of function passes. It is also
@ -297,6 +306,12 @@ namespace detail {
/// - invalidateImpl
///
/// The details of the call pattern are within.
///
/// Note that there is also a generic analysis manager template which implements
/// the above required functions along with common datastructures used for
/// managing analyses. This base class is factored so that if you need to
/// customize the handling of a specific IR unit, you can do so without
/// replicating *all* of the boilerplate.
template <typename DerivedT, typename IRUnitT> class AnalysisManagerBase {
DerivedT *derived_this() { return static_cast<DerivedT *>(this); }
const DerivedT *derived_this() const {
@ -419,107 +434,146 @@ private:
} // End namespace detail
/// \brief A module analysis pass manager with lazy running and caching of
/// \brief A generic analysis pass manager with lazy running and caching of
/// results.
class ModuleAnalysisManager
: public detail::AnalysisManagerBase<ModuleAnalysisManager, Module> {
friend class detail::AnalysisManagerBase<ModuleAnalysisManager, Module>;
typedef detail::AnalysisManagerBase<ModuleAnalysisManager, Module> BaseT;
typedef BaseT::ResultConceptT ResultConceptT;
typedef BaseT::PassConceptT PassConceptT;
public:
// We have to explicitly define all the special member functions because MSVC
// refuses to generate them.
ModuleAnalysisManager() {}
ModuleAnalysisManager(ModuleAnalysisManager &&Arg)
: BaseT(std::move(static_cast<BaseT &>(Arg))),
ModuleAnalysisResults(std::move(Arg.ModuleAnalysisResults)) {}
ModuleAnalysisManager &operator=(ModuleAnalysisManager &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
ModuleAnalysisResults = std::move(RHS.ModuleAnalysisResults);
return *this;
}
private:
ModuleAnalysisManager(const ModuleAnalysisManager &) LLVM_DELETED_FUNCTION;
ModuleAnalysisManager &
operator=(const ModuleAnalysisManager &) LLVM_DELETED_FUNCTION;
/// \brief Get a module pass result, running the pass if necessary.
ResultConceptT &getResultImpl(void *PassID, Module &M);
/// \brief Get a cached module pass result or return null.
ResultConceptT *getCachedResultImpl(void *PassID, Module &M) const;
/// \brief Invalidate a module pass result.
void invalidateImpl(void *PassID, Module &M);
/// \brief Invalidate results across a module.
PreservedAnalyses invalidateImpl(Module &M, PreservedAnalyses PA);
/// \brief Map type from module analysis pass ID to pass result concept
/// pointer.
typedef DenseMap<void *,
std::unique_ptr<detail::AnalysisResultConcept<Module>>>
ModuleAnalysisResultMapT;
/// \brief Cache of computed module analysis results for this module.
ModuleAnalysisResultMapT ModuleAnalysisResults;
};
/// \brief A function analysis manager to coordinate and cache analyses run over
/// a module.
class FunctionAnalysisManager
: public detail::AnalysisManagerBase<FunctionAnalysisManager, Function> {
friend class detail::AnalysisManagerBase<FunctionAnalysisManager, Function>;
typedef detail::AnalysisManagerBase<FunctionAnalysisManager, Function> BaseT;
typedef BaseT::ResultConceptT ResultConceptT;
typedef BaseT::PassConceptT PassConceptT;
///
/// This analysis manager can be used for any IR unit where the address of the
/// IR unit sufficies as its identity. It manages the cache for a unit of IR via
/// the address of each unit of IR cached.
template <typename IRUnitT>
class AnalysisManager
: public detail::AnalysisManagerBase<AnalysisManager<IRUnitT>, IRUnitT> {
friend class detail::AnalysisManagerBase<AnalysisManager<IRUnitT>, IRUnitT>;
typedef detail::AnalysisManagerBase<AnalysisManager<IRUnitT>, IRUnitT> BaseT;
typedef typename BaseT::ResultConceptT ResultConceptT;
typedef typename BaseT::PassConceptT PassConceptT;
public:
// Most public APIs are inherited from the CRTP base class.
// We have to explicitly define all the special member functions because MSVC
// refuses to generate them.
FunctionAnalysisManager() {}
FunctionAnalysisManager(FunctionAnalysisManager &&Arg)
AnalysisManager() {}
AnalysisManager(AnalysisManager &&Arg)
: BaseT(std::move(static_cast<BaseT &>(Arg))),
FunctionAnalysisResults(std::move(Arg.FunctionAnalysisResults)) {}
FunctionAnalysisManager &operator=(FunctionAnalysisManager &&RHS) {
AnalysisResults(std::move(Arg.AnalysisResults)) {}
AnalysisManager &operator=(AnalysisManager &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
FunctionAnalysisResults = std::move(RHS.FunctionAnalysisResults);
AnalysisResults = std::move(RHS.AnalysisResults);
return *this;
}
/// \brief Returns true if the analysis manager has an empty results cache.
bool empty() const;
bool empty() const {
assert(AnalysisResults.empty() == AnalysisResultLists.empty() &&
"The storage and index of analysis results disagree on how many "
"there are!");
return AnalysisResults.empty();
}
/// \brief Clear the function analysis result cache.
/// \brief Clear the analysis result cache.
///
/// This routine allows cleaning up when the set of functions itself has
/// This routine allows cleaning up when the set of IR units itself has
/// potentially changed, and thus we can't even look up a a result and
/// invalidate it directly. Notably, this does *not* call invalidate
/// functions as there is nothing to be done for them.
void clear();
/// invalidate it directly. Notably, this does *not* call invalidate functions
/// as there is nothing to be done for them.
void clear() {
AnalysisResults.clear();
AnalysisResultLists.clear();
}
private:
FunctionAnalysisManager(const FunctionAnalysisManager &)
LLVM_DELETED_FUNCTION;
FunctionAnalysisManager &
operator=(const FunctionAnalysisManager &) LLVM_DELETED_FUNCTION;
AnalysisManager(const AnalysisManager &) LLVM_DELETED_FUNCTION;
AnalysisManager &operator=(const AnalysisManager &) LLVM_DELETED_FUNCTION;
/// \brief Get a function pass result, running the pass if necessary.
ResultConceptT &getResultImpl(void *PassID, Function &F);
/// \brief Get an analysis result, running the pass if necessary.
ResultConceptT &getResultImpl(void *PassID, IRUnitT &IR) {
typename AnalysisResultMapT::iterator RI;
bool Inserted;
std::tie(RI, Inserted) = AnalysisResults.insert(std::make_pair(
std::make_pair(PassID, &IR), typename AnalysisResultListT::iterator()));
/// \brief Get a cached function pass result or return null.
ResultConceptT *getCachedResultImpl(void *PassID, Function &F) const;
// If we don't have a cached result for this function, look up the pass and
// run it to produce a result, which we then add to the cache.
if (Inserted) {
auto &P = this->lookupPass(PassID);
if (detail::DebugPM)
dbgs() << "Running analysis: " << P.name() << "\n";
AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
ResultList.emplace_back(PassID, P.run(IR, this));
RI->second = std::prev(ResultList.end());
}
return *RI->second->second;
}
/// \brief Get a cached analysis result or return null.
ResultConceptT *getCachedResultImpl(void *PassID, IRUnitT &IR) const {
typename AnalysisResultMapT::const_iterator RI =
AnalysisResults.find(std::make_pair(PassID, &IR));
return RI == AnalysisResults.end() ? nullptr : &*RI->second->second;
}
/// \brief Invalidate a function pass result.
void invalidateImpl(void *PassID, Function &F);
void invalidateImpl(void *PassID, IRUnitT &IR) {
typename AnalysisResultMapT::iterator RI =
AnalysisResults.find(std::make_pair(PassID, &IR));
if (RI == AnalysisResults.end())
return;
if (detail::DebugPM)
dbgs() << "Invalidating analysis: " << this->lookupPass(PassID).name()
<< "\n";
AnalysisResultLists[&IR].erase(RI->second);
AnalysisResults.erase(RI);
}
/// \brief Invalidate the results for a function..
PreservedAnalyses invalidateImpl(Function &F, PreservedAnalyses PA);
PreservedAnalyses invalidateImpl(IRUnitT &IR, PreservedAnalyses PA) {
// Short circuit for a common case of all analyses being preserved.
if (PA.areAllPreserved())
return std::move(PA);
if (detail::DebugPM)
dbgs() << "Invalidating all non-preserved analyses for: "
<< IR.getName() << "\n";
// Clear all the invalidated results associated specifically with this
// function.
SmallVector<void *, 8> InvalidatedPassIDs;
AnalysisResultListT &ResultsList = AnalysisResultLists[&IR];
for (typename AnalysisResultListT::iterator I = ResultsList.begin(),
E = ResultsList.end();
I != E;) {
void *PassID = I->first;
// Pass the invalidation down to the pass itself to see if it thinks it is
// necessary. The analysis pass can return false if no action on the part
// of the analysis manager is required for this invalidation event.
if (I->second->invalidate(IR, PA)) {
if (detail::DebugPM)
dbgs() << "Invalidating analysis: " << this->lookupPass(PassID).name()
<< "\n";
InvalidatedPassIDs.push_back(I->first);
I = ResultsList.erase(I);
} else {
++I;
}
// After handling each pass, we mark it as preserved. Once we've
// invalidated any stale results, the rest of the system is allowed to
// start preserving this analysis again.
PA.preserve(PassID);
}
while (!InvalidatedPassIDs.empty())
AnalysisResults.erase(
std::make_pair(InvalidatedPassIDs.pop_back_val(), &IR));
if (ResultsList.empty())
AnalysisResultLists.erase(&IR);
return std::move(PA);
}
/// \brief List of function analysis pass IDs and associated concept pointers.
///
@ -527,28 +581,26 @@ private:
/// erases. Provides both the pass ID and concept pointer such that it is
/// half of a bijection and provides storage for the actual result concept.
typedef std::list<std::pair<
void *, std::unique_ptr<detail::AnalysisResultConcept<Function>>>>
FunctionAnalysisResultListT;
void *, std::unique_ptr<detail::AnalysisResultConcept<IRUnitT>>>>
AnalysisResultListT;
/// \brief Map type from function pointer to our custom list type.
typedef DenseMap<Function *, FunctionAnalysisResultListT>
FunctionAnalysisResultListMapT;
typedef DenseMap<IRUnitT *, AnalysisResultListT> AnalysisResultListMapT;
/// \brief Map from function to a list of function analysis results.
///
/// Provides linear time removal of all analysis results for a function and
/// the ultimate storage for a particular cached analysis result.
FunctionAnalysisResultListMapT FunctionAnalysisResultLists;
AnalysisResultListMapT AnalysisResultLists;
/// \brief Map type from a pair of analysis ID and function pointer to an
/// iterator into a particular result list.
typedef DenseMap<std::pair<void *, Function *>,
FunctionAnalysisResultListT::iterator>
FunctionAnalysisResultMapT;
typedef DenseMap<std::pair<void *, IRUnitT *>,
typename AnalysisResultListT::iterator> AnalysisResultMapT;
/// \brief Map from an analysis ID and function to a particular cached
/// analysis result.
FunctionAnalysisResultMapT FunctionAnalysisResults;
AnalysisResultMapT AnalysisResults;
};
/// \brief A module analysis which acts as a proxy for a function analysis

View File

@ -49,106 +49,6 @@ PreservedAnalyses CGSCCPassManager::run(LazyCallGraph::SCC &C,
return PA;
}
bool CGSCCAnalysisManager::empty() const {
assert(CGSCCAnalysisResults.empty() == CGSCCAnalysisResultLists.empty() &&
"The storage and index of analysis results disagree on how many there "
"are!");
return CGSCCAnalysisResults.empty();
}
void CGSCCAnalysisManager::clear() {
CGSCCAnalysisResults.clear();
CGSCCAnalysisResultLists.clear();
}
CGSCCAnalysisManager::ResultConceptT &
CGSCCAnalysisManager::getResultImpl(void *PassID, LazyCallGraph::SCC &C) {
CGSCCAnalysisResultMapT::iterator RI;
bool Inserted;
std::tie(RI, Inserted) = CGSCCAnalysisResults.insert(std::make_pair(
std::make_pair(PassID, &C), CGSCCAnalysisResultListT::iterator()));
// If we don't have a cached result for this function, look up the pass and
// run it to produce a result, which we then add to the cache.
if (Inserted) {
auto &P = lookupPass(PassID);
if (DebugPM)
dbgs() << "Running CGSCC analysis: " << P.name() << "\n";
CGSCCAnalysisResultListT &ResultList = CGSCCAnalysisResultLists[&C];
ResultList.emplace_back(PassID, P.run(C, this));
RI->second = std::prev(ResultList.end());
}
return *RI->second->second;
}
CGSCCAnalysisManager::ResultConceptT *
CGSCCAnalysisManager::getCachedResultImpl(void *PassID,
LazyCallGraph::SCC &C) const {
CGSCCAnalysisResultMapT::const_iterator RI =
CGSCCAnalysisResults.find(std::make_pair(PassID, &C));
return RI == CGSCCAnalysisResults.end() ? nullptr : &*RI->second->second;
}
void CGSCCAnalysisManager::invalidateImpl(void *PassID, LazyCallGraph::SCC &C) {
CGSCCAnalysisResultMapT::iterator RI =
CGSCCAnalysisResults.find(std::make_pair(PassID, &C));
if (RI == CGSCCAnalysisResults.end())
return;
if (DebugPM)
dbgs() << "Invalidating CGSCC analysis: " << lookupPass(PassID).name()
<< "\n";
CGSCCAnalysisResultLists[&C].erase(RI->second);
CGSCCAnalysisResults.erase(RI);
}
PreservedAnalyses CGSCCAnalysisManager::invalidateImpl(LazyCallGraph::SCC &C,
PreservedAnalyses PA) {
// Short circuit for a common case of all analyses being preserved.
if (PA.areAllPreserved())
return std::move(PA);
if (DebugPM)
dbgs() << "Invalidating all non-preserved analyses for SCC: " << C.getName()
<< "\n";
// Clear all the invalidated results associated specifically with this
// function.
SmallVector<void *, 8> InvalidatedPassIDs;
CGSCCAnalysisResultListT &ResultsList = CGSCCAnalysisResultLists[&C];
for (CGSCCAnalysisResultListT::iterator I = ResultsList.begin(),
E = ResultsList.end();
I != E;) {
void *PassID = I->first;
// Pass the invalidation down to the pass itself to see if it thinks it is
// necessary. The analysis pass can return false if no action on the part
// of the analysis manager is required for this invalidation event.
if (I->second->invalidate(C, PA)) {
if (DebugPM)
dbgs() << "Invalidating CGSCC analysis: " << lookupPass(PassID).name()
<< "\n";
InvalidatedPassIDs.push_back(I->first);
I = ResultsList.erase(I);
} else {
++I;
}
// After handling each pass, we mark it as preserved. Once we've
// invalidated any stale results, the rest of the system is allowed to
// start preserving this analysis again.
PA.preserve(PassID);
}
while (!InvalidatedPassIDs.empty())
CGSCCAnalysisResults.erase(
std::make_pair(InvalidatedPassIDs.pop_back_val(), &C));
CGSCCAnalysisResultLists.erase(&C);
return std::move(PA);
}
char CGSCCAnalysisManagerModuleProxy::PassID;
CGSCCAnalysisManagerModuleProxy::Result

View File

@ -10,14 +10,13 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
using namespace llvm;
using llvm::detail::DebugPM;
static cl::opt<bool>
DebugPM("debug-pass-manager", cl::Hidden,
cl::desc("Print pass management debugging information"));
cl::opt<bool> llvm::detail::DebugPM(
"debug-pass-manager", cl::Hidden,
cl::desc("Print pass management debugging information"));
PreservedAnalyses ModulePassManager::run(Module &M, ModuleAnalysisManager *AM) {
PreservedAnalyses PA = PreservedAnalyses::all();
@ -52,76 +51,6 @@ PreservedAnalyses ModulePassManager::run(Module &M, ModuleAnalysisManager *AM) {
return PA;
}
ModuleAnalysisManager::ResultConceptT &
ModuleAnalysisManager::getResultImpl(void *PassID, Module &M) {
ModuleAnalysisResultMapT::iterator RI;
bool Inserted;
std::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair(
PassID, std::unique_ptr<detail::AnalysisResultConcept<Module>>()));
// If we don't have a cached result for this module, look up the pass and run
// it to produce a result, which we then add to the cache.
if (Inserted) {
auto &P = lookupPass(PassID);
if (DebugPM)
dbgs() << "Running module analysis: " << P.name() << "\n";
RI->second = P.run(M, this);
}
return *RI->second;
}
ModuleAnalysisManager::ResultConceptT *
ModuleAnalysisManager::getCachedResultImpl(void *PassID, Module &M) const {
ModuleAnalysisResultMapT::const_iterator RI =
ModuleAnalysisResults.find(PassID);
return RI == ModuleAnalysisResults.end() ? nullptr : &*RI->second;
}
void ModuleAnalysisManager::invalidateImpl(void *PassID, Module &M) {
if (DebugPM)
dbgs() << "Invalidating module analysis: " << lookupPass(PassID).name()
<< "\n";
ModuleAnalysisResults.erase(PassID);
}
PreservedAnalyses ModuleAnalysisManager::invalidateImpl(Module &M,
PreservedAnalyses PA) {
// Short circuit for a common case of all analyses being preserved.
if (PA.areAllPreserved())
return std::move(PA);
if (DebugPM)
dbgs() << "Invalidating all non-preserved analyses for module: "
<< M.getModuleIdentifier() << "\n";
// FIXME: This is a total hack based on the fact that erasure doesn't
// invalidate iteration for DenseMap.
for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(),
E = ModuleAnalysisResults.end();
I != E; ++I) {
void *PassID = I->first;
// Pass the invalidation down to the pass itself to see if it thinks it is
// necessary. The analysis pass can return false if no action on the part
// of the analysis manager is required for this invalidation event.
if (I->second->invalidate(M, PA)) {
if (DebugPM)
dbgs() << "Invalidating module analysis: " << lookupPass(PassID).name()
<< "\n";
ModuleAnalysisResults.erase(I);
}
// After handling each pass, we mark it as preserved. Once we've
// invalidated any stale results, the rest of the system is allowed to
// start preserving this analysis again.
PA.preserve(PassID);
}
return std::move(PA);
}
PreservedAnalyses FunctionPassManager::run(Function &F,
FunctionAnalysisManager *AM) {
PreservedAnalyses PA = PreservedAnalyses::all();
@ -156,107 +85,6 @@ PreservedAnalyses FunctionPassManager::run(Function &F,
return PA;
}
bool FunctionAnalysisManager::empty() const {
assert(FunctionAnalysisResults.empty() ==
FunctionAnalysisResultLists.empty() &&
"The storage and index of analysis results disagree on how many there "
"are!");
return FunctionAnalysisResults.empty();
}
void FunctionAnalysisManager::clear() {
FunctionAnalysisResults.clear();
FunctionAnalysisResultLists.clear();
}
FunctionAnalysisManager::ResultConceptT &
FunctionAnalysisManager::getResultImpl(void *PassID, Function &F) {
FunctionAnalysisResultMapT::iterator RI;
bool Inserted;
std::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair(
std::make_pair(PassID, &F), FunctionAnalysisResultListT::iterator()));
// If we don't have a cached result for this function, look up the pass and
// run it to produce a result, which we then add to the cache.
if (Inserted) {
auto &P = lookupPass(PassID);
if (DebugPM)
dbgs() << "Running function analysis: " << P.name() << "\n";
FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[&F];
ResultList.emplace_back(PassID, P.run(F, this));
RI->second = std::prev(ResultList.end());
}
return *RI->second->second;
}
FunctionAnalysisManager::ResultConceptT *
FunctionAnalysisManager::getCachedResultImpl(void *PassID, Function &F) const {
FunctionAnalysisResultMapT::const_iterator RI =
FunctionAnalysisResults.find(std::make_pair(PassID, &F));
return RI == FunctionAnalysisResults.end() ? nullptr : &*RI->second->second;
}
void FunctionAnalysisManager::invalidateImpl(void *PassID, Function &F) {
FunctionAnalysisResultMapT::iterator RI =
FunctionAnalysisResults.find(std::make_pair(PassID, &F));
if (RI == FunctionAnalysisResults.end())
return;
if (DebugPM)
dbgs() << "Invalidating function analysis: " << lookupPass(PassID).name()
<< "\n";
FunctionAnalysisResultLists[&F].erase(RI->second);
FunctionAnalysisResults.erase(RI);
}
PreservedAnalyses
FunctionAnalysisManager::invalidateImpl(Function &F, PreservedAnalyses PA) {
// Short circuit for a common case of all analyses being preserved.
if (PA.areAllPreserved())
return std::move(PA);
if (DebugPM)
dbgs() << "Invalidating all non-preserved analyses for function: "
<< F.getName() << "\n";
// Clear all the invalidated results associated specifically with this
// function.
SmallVector<void *, 8> InvalidatedPassIDs;
FunctionAnalysisResultListT &ResultsList = FunctionAnalysisResultLists[&F];
for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(),
E = ResultsList.end();
I != E;) {
void *PassID = I->first;
// Pass the invalidation down to the pass itself to see if it thinks it is
// necessary. The analysis pass can return false if no action on the part
// of the analysis manager is required for this invalidation event.
if (I->second->invalidate(F, PA)) {
if (DebugPM)
dbgs() << "Invalidating function analysis: "
<< lookupPass(PassID).name() << "\n";
InvalidatedPassIDs.push_back(I->first);
I = ResultsList.erase(I);
} else {
++I;
}
// After handling each pass, we mark it as preserved. Once we've
// invalidated any stale results, the rest of the system is allowed to
// start preserving this analysis again.
PA.preserve(PassID);
}
while (!InvalidatedPassIDs.empty())
FunctionAnalysisResults.erase(
std::make_pair(InvalidatedPassIDs.pop_back_val(), &F));
if (ResultsList.empty())
FunctionAnalysisResultLists.erase(&F);
return std::move(PA);
}
char FunctionAnalysisManagerModuleProxy::PassID;
FunctionAnalysisManagerModuleProxy::Result

View File

@ -20,8 +20,8 @@
; RUN: | FileCheck %s --check-prefix=CHECK-CGSCC-PASS
; CHECK-CGSCC-PASS: Starting module pass manager
; CHECK-CGSCC-PASS-NEXT: Running module pass: ModuleToPostOrderCGSCCPassAdaptor
; CHECK-CGSCC-PASS-NEXT: Running module analysis: CGSCCAnalysisManagerModuleProxy
; CHECK-CGSCC-PASS-NEXT: Running module analysis: Lazy CallGraph Analysis
; CHECK-CGSCC-PASS-NEXT: Running analysis: CGSCCAnalysisManagerModuleProxy
; CHECK-CGSCC-PASS-NEXT: Running analysis: Lazy CallGraph Analysis
; CHECK-CGSCC-PASS-NEXT: Starting CGSCC pass manager run.
; CHECK-CGSCC-PASS-NEXT: Running CGSCC pass: NoOpCGSCCPass
; CHECK-CGSCC-PASS-NEXT: Finished CGSCC pass manager run.
@ -35,7 +35,7 @@
; RUN: | FileCheck %s --check-prefix=CHECK-FUNCTION-PASS
; CHECK-FUNCTION-PASS: Starting module pass manager
; CHECK-FUNCTION-PASS-NEXT: Running module pass: ModuleToFunctionPassAdaptor
; CHECK-FUNCTION-PASS-NEXT: Running module analysis: FunctionAnalysisManagerModuleProxy
; CHECK-FUNCTION-PASS-NEXT: Running analysis: FunctionAnalysisManagerModuleProxy
; CHECK-FUNCTION-PASS-NEXT: Starting function pass manager run.
; CHECK-FUNCTION-PASS-NEXT: Running function pass: NoOpFunctionPass
; CHECK-FUNCTION-PASS-NEXT: Finished function pass manager run.
@ -65,7 +65,7 @@
; CHECK-FUNCTION-PRINT: Starting module pass manager
; CHECK-FUNCTION-PRINT: Running module pass: VerifierPass
; CHECK-FUNCTION-PRINT: Running module pass: ModuleToFunctionPassAdaptor
; CHECK-FUNCTION-PRINT: Running module analysis: FunctionAnalysisManagerModuleProxy
; CHECK-FUNCTION-PRINT: Running analysis: FunctionAnalysisManagerModuleProxy
; CHECK-FUNCTION-PRINT: Starting function pass manager
; CHECK-FUNCTION-PRINT: Running function pass: PrintFunctionPass
; CHECK-FUNCTION-PRINT-NOT: ModuleID
@ -127,13 +127,13 @@
; RUN: | FileCheck %s --check-prefix=CHECK-ANALYSES
; CHECK-ANALYSES: Starting module pass manager
; CHECK-ANALYSES: Running module pass: RequireAnalysisPass
; CHECK-ANALYSES: Running module analysis: NoOpModuleAnalysis
; CHECK-ANALYSES: Running analysis: NoOpModuleAnalysis
; CHECK-ANALYSES: Starting CGSCC pass manager
; CHECK-ANALYSES: Running CGSCC pass: RequireAnalysisPass
; CHECK-ANALYSES: Running CGSCC analysis: NoOpCGSCCAnalysis
; CHECK-ANALYSES: Running analysis: NoOpCGSCCAnalysis
; CHECK-ANALYSES: Starting function pass manager
; CHECK-ANALYSES: Running function pass: RequireAnalysisPass
; CHECK-ANALYSES: Running function analysis: NoOpFunctionAnalysis
; CHECK-ANALYSES: Running analysis: NoOpFunctionAnalysis
; Make sure no-op passes that preserve all analyses don't even try to do any
; analysis invalidation.
@ -148,81 +148,81 @@
; RUN: | FileCheck %s --check-prefix=CHECK-DO-CACHE-MODULE-ANALYSIS-RESULTS
; CHECK-DO-CACHE-MODULE-ANALYSIS-RESULTS: Starting module pass manager
; CHECK-DO-CACHE-MODULE-ANALYSIS-RESULTS: Running module pass: RequireAnalysisPass
; CHECK-DO-CACHE-MODULE-ANALYSIS-RESULTS: Running module analysis: NoOpModuleAnalysis
; CHECK-DO-CACHE-MODULE-ANALYSIS-RESULTS-NOT: Running module analysis: NoOpModuleAnalysis
; CHECK-DO-CACHE-MODULE-ANALYSIS-RESULTS: Running analysis: NoOpModuleAnalysis
; CHECK-DO-CACHE-MODULE-ANALYSIS-RESULTS-NOT: Running analysis: NoOpModuleAnalysis
; RUN: opt -disable-output -debug-pass-manager -debug-cgscc-pass-manager \
; RUN: -passes='require<no-op-module>,invalidate<no-op-module>,require<no-op-module>' %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-DO-INVALIDATE-MODULE-ANALYSIS-RESULTS
; CHECK-DO-INVALIDATE-MODULE-ANALYSIS-RESULTS: Starting module pass manager
; CHECK-DO-INVALIDATE-MODULE-ANALYSIS-RESULTS: Running module pass: RequireAnalysisPass
; CHECK-DO-INVALIDATE-MODULE-ANALYSIS-RESULTS: Running module analysis: NoOpModuleAnalysis
; CHECK-DO-INVALIDATE-MODULE-ANALYSIS-RESULTS: Invalidating module analysis: NoOpModuleAnalysis
; CHECK-DO-INVALIDATE-MODULE-ANALYSIS-RESULTS: Running module analysis: NoOpModuleAnalysis
; CHECK-DO-INVALIDATE-MODULE-ANALYSIS-RESULTS: Running analysis: NoOpModuleAnalysis
; CHECK-DO-INVALIDATE-MODULE-ANALYSIS-RESULTS: Invalidating analysis: NoOpModuleAnalysis
; CHECK-DO-INVALIDATE-MODULE-ANALYSIS-RESULTS: Running analysis: NoOpModuleAnalysis
; RUN: opt -disable-output -debug-pass-manager -debug-cgscc-pass-manager \
; RUN: -passes='cgscc(require<no-op-cgscc>,require<no-op-cgscc>,require<no-op-cgscc>)' %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-DO-CACHE-CGSCC-ANALYSIS-RESULTS
; CHECK-DO-CACHE-CGSCC-ANALYSIS-RESULTS: Starting CGSCC pass manager
; CHECK-DO-CACHE-CGSCC-ANALYSIS-RESULTS: Running CGSCC pass: RequireAnalysisPass
; CHECK-DO-CACHE-CGSCC-ANALYSIS-RESULTS: Running CGSCC analysis: NoOpCGSCCAnalysis
; CHECK-DO-CACHE-CGSCC-ANALYSIS-RESULTS-NOT: Running CGSCC analysis: NoOpCGSCCAnalysis
; CHECK-DO-CACHE-CGSCC-ANALYSIS-RESULTS: Running analysis: NoOpCGSCCAnalysis
; CHECK-DO-CACHE-CGSCC-ANALYSIS-RESULTS-NOT: Running analysis: NoOpCGSCCAnalysis
; RUN: opt -disable-output -debug-pass-manager -debug-cgscc-pass-manager \
; RUN: -passes='cgscc(require<no-op-cgscc>,invalidate<no-op-cgscc>,require<no-op-cgscc>)' %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-DO-INVALIDATE-CGSCC-ANALYSIS-RESULTS
; CHECK-DO-INVALIDATE-CGSCC-ANALYSIS-RESULTS: Starting CGSCC pass manager
; CHECK-DO-INVALIDATE-CGSCC-ANALYSIS-RESULTS: Running CGSCC pass: RequireAnalysisPass
; CHECK-DO-INVALIDATE-CGSCC-ANALYSIS-RESULTS: Running CGSCC analysis: NoOpCGSCCAnalysis
; CHECK-DO-INVALIDATE-CGSCC-ANALYSIS-RESULTS: Invalidating CGSCC analysis: NoOpCGSCCAnalysis
; CHECK-DO-INVALIDATE-CGSCC-ANALYSIS-RESULTS: Running CGSCC analysis: NoOpCGSCCAnalysis
; CHECK-DO-INVALIDATE-CGSCC-ANALYSIS-RESULTS: Running analysis: NoOpCGSCCAnalysis
; CHECK-DO-INVALIDATE-CGSCC-ANALYSIS-RESULTS: Invalidating analysis: NoOpCGSCCAnalysis
; CHECK-DO-INVALIDATE-CGSCC-ANALYSIS-RESULTS: Running analysis: NoOpCGSCCAnalysis
; RUN: opt -disable-output -debug-pass-manager -debug-cgscc-pass-manager \
; RUN: -passes='function(require<no-op-function>,require<no-op-function>,require<no-op-function>)' %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-DO-CACHE-FUNCTION-ANALYSIS-RESULTS
; CHECK-DO-CACHE-FUNCTION-ANALYSIS-RESULTS: Starting function pass manager
; CHECK-DO-CACHE-FUNCTION-ANALYSIS-RESULTS: Running function pass: RequireAnalysisPass
; CHECK-DO-CACHE-FUNCTION-ANALYSIS-RESULTS: Running function analysis: NoOpFunctionAnalysis
; CHECK-DO-CACHE-FUNCTION-ANALYSIS-RESULTS-NOT: Running function analysis: NoOpFunctionAnalysis
; CHECK-DO-CACHE-FUNCTION-ANALYSIS-RESULTS: Running analysis: NoOpFunctionAnalysis
; CHECK-DO-CACHE-FUNCTION-ANALYSIS-RESULTS-NOT: Running analysis: NoOpFunctionAnalysis
; RUN: opt -disable-output -debug-pass-manager -debug-cgscc-pass-manager \
; RUN: -passes='function(require<no-op-function>,invalidate<no-op-function>,require<no-op-function>)' %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-DO-INVALIDATE-FUNCTION-ANALYSIS-RESULTS
; CHECK-DO-INVALIDATE-FUNCTION-ANALYSIS-RESULTS: Starting function pass manager
; CHECK-DO-INVALIDATE-FUNCTION-ANALYSIS-RESULTS: Running function pass: RequireAnalysisPass
; CHECK-DO-INVALIDATE-FUNCTION-ANALYSIS-RESULTS: Running function analysis: NoOpFunctionAnalysis
; CHECK-DO-INVALIDATE-FUNCTION-ANALYSIS-RESULTS: Invalidating function analysis: NoOpFunctionAnalysis
; CHECK-DO-INVALIDATE-FUNCTION-ANALYSIS-RESULTS: Running function analysis: NoOpFunctionAnalysis
; CHECK-DO-INVALIDATE-FUNCTION-ANALYSIS-RESULTS: Running analysis: NoOpFunctionAnalysis
; CHECK-DO-INVALIDATE-FUNCTION-ANALYSIS-RESULTS: Invalidating analysis: NoOpFunctionAnalysis
; CHECK-DO-INVALIDATE-FUNCTION-ANALYSIS-RESULTS: Running analysis: NoOpFunctionAnalysis
; RUN: opt -disable-output -disable-verify -debug-pass-manager -debug-cgscc-pass-manager \
; RUN: -passes='require<no-op-module>,module(require<no-op-module>,function(require<no-op-function>,invalidate<all>,require<no-op-function>),require<no-op-module>),require<no-op-module>' %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-INVALIDATE-ALL
; CHECK-INVALIDATE-ALL: Starting module pass manager run.
; CHECK-INVALIDATE-ALL: Running module pass: RequireAnalysisPass
; CHECK-INVALIDATE-ALL: Running module analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL: Running analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL: Starting module pass manager run.
; CHECK-INVALIDATE-ALL: Running module pass: RequireAnalysisPass
; CHECK-INVALIDATE-ALL-NOT: Running module analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL-NOT: Running analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL: Starting function pass manager run.
; CHECK-INVALIDATE-ALL: Running function pass: RequireAnalysisPass
; CHECK-INVALIDATE-ALL: Running function analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL: Running analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL: Running function pass: InvalidateAllAnalysesPass
; CHECK-INVALIDATE-ALL: Invalidating all non-preserved analyses for function
; CHECK-INVALIDATE-ALL: Invalidating function analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL: Invalidating all non-preserved analyses
; CHECK-INVALIDATE-ALL: Invalidating analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL: Running function pass: RequireAnalysisPass
; CHECK-INVALIDATE-ALL: Running function analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL: Running analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL: Finished function pass manager run.
; CHECK-INVALIDATE-ALL: Invalidating all non-preserved analyses for function
; CHECK-INVALIDATE-ALL-NOT: Running function analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL: Invalidating all non-preserved analyses for module
; CHECK-INVALIDATE-ALL: Invalidating module analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL: Invalidating all non-preserved analyses
; CHECK-INVALIDATE-ALL-NOT: Running analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL: Invalidating all non-preserved analyses
; CHECK-INVALIDATE-ALL: Invalidating analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL: Running module pass: RequireAnalysisPass
; CHECK-INVALIDATE-ALL: Running module analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL: Running analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL: Finished module pass manager run.
; CHECK-INVALIDATE-ALL: Invalidating all non-preserved analyses for module
; CHECK-INVALIDATE-ALL-NOT: Invalidating module analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL: Invalidating all non-preserved analyses
; CHECK-INVALIDATE-ALL-NOT: Invalidating analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL: Running module pass: RequireAnalysisPass
; CHECK-INVALIDATE-ALL-NOT: Running module analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL-NOT: Running analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL: Finished module pass manager run.
; RUN: opt -disable-output -disable-verify -debug-pass-manager -debug-cgscc-pass-manager \
@ -230,40 +230,40 @@
; RUN: | FileCheck %s --check-prefix=CHECK-INVALIDATE-ALL-CG
; CHECK-INVALIDATE-ALL-CG: Starting module pass manager run.
; CHECK-INVALIDATE-ALL-CG: Running module pass: RequireAnalysisPass
; CHECK-INVALIDATE-ALL-CG: Running module analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL-CG: Running analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL-CG: Starting module pass manager run.
; CHECK-INVALIDATE-ALL-CG: Running module pass: RequireAnalysisPass
; CHECK-INVALIDATE-ALL-CG-NOT: Running module analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL-CG-NOT: Running analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL-CG: Starting CGSCC pass manager run.
; CHECK-INVALIDATE-ALL-CG: Running CGSCC pass: RequireAnalysisPass
; CHECK-INVALIDATE-ALL-CG: Running CGSCC analysis: NoOpCGSCCAnalysis
; CHECK-INVALIDATE-ALL-CG: Running analysis: NoOpCGSCCAnalysis
; CHECK-INVALIDATE-ALL-CG: Starting function pass manager run.
; CHECK-INVALIDATE-ALL-CG: Running function pass: RequireAnalysisPass
; CHECK-INVALIDATE-ALL-CG: Running function analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL-CG: Running analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL-CG: Running function pass: InvalidateAllAnalysesPass
; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses for function
; CHECK-INVALIDATE-ALL-CG: Invalidating function analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses
; CHECK-INVALIDATE-ALL-CG: Invalidating analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL-CG: Running function pass: RequireAnalysisPass
; CHECK-INVALIDATE-ALL-CG: Running function analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL-CG: Running analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL-CG: Finished function pass manager run.
; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses for function
; CHECK-INVALIDATE-ALL-CG-NOT: Running function analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses for SCC
; CHECK-INVALIDATE-ALL-CG: Invalidating CGSCC analysis: NoOpCGSCCAnalysis
; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses
; CHECK-INVALIDATE-ALL-CG-NOT: Running analysis: NoOpFunctionAnalysis
; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses
; CHECK-INVALIDATE-ALL-CG: Invalidating analysis: NoOpCGSCCAnalysis
; CHECK-INVALIDATE-ALL-CG: Running CGSCC pass: RequireAnalysisPass
; CHECK-INVALIDATE-ALL-CG: Running CGSCC analysis: NoOpCGSCCAnalysis
; CHECK-INVALIDATE-ALL-CG: Running analysis: NoOpCGSCCAnalysis
; CHECK-INVALIDATE-ALL-CG: Finished CGSCC pass manager run.
; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses for SCC
; CHECK-INVALIDATE-ALL-CG-NOT: Invalidating CGSCC analysis: NoOpCGSCCAnalysis
; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses for module
; CHECK-INVALIDATE-ALL-CG: Invalidating module analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses
; CHECK-INVALIDATE-ALL-CG-NOT: Invalidating analysis: NoOpCGSCCAnalysis
; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses
; CHECK-INVALIDATE-ALL-CG: Invalidating analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL-CG: Running module pass: RequireAnalysisPass
; CHECK-INVALIDATE-ALL-CG: Running module analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL-CG: Running analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL-CG: Finished module pass manager run.
; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses for module
; CHECK-INVALIDATE-ALL-CG-NOT: Invalidating module analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses
; CHECK-INVALIDATE-ALL-CG-NOT: Invalidating analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL-CG: Running module pass: RequireAnalysisPass
; CHECK-INVALIDATE-ALL-CG-NOT: Running module analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL-CG-NOT: Running analysis: NoOpModuleAnalysis
; CHECK-INVALIDATE-ALL-CG: Finished module pass manager run.
define void @foo() {

View File

@ -17,12 +17,10 @@
#define LLVM_TOOLS_OPT_PASSES_H
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Analysis/CGSCCPassManager.h"
namespace llvm {
class CGSCCAnalysisManager;
class FunctionAnalysisManager;
class ModuleAnalysisManager;
class ModulePassManager;
/// \brief Registers all available module analysis passes.
///