Break part of Pass.h out into PassAnalysisSupport.h

Add PassSupport.h which contains code for Pass registration

llvm-svn: 3010
This commit is contained in:
Chris Lattner 2002-07-23 17:59:55 +00:00
parent 301dd0e990
commit a073fe167c
3 changed files with 342 additions and 140 deletions

View File

@ -13,6 +13,10 @@
// global optimizations should derive from FunctionPass, because they do not add
// or delete functions, they operate on the internals of the function.
//
// Note that this file #includes PassSupport.h and PassAnalysisSupport.h (at the
// bottom), so the APIs exposed by these files are also automatically available
// to all users of this file.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_PASS_H
@ -26,6 +30,7 @@ class Function;
class Module;
class AnalysisUsage;
class AnalysisID;
class PassInfo;
template<class UnitType> class PassManagerT;
struct AnalysisResolver;
@ -38,8 +43,8 @@ class Pass {
friend class AnalysisResolver;
AnalysisResolver *Resolver; // AnalysisResolver this pass is owned by...
public:
inline Pass(AnalysisResolver *AR = 0) : Resolver(AR) {}
inline virtual ~Pass() {} // Destructor is virtual so we can be subclassed
Pass(AnalysisResolver *AR = 0) : Resolver(AR) {}
virtual ~Pass() {} // Destructor is virtual so we can be subclassed
// getPassName - Return a nice clean name for a pass. This should be
// overloaded by the pass, but if it is not, C++ RTTI will be consulted to get
@ -47,6 +52,10 @@ public:
//
virtual const char *getPassName() const;
// getPassInfo - Return the PassInfo data structure that corresponds to this
// pass...
const PassInfo *getPassInfo() const;
// run - Run this pass, returning true if a modification was made to the
// module argument. This should be implemented by all concrete subclasses.
//
@ -186,144 +195,10 @@ private:
virtual void addToPassManager(PassManagerT<BasicBlock> *PM,AnalysisUsage &AU);
};
// 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.
// Include support files that contain important APIs commonly used by Passes,
// but that we want to seperate out to make it easier to read the header files.
//
template<class AnalysisType>
static Pass *CreatePass(AnalysisID ID) { return new AnalysisType(ID); }
//===----------------------------------------------------------------------===//
// 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)(AnalysisID); // Constructor to return the Analysis
AnalysisID(); // Disable default ctor
AnalysisID(unsigned id, Pass *(*Ct)(AnalysisID)) : 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(*this); }
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);
};
#include "llvm/PassSupport.h"
#include "llvm/PassAnalysisSupport.h"
#endif

View File

@ -0,0 +1,157 @@
//===- 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(AnalysisID ID) { return new AnalysisType(ID); }
//===----------------------------------------------------------------------===//
// 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)(AnalysisID); // Constructor to return the Analysis
AnalysisID(); // Disable default ctor
AnalysisID(unsigned id, Pass *(*Ct)(AnalysisID)) : 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(*this); }
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

View File

@ -0,0 +1,170 @@
//===- llvm/PassSupport.h - Pass Support code -------------------*- C++ -*-===//
//
// This file defines stuff that is used to define and "use" Passes. This file
// is automatically #included by Pass.h, so:
//
// NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY
//
// Instead, #include Pass.h.
//
// This file defines Pass registration code and classes used for it.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_PASS_SUPPORT_H
#define LLVM_PASS_SUPPORT_H
// No need to include Pass.h, we are being included by it!
#include <typeinfo>
class TargetData;
//===---------------------------------------------------------------------------
// PassInfo class - An instance of this class exists for every pass known by the
// system, and can be obtained from a live Pass by calling its getPassInfo()
// method. These objects are set up by the RegisterPass<> template, defined
// below.
//
class PassInfo {
const char *PassName; // Nice name for Pass
const char *PassArgument; // Command Line argument to run this pass
const std::type_info &TypeInfo; // type_info object for this Pass class
Pass *(*NormalCtor)(); // No argument ctor
Pass *(*DataCtor)(const TargetData&);// Ctor taking TargetData object...
public:
// PassInfo ctor - Do not call this directly, this should only be invoked
// through RegisterPass.
PassInfo(const char *name, const char *arg, const std::type_info &ti,
Pass *(*normal)(), Pass *(*data)(const TargetData &))
: PassName(name), PassArgument(arg), TypeInfo(ti), NormalCtor(normal),
DataCtor(data) {
}
// getPassName - Return the friendly name for the pass, never returns null
const char *getPassName() const { return PassName; }
// getPassArgument - Return the command line option that may be passed to
// 'opt' that will cause this pass to be run. This will return null if there
// is no argument.
//
const char *getPassArgument() const { return PassArgument; }
// getTypeInfo - Return the type_info object for the pass...
const std::type_info &getTypeInfo() const { return TypeInfo; }
// getNormalCtor - Return a pointer to a function, that when called, creates
// an instance of the pass and returns it. This pointer may be null if there
// is no default constructor for the pass.
Pass *(*getNormalCtor() const)() {
return NormalCtor;
}
// getDataCtor - Return a pointer to a function that creates an instance of
// the pass and returns it. This returns a constructor for a version of the
// pass that takes a TArgetData object as a parameter.
//
Pass *(*getDataCtor() const)(const TargetData &) {
return DataCtor;
}
};
//===---------------------------------------------------------------------------
// RegisterPass<t> template - This template class is used to notify the system
// that a Pass is available for use, and registers it into the internal database
// maintained by the PassManager. Unless this template is used, opt, for
// example will not be able to see the pass and attempts to create the pass will
// fail. This template is used in the follow manner (at global scope, in your
// .cpp file):
//
// static RegisterPass<YourPassClassName> tmp("passopt", "My Pass Name");
//
// This statement will cause your pass to be created by calling the default
// constructor exposed by the pass. If you have a different constructor that
// must be called, create a global constructor function (which takes the
// arguments you need and returns a Pass*) and register your pass like this:
//
// Pass *createMyPass(foo &opt) { return new MyPass(opt); }
// static RegisterPass<PassClassName> tmp("passopt", "My Name", createMyPass);
//
struct RegisterPassBase {
// getPassInfo - Get the pass info for the registered class...
const PassInfo *getPassInfo() const { return PIObj; }
~RegisterPassBase(); // Intentionally non-virtual...
protected:
PassInfo *PIObj; // The PassInfo object for this pass
void registerPass(PassInfo *);
};
template<typename PassName>
Pass *callDefaultCtor() { return new PassName(); }
template<typename PassName>
struct RegisterPass : public RegisterPassBase {
// Register Pass using default constructor...
RegisterPass(const char *PassArg, const char *Name) {
registerPass(new PassInfo(Name, PassArg, typeid(PassName),
callDefaultCtor<PassName>, 0));
}
// Register Pass using default constructor explicitly...
RegisterPass(const char *PassArg, const char *Name,
Pass *(*ctor)()) {
registerPass(new PassInfo(Name, PassArg, typeid(PassName), ctor, 0));
}
// Register Pass using TargetData constructor...
RegisterPass(const char *PassArg, const char *Name,
Pass *(*datactor)(const TargetData &)) {
registerPass(new PassInfo(Name, PassArg, typeid(PassName), 0, datactor));
}
// Generic constructor version that has an unknown ctor type...
template<typename CtorType>
RegisterPass(const char *PassArg, const char *Name, CtorType *Fn) {
registerPass(new PassInfo(Name, PassArg, typeid(PassName), 0, 0));
}
};
//===---------------------------------------------------------------------------
// PassRegistrationListener class - This class is meant to be derived from by
// clients that are interested in which passes get registered and unregistered
// at runtime (which can be because of the RegisterPass constructors being run
// as the program starts up, or may be because a shared object just got loaded).
// Deriving from the PassRegistationListener class automatically registers your
// object to receive callbacks indicating when passes are loaded and removed.
//
struct PassRegistrationListener {
// PassRegistrationListener ctor - Add the current object to the list of
// PassRegistrationListeners...
PassRegistrationListener();
// dtor - Remove object from list of listeners...
virtual ~PassRegistrationListener();
// Callback functions - These functions are invoked whenever a pass is loaded
// or removed from the current executable.
//
virtual void passRegistered(const PassInfo *P) {}
virtual void passUnregistered(const PassInfo *P) {}
// enumeratePasses - Iterate over the registered passes, calling the
// passEnumerate callback on each PassInfo object.
//
void enumeratePasses();
// passEnumerate - Callback function invoked when someone calls
// enumeratePasses on this PassRegistrationListener object.
//
virtual void passEnumerate(const PassInfo *P) {}
};
#endif