X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FPassSupport.h;h=81b3ce153c9104db1dc6eac3ba1470a9e5481026;hb=b09c146b116359616f6cbd4c8b3328607e00ff42;hp=270b9f6108af11834cf62fc4273f1fb3bf1e0727;hpb=c37fca1492a26e0eb4eb1e77833a1489fa73ff62;p=oota-llvm.git diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h index 270b9f6108a..81b3ce153c9 100644 --- a/include/llvm/PassSupport.h +++ b/include/llvm/PassSupport.h @@ -1,5 +1,12 @@ //===- llvm/PassSupport.h - Pass Support code -------------------*- C++ -*-===// // +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// // This file defines stuff that is used to define and "use" Passes. This file // is automatically #included by Pass.h, so: // @@ -14,337 +21,321 @@ #ifndef LLVM_PASS_SUPPORT_H #define LLVM_PASS_SUPPORT_H -// No need to include Pass.h, we are being included by it! +#include "Pass.h" +#include "llvm/InitializePasses.h" +#include "llvm/PassRegistry.h" +#include "llvm/Support/Atomic.h" +#include "llvm/Support/Valgrind.h" +#include -class TargetData; -class TargetMachine; +namespace llvm { //===--------------------------------------------------------------------------- -// 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. -// +/// 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 - unsigned char PassType; // Set of enums values below... +public: + typedef Pass* (*NormalCtor_t)(); - Pass *(*NormalCtor)(); // No argument ctor - Pass *(*DataCtor)(const TargetData&);// Ctor taking TargetData object... +private: + const char *const PassName; // Nice name for Pass + const char *const PassArgument; // Command Line argument to run this pass + const void *PassID; + const bool IsCFGOnlyPass; // Pass only looks at the CFG. + const bool IsAnalysis; // True if an analysis pass. + const bool IsAnalysisGroup; // True if an analysis group. + std::vector ItfImpl;// Interfaces implemented by this pass -public: - // PassType - Define symbolic constants that can be used to test to see if - // this pass should be listed by analyze or opt. Passes can use none, one or - // many of these flags or'd together. It is not legal to combine the - // AnalysisGroup flag with others. - // - enum { - Analysis = 1, Optimization = 2, LLC = 4, AnalysisGroup = 8 - }; - - // 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, - unsigned pt, Pass *(*normal)(), Pass *(*data)(const TargetData &)) - : PassName(name), PassArgument(arg), TypeInfo(ti), PassType(pt), - NormalCtor(normal), DataCtor(data) { - } + NormalCtor_t NormalCtor; - // getPassName - Return the friendly name for the pass, never returns null +public: + /// PassInfo ctor - Do not call this directly, this should only be invoked + /// through RegisterPass. + PassInfo(const char *name, const char *arg, const void *pi, + NormalCtor_t normal, bool isCFGOnly, bool is_analysis) + : PassName(name), PassArgument(arg), PassID(pi), + IsCFGOnlyPass(isCFGOnly), + IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal) { } + /// PassInfo ctor - Do not call this directly, this should only be invoked + /// through RegisterPass. This version is for use by analysis groups; it + /// does not auto-register the pass. + PassInfo(const char *name, const void *pi) + : PassName(name), PassArgument(""), PassID(pi), + IsCFGOnlyPass(false), + IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(0) { } + + /// getPassName - Return the friendly name for the pass, never returns null + /// const char *getPassName() const { return PassName; } - void setPassName(const char *Name) { PassName = Name; } - // 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. - // + /// 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; } + /// getTypeInfo - Return the id object for the pass... + /// TODO : Rename + const void *getTypeInfo() const { return PassID; } - // getPassType - Return the PassType of a pass. Note that this can be several - // different types or'd together. This is _strictly_ for use by opt, analyze - // and llc for deciding which passes to use as command line options. - // - unsigned getPassType() const { return PassType; } - - // 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. + /// Return true if this PassID implements the specified ID pointer. + bool isPassID(const void *IDPtr) const { + return PassID == IDPtr; + } + + /// isAnalysisGroup - Return true if this is an analysis group, not a normal + /// pass. + /// + bool isAnalysisGroup() const { return IsAnalysisGroup; } + bool isAnalysis() const { return IsAnalysis; } + + /// isCFGOnlyPass - return true if this pass only looks at the CFG for the + /// function. + bool isCFGOnlyPass() const { return IsCFGOnlyPass; } - Pass *(*getNormalCtor() const)() { + /// 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. + /// + NormalCtor_t getNormalCtor() const { return NormalCtor; } - void setNormalCtor(Pass *(*Ctor)()) { + void setNormalCtor(NormalCtor_t Ctor) { NormalCtor = Ctor; } - // createPass() - Use this - Pass *createPass() const { - assert((PassType != AnalysisGroup || NormalCtor) && - "No default implementation found for analysis group!"); - assert(NormalCtor && - "Cannot call createPass on PassInfo without default ctor!"); - return NormalCtor(); - } + /// createPass() - Use this method to create an instance of this pass. + Pass *createPass() const; - // 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; + /// addInterfaceImplemented - This method is called when this pass is + /// registered as a member of an analysis group with the RegisterAnalysisGroup + /// template. + /// + void addInterfaceImplemented(const PassInfo *ItfPI) { + ItfImpl.push_back(ItfPI); } -}; - -//===--------------------------------------------------------------------------- -// 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() : PIObj(0) {} - ~RegisterPassBase() { // Intentionally non-virtual... - if (PIObj) unregisterPass(PIObj); + /// getInterfacesImplemented - Return a list of all of the analysis group + /// interfaces implemented by this pass. + /// + const std::vector &getInterfacesImplemented() const { + return ItfImpl; } -protected: - PassInfo *PIObj; // The PassInfo object for this pass - void registerPass(PassInfo *); - void unregisterPass(PassInfo *); - - // setPreservesCFG - Notice that this pass only depends on the CFG, so - // transformations that do not modify the CFG do not invalidate this pass. - // - void setPreservesCFG(); +private: + void operator=(const PassInfo &) LLVM_DELETED_FUNCTION; + PassInfo(const PassInfo &) LLVM_DELETED_FUNCTION; }; -template -Pass *callDefaultCtor() { return new PassName(); } - -template -struct RegisterPass : public RegisterPassBase { - - // Register Pass using default constructor... - RegisterPass(const char *PassArg, const char *Name, unsigned PassTy = 0) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), PassTy, - callDefaultCtor, 0)); - } - - // Register Pass using default constructor explicitly... - RegisterPass(const char *PassArg, const char *Name, unsigned PassTy, - Pass *(*ctor)()) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), PassTy, ctor,0)); +#define CALL_ONCE_INITIALIZATION(function) \ + static volatile sys::cas_flag initialized = 0; \ + sys::cas_flag old_val = sys::CompareAndSwap(&initialized, 1, 0); \ + if (old_val == 0) { \ + function(Registry); \ + sys::MemoryFence(); \ + TsanIgnoreWritesBegin(); \ + TsanHappensBefore(&initialized); \ + initialized = 2; \ + TsanIgnoreWritesEnd(); \ + } else { \ + sys::cas_flag tmp = initialized; \ + sys::MemoryFence(); \ + while (tmp != 2) { \ + tmp = initialized; \ + sys::MemoryFence(); \ + } \ + } \ + TsanHappensAfter(&initialized); + +#define INITIALIZE_PASS(passName, arg, name, cfg, analysis) \ + static void* initialize##passName##PassOnce(PassRegistry &Registry) { \ + PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \ + PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \ + Registry.registerPass(*PI, true); \ + return PI; \ + } \ + void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ + CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \ } - // Register Pass using TargetData constructor... - RegisterPass(const char *PassArg, const char *Name, unsigned PassTy, - Pass *(*datactor)(const TargetData &)) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), PassTy, - 0, datactor)); +#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis) \ + static void* initialize##passName##PassOnce(PassRegistry &Registry) { + +#define INITIALIZE_PASS_DEPENDENCY(depName) \ + initialize##depName##Pass(Registry); +#define INITIALIZE_AG_DEPENDENCY(depName) \ + initialize##depName##AnalysisGroup(Registry); + +#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis) \ + PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \ + PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \ + Registry.registerPass(*PI, true); \ + return PI; \ + } \ + void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ + CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \ } - // Generic constructor version that has an unknown ctor type... - template - RegisterPass(const char *PassArg, const char *Name, unsigned PassTy, - CtorType *Fn) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), PassTy, 0, 0)); - } -}; - -// RegisterOpt - Register something that is to show up in Opt, this is just a -// shortcut for specifying RegisterPass... -// template -struct RegisterOpt : public RegisterPassBase { - RegisterOpt(const char *PassArg, const char *Name) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), - PassInfo::Optimization, - callDefaultCtor, 0)); - } - - // Register Pass using default constructor explicitly... - RegisterOpt(const char *PassArg, const char *Name, Pass *(*ctor)()) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), - PassInfo::Optimization, ctor, 0)); - } +Pass *callDefaultCtor() { return new PassName(); } - // Register Pass using TargetData constructor... - RegisterOpt(const char *PassArg, const char *Name, - Pass *(*datactor)(const TargetData &)) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), - PassInfo::Optimization, 0, 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: +/// +/// static RegisterPass tmp("passopt", "My Name"); +/// +template +struct RegisterPass : public PassInfo { -// RegisterAnalysis - Register something that is to show up in Analysis, this is -// just a shortcut for specifying RegisterPass... Analyses take a special -// argument that, when set to true, tells the system that the analysis ONLY -// depends on the shape of the CFG, so if a transformation preserves the CFG -// that the analysis is not invalidated. -// -template -struct RegisterAnalysis : public RegisterPassBase { - RegisterAnalysis(const char *PassArg, const char *Name, - bool CFGOnly = false) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), - PassInfo::Analysis, - callDefaultCtor, 0)); - if (CFGOnly) - setPreservesCFG(); + // Register Pass using default constructor... + RegisterPass(const char *PassArg, const char *Name, bool CFGOnly = false, + bool is_analysis = false) + : PassInfo(Name, PassArg, &passName::ID, + PassInfo::NormalCtor_t(callDefaultCtor), + CFGOnly, is_analysis) { + PassRegistry::getPassRegistry()->registerPass(*this); } }; -// RegisterLLC - Register something that is to show up in LLC, this is just a -// shortcut for specifying RegisterPass... -// -template -struct RegisterLLC : public RegisterPassBase { - RegisterLLC(const char *PassArg, const char *Name) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), - PassInfo::LLC, - callDefaultCtor, 0)); - } - // Register Pass using default constructor explicitly... - RegisterLLC(const char *PassArg, const char *Name, Pass *(*ctor)()) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), - PassInfo::LLC, ctor, 0)); - } +/// RegisterAnalysisGroup - Register a Pass as a member of an analysis _group_. +/// Analysis groups are used to define an interface (which need not derive from +/// Pass) that is required by passes to do their job. Analysis Groups differ +/// from normal analyses because any available implementation of the group will +/// be used if it is available. +/// +/// If no analysis implementing the interface is available, a default +/// implementation is created and added. A pass registers itself as the default +/// implementation by specifying 'true' as the second template argument of this +/// class. +/// +/// In addition to registering itself as an analysis group member, a pass must +/// register itself normally as well. Passes may be members of multiple groups +/// and may still be "required" specifically by name. +/// +/// The actual interface may also be registered as well (by not specifying the +/// second template argument). The interface should be registered to associate +/// a nice name with the interface. +/// +class RegisterAGBase : public PassInfo { +public: + RegisterAGBase(const char *Name, + const void *InterfaceID, + const void *PassID = 0, + bool isDefault = false); +}; - // Register Pass using TargetData constructor... - RegisterLLC(const char *PassArg, const char *Name, - Pass *(*datactor)(const TargetData &)) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), - PassInfo::LLC, 0, datactor)); +template +struct RegisterAnalysisGroup : public RegisterAGBase { + explicit RegisterAnalysisGroup(PassInfo &RPB) + : RegisterAGBase(RPB.getPassName(), + &Interface::ID, RPB.getTypeInfo(), + Default) { } - // Register Pass using TargetMachine constructor... - RegisterLLC(const char *PassArg, const char *Name, - Pass *(*datactor)(TargetMachine &)) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), - PassInfo::LLC, 0, 0)); + explicit RegisterAnalysisGroup(const char *Name) + : RegisterAGBase(Name, &Interface::ID) { } }; - -// RegisterAnalysisGroup - Register a Pass as a member of an analysis _group_. -// Analysis groups are used to define an interface (which need not derive from -// Pass) that is required by passes to do their job. Analysis Groups differ -// from normal analyses because any available implementation of the group will -// be used if it is available. -// -// If no analysis implementing the interface is available, a default -// implementation is created and added. A pass registers itself as the default -// implementation by specifying 'true' as the third template argument of this -// class. -// -// In addition to registering itself as an analysis group member, a pass must -// register itself normally as well. Passes may be members of multiple groups -// and may still be "required" specifically by name. -// -// The actual interface may also be registered as well (by not specifying the -// second template argument). The interface should be registered to associate a -// nice name with the interface. -// -class RegisterAGBase : public RegisterPassBase { - PassInfo *InterfaceInfo; - const PassInfo *ImplementationInfo; - bool isDefaultImplementation; -protected: - RegisterAGBase(const std::type_info &Interface, - const std::type_info *Pass = 0, - bool isDefault = false); - void setGroupName(const char *Name); -public: - ~RegisterAGBase(); -}; - - -template -struct RegisterAnalysisGroup : public RegisterAGBase { - RegisterAnalysisGroup() : RegisterAGBase(typeid(Interface), - &typeid(DefaultImplementationPass), - Default) { +#define INITIALIZE_ANALYSIS_GROUP(agName, name, defaultPass) \ + static void* initialize##agName##AnalysisGroupOnce(PassRegistry &Registry) { \ + initialize##defaultPass##Pass(Registry); \ + PassInfo *AI = new PassInfo(name, & agName :: ID); \ + Registry.registerAnalysisGroup(& agName ::ID, 0, *AI, false, true); \ + return AI; \ + } \ + void llvm::initialize##agName##AnalysisGroup(PassRegistry &Registry) { \ + CALL_ONCE_INITIALIZATION(initialize##agName##AnalysisGroupOnce) \ } -}; -// Define a specialization of RegisterAnalysisGroup that is used to set the name -// for the analysis group. -// -template -struct RegisterAnalysisGroup : public RegisterAGBase { - RegisterAnalysisGroup(const char *Name) - : RegisterAGBase(typeid(Interface)) { - setGroupName(Name); + +#define INITIALIZE_AG_PASS(passName, agName, arg, name, cfg, analysis, def) \ + static void* initialize##passName##PassOnce(PassRegistry &Registry) { \ + if (!def) initialize##agName##AnalysisGroup(Registry); \ + PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \ + PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \ + Registry.registerPass(*PI, true); \ + \ + PassInfo *AI = new PassInfo(name, & agName :: ID); \ + Registry.registerAnalysisGroup(& agName ::ID, & passName ::ID, \ + *AI, def, true); \ + return AI; \ + } \ + void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ + CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \ } -}; +#define INITIALIZE_AG_PASS_BEGIN(passName, agName, arg, n, cfg, analysis, def) \ + static void* initialize##passName##PassOnce(PassRegistry &Registry) { \ + if (!def) initialize##agName##AnalysisGroup(Registry); + +#define INITIALIZE_AG_PASS_END(passName, agName, arg, n, cfg, analysis, def) \ + PassInfo *PI = new PassInfo(n, arg, & passName ::ID, \ + PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \ + Registry.registerPass(*PI, true); \ + \ + PassInfo *AI = new PassInfo(n, & agName :: ID); \ + Registry.registerAnalysisGroup(& agName ::ID, & passName ::ID, \ + *AI, def, true); \ + return AI; \ + } \ + void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ + CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \ + } //===--------------------------------------------------------------------------- -// 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. -// +/// 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 ctor - Add the current object to the list of + /// PassRegistrationListeners... PassRegistrationListener(); - // dtor - Remove object from list of listeners... + /// 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) {} + /// Callback functions - These functions are invoked whenever a pass is loaded + /// or removed from the current executable. + /// + virtual void passRegistered(const PassInfo *) {} - // enumeratePasses - Iterate over the registered passes, calling the - // passEnumerate callback on each PassInfo object. - // + /// 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) {} + /// passEnumerate - Callback function invoked when someone calls + /// enumeratePasses on this PassRegistrationListener object. + /// + virtual void passEnumerate(const PassInfo *) {} }; -//===--------------------------------------------------------------------------- -// IncludeFile class - This class is used as a hack to make sure that the -// implementation of a header file is included into a tool that uses the header. -// This is solely to overcome problems linking .a files and not getting the -// implementation of passes we need. -// -struct IncludeFile { - IncludeFile(void *); -}; +} // End llvm namespace + #endif