mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-26 20:57:15 +00:00
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225757 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cd7eb37ca4
commit
6b1894aeae
@ -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.
|
||||
///
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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.
|
||||
///
|
||||
|
Loading…
x
Reference in New Issue
Block a user