llvm-mirror/include/llvm/PassAnalysisSupport.h
Chris Lattner 64a9cec8a8 Analysis contructors now no longer take AnalysisID's as their argument,
because there is a one-one mapping between classes and analyses.

llvm-svn: 3106
2002-07-26 19:19:16 +00:00

158 lines
5.4 KiB
C++

//===- llvm/PassAnalysisSupport.h - Analysis Pass Support code ---*- C++ -*-==//
//
// This file defines stuff that is used to define and "use" Analysis Passes.
// This file is automatically #included by Pass.h, so:
//
// NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY
//
// Instead, #include Pass.h
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_PASS_ANALYSIS_SUPPORT_H
#define LLVM_PASS_ANALYSIS_SUPPORT_H
// No need to include Pass.h, we are being included by it!
// CreatePass - Helper template to invoke the constructor for the AnalysisID
// class. Note that this should be a template internal to AnalysisID, but
// GCC 2.95.3 crashes if we do that, doh.
//
template<class AnalysisType>
static Pass *CreatePass() { return new AnalysisType(); }
//===----------------------------------------------------------------------===//
// AnalysisID - This class is used to uniquely identify an analysis pass that
// is referenced by a transformation.
//
class AnalysisID {
static unsigned NextID; // Next ID # to deal out...
unsigned ID; // Unique ID for this analysis
Pass *(*Constructor)(); // Constructor to return the Analysis
AnalysisID(); // Disable default ctor
AnalysisID(unsigned id, Pass *(*Ct)()) : ID(id), Constructor(Ct) {}
public:
// create - the only way to define a new AnalysisID. This static method is
// supposed to be used to define the class static AnalysisID's that are
// provided by analysis passes. In the implementation (.cpp) file for the
// class, there should be a line that looks like this (using CallGraph as an
// example):
//
// AnalysisID CallGraph::ID(AnalysisID::create<CallGraph>());
//
template<class AnalysisType>
static AnalysisID create() {
return AnalysisID(NextID++, CreatePass<AnalysisType>);
}
// Special Copy Constructor - This is how analysis passes declare that they
// only depend on the CFG of the function they are working on, so they are not
// invalidated by other passes that do not modify the CFG. This should be
// used like this:
// AnalysisID DominatorSet::ID(AnalysisID::create<DominatorSet>(), true);
//
AnalysisID(const AnalysisID &AID, bool DependsOnlyOnCFG = false);
inline Pass *createPass() const { return Constructor(); }
inline bool operator==(const AnalysisID &A) const {
return A.ID == ID;
}
inline bool operator!=(const AnalysisID &A) const {
return A.ID != ID;
}
inline bool operator<(const AnalysisID &A) const {
return ID < A.ID;
}
};
//===----------------------------------------------------------------------===//
// AnalysisUsage - Represent the analysis usage information of a pass. This
// tracks analyses that the pass REQUIRES (must available when the pass runs),
// and analyses that the pass PRESERVES (the pass does not invalidate the
// results of these analyses). This information is provided by a pass to the
// Pass infrastructure through the getAnalysisUsage virtual function.
//
class AnalysisUsage {
// Sets of analyses required and preserved by a pass
std::vector<AnalysisID> Required, Preserved, Provided;
bool PreservesAll;
public:
AnalysisUsage() : PreservesAll(false) {}
// addRequires - Add the specified ID to the required set of the usage info
// for a pass.
//
AnalysisUsage &addRequired(AnalysisID ID) {
Required.push_back(ID);
return *this;
}
// addPreserves - Add the specified ID to the set of analyses preserved by
// this pass
//
AnalysisUsage &addPreserved(AnalysisID ID) {
Preserved.push_back(ID);
return *this;
}
void addProvided(AnalysisID ID) {
Provided.push_back(ID);
}
// PreservesAll - Set by analyses that do not transform their input at all
void setPreservesAll() { PreservesAll = true; }
bool preservesAll() const { return PreservesAll; }
// preservesCFG - This function should be called to by the pass, iff they do
// not:
//
// 1. Add or remove basic blocks from the function
// 2. Modify terminator instructions in any way.
//
// This function annotates the AnalysisUsage info object to say that analyses
// that only depend on the CFG are preserved by this pass.
//
void preservesCFG();
const std::vector<AnalysisID> &getRequiredSet() const { return Required; }
const std::vector<AnalysisID> &getPreservedSet() const { return Preserved; }
const std::vector<AnalysisID> &getProvidedSet() const { return Provided; }
};
//===----------------------------------------------------------------------===//
// AnalysisResolver - Simple interface implemented by PassManagers objects that
// is used to pull analysis information out of them.
//
struct AnalysisResolver {
virtual Pass *getAnalysisOrNullUp(AnalysisID ID) const = 0;
virtual Pass *getAnalysisOrNullDown(AnalysisID ID) const = 0;
Pass *getAnalysis(AnalysisID ID) {
Pass *Result = getAnalysisOrNullUp(ID);
assert(Result && "Pass has an incorrect analysis uses set!");
return Result;
}
// getAnalysisToUpdate - Return an analysis result or null if it doesn't exist
Pass *getAnalysisToUpdate(AnalysisID ID) {
Pass *Result = getAnalysisOrNullUp(ID);
return Result;
}
virtual unsigned getDepth() const = 0;
virtual void markPassUsed(AnalysisID P, Pass *User) = 0;
void startPass(Pass *P) {}
void endPass(Pass *P) {}
protected:
void setAnalysisResolver(Pass *P, AnalysisResolver *AR);
};
#endif