From 4c76fc048bb9a3c5f760a50ea114f0605b9561d9 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 23 Jul 2002 17:59:55 +0000 Subject: [PATCH] Break part of Pass.h out into PassAnalysisSupport.h Add PassSupport.h which contains code for Pass registration git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3010 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Pass.h | 155 +++----------------------- include/llvm/PassAnalysisSupport.h | 157 ++++++++++++++++++++++++++ include/llvm/PassSupport.h | 170 +++++++++++++++++++++++++++++ 3 files changed, 342 insertions(+), 140 deletions(-) create mode 100644 include/llvm/PassAnalysisSupport.h create mode 100644 include/llvm/PassSupport.h diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index 097fc34e61f..2cf85d4dc47 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -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 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 *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. -// -template -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()); - // - template - static AnalysisID create() { - return AnalysisID(NextID++, CreatePass); - } - - // 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(), 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. +// 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. // -class AnalysisUsage { - // Sets of analyses required and preserved by a pass - std::vector 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 &getRequiredSet() const { return Required; } - const std::vector &getPreservedSet() const { return Preserved; } - const std::vector &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 diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h new file mode 100644 index 00000000000..5952a467363 --- /dev/null +++ b/include/llvm/PassAnalysisSupport.h @@ -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 +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()); + // + template + static AnalysisID create() { + return AnalysisID(NextID++, CreatePass); + } + + // 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(), 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 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 &getRequiredSet() const { return Required; } + const std::vector &getPreservedSet() const { return Preserved; } + const std::vector &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 diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h new file mode 100644 index 00000000000..5d571bb5b24 --- /dev/null +++ b/include/llvm/PassSupport.h @@ -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 +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 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 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 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 +Pass *callDefaultCtor() { return new PassName(); } + +template +struct RegisterPass : public RegisterPassBase { + + // Register Pass using default constructor... + RegisterPass(const char *PassArg, const char *Name) { + registerPass(new PassInfo(Name, PassArg, typeid(PassName), + callDefaultCtor, 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 + 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 -- 2.34.1