Skip to content

Commit

Permalink
[PM] Fold all three analysis managers into a single AnalysisManager
Browse files Browse the repository at this point in the history
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
  • Loading branch information
chandlerc committed Jan 13, 2015
1 parent cd7eb37 commit 6b1894a
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 515 deletions.
94 changes: 7 additions & 87 deletions include/llvm/Analysis/CGSCCPassManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -67,92 +73,6 @@ class CGSCCPassManager {
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.
///
Expand Down
2 changes: 1 addition & 1 deletion include/llvm/Analysis/LazyCallGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
6 changes: 6 additions & 0 deletions include/llvm/IR/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@ class Module {
/// @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; }
Expand Down
Loading

0 comments on commit 6b1894a

Please sign in to comment.