X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FPassSupport.h;h=8206e5f28e6a11ec524af3db9c15295704aa94df;hb=ef27d899fd6518b7e8da1eec9f76d7beb631b3d8;hp=e3c8ba75b59caf64cb0ff3ae8b34d81ae47ab042;hpb=631149287eaf7aac4caee7666ad86ca0428c274c;p=oota-llvm.git diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h index e3c8ba75b59..8206e5f28e6 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 was developed by the LLVM research group and 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: // @@ -16,104 +23,162 @@ // No need to include Pass.h, we are being included by it! -#include -class TargetData; +namespace llvm { + +class TargetMachine; //===--------------------------------------------------------------------------- -// 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... + std::vector ItfImpl;// Interfaces implemented by this pass Pass *(*NormalCtor)(); // No argument ctor - Pass *(*DataCtor)(const TargetData&);// Ctor taking TargetData object... + Pass *(*TargetCtor)(TargetMachine&); // Ctor taking TargetMachine object... 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. - // + /// 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 + Analysis = 1, Optimization = 2, AnalysisGroup = 4 }; - // 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 &)) + /// 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 char pt, Pass *(*normal)() = 0, + Pass *(*targetctor)(TargetMachine &) = 0) : PassName(name), PassArgument(arg), TypeInfo(ti), PassType(pt), - NormalCtor(normal), DataCtor(data) { + NormalCtor(normal), TargetCtor(targetctor) { } - // getPassName - Return the friendly name for the pass, never returns null + /// 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... + /// getTypeInfo - Return the type_info object for the pass... + /// const std::type_info &getTypeInfo() const { return TypeInfo; } - // 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. - // + /// 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. - + /// 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; } + void setNormalCtor(Pass *(*Ctor)()) { + NormalCtor = Ctor; + } + + /// createPass() - Use this method to create an instance of this pass. + 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(); + } + + /// getTargetCtor - 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 TargetMachine object as a parameter. + /// + Pass *(*getTargetCtor() const)(TargetMachine &) { + return TargetCtor; + } + + /// 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); + } - // 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; + /// getInterfacesImplemented - Return a list of all of the analysis group + /// interfaces implemented by this pass. + /// + const std::vector &getInterfacesImplemented() const { + return ItfImpl; } }; //===--------------------------------------------------------------------------- -// 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); -// +/// 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... + /// getPassInfo - Get the pass info for the registered class... + /// + const PassInfo *getPassInfo() const { return &PIObj; } + + RegisterPassBase(const char *Name, const char *Arg, const std::type_info &TI, + unsigned char PT, Pass *(*Normal)() = 0, + Pass *(*TargetCtor)(TargetMachine &) = 0) + : PIObj(Name, Arg, TI, PT, Normal, TargetCtor) { + registerPass(); + } + RegisterPassBase(const std::type_info &TI, unsigned char PT) + : PIObj("", "", TI, PT, 0, 0) { + // This ctor may only be used for analysis groups: it does not auto-register + // the pass. + assert(PT == PassInfo::AnalysisGroup && "Not an AnalysisGroup!"); + } + + ~RegisterPassBase() { // Intentionally non-virtual. + // Analysis groups are registered/unregistered by their dtor. + if (PIObj.getPassType() != PassInfo::AnalysisGroup) + unregisterPass(); + } protected: - PassInfo *PIObj; // The PassInfo object for this pass - void registerPass(PassInfo *); + PassInfo PIObj; // The PassInfo object for this pass + void registerPass(); + void unregisterPass(); + + /// setOnlyUsesCFG - Notice that this pass only depends on the CFG, so + /// transformations that do not modify the CFG do not invalidate this pass. + /// + void setOnlyUsesCFG(); }; template @@ -121,117 +186,198 @@ 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)); - } + RegisterPass(const char *PassArg, const char *Name, unsigned char PassTy = 0) + : RegisterPassBase(Name, PassArg, typeid(PassName), PassTy, + callDefaultCtor) {} // 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)); - } + RegisterPass(const char *PassArg, const char *Name, unsigned char PassTy, + Pass *(*ctor)()) + : RegisterPassBase(Name, PassArg, typeid(PassName), PassTy, ctor) {} - // 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)); - } + // Register Pass using TargetMachine constructor... + RegisterPass(const char *PassArg, const char *Name, unsigned char PassTy, + Pass *(*targetctor)(TargetMachine &)) + : RegisterPassBase(Name, PassArg, typeid(PassName), PassTy, + 0, targetctor) {} // 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), 0, 0)); - } + RegisterPass(const char *PassArg, const char *Name, unsigned char PassTy, + CtorType *Fn) + : RegisterPassBase(Name, PassArg, typeid(PassName), PassTy, 0) {} }; -// RegisterOpt - Register something that is to show up in Opt, this is just a -// shortcut for specifying RegisterPass... -// +/// 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)); + RegisterOpt(const char *PassArg, const char *Name, bool CFGOnly = false) + : RegisterPassBase(Name, PassArg, typeid(PassName), PassInfo::Optimization, + callDefaultCtor) { + if (CFGOnly) setOnlyUsesCFG(); } - // 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)); + /// Register Pass using default constructor explicitly... + /// + RegisterOpt(const char *PassArg, const char *Name, Pass *(*ctor)(), + bool CFGOnly = false) + : RegisterPassBase(Name, PassArg, typeid(PassName), + PassInfo::Optimization, ctor) { + if (CFGOnly) setOnlyUsesCFG(); + } + + /// Register FunctionPass using default constructor explicitly... + /// + RegisterOpt(const char *PassArg, const char *Name, FunctionPass *(*ctor)(), + bool CFGOnly = false) + : RegisterPassBase(Name, PassArg, typeid(PassName), PassInfo::Optimization, + static_cast(ctor)) { + if (CFGOnly) setOnlyUsesCFG(); + } + + /// Register Pass using TargetMachine constructor... + /// + RegisterOpt(const char *PassArg, const char *Name, + Pass *(*targetctor)(TargetMachine &), bool CFGOnly = false) + : RegisterPassBase(Name, PassArg, typeid(PassName), + PassInfo::Optimization, 0, targetctor) { + if (CFGOnly) setOnlyUsesCFG(); } - // Register Pass using TargetData constructor... + /// Register FunctionPass using TargetMachine constructor... + /// RegisterOpt(const char *PassArg, const char *Name, - Pass *(*datactor)(const TargetData &)) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), - PassInfo::Optimization, 0, datactor)); + FunctionPass *(*targetctor)(TargetMachine &), + bool CFGOnly = false) + : RegisterPassBase(Name, PassArg, typeid(PassName), PassInfo::Optimization, 0, + static_cast(targetctor)) { + if (CFGOnly) setOnlyUsesCFG(); } }; -// RegisterAnalysis - Register something that is to show up in Analysis, this is -// just a shortcut for specifying RegisterPass... -// +/// 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) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), - PassInfo::Analysis, - callDefaultCtor, 0)); + RegisterAnalysis(const char *PassArg, const char *Name, + bool CFGOnly = false) + : RegisterPassBase(Name, PassArg, typeid(PassName), PassInfo::Analysis, + callDefaultCtor) { + if (CFGOnly) setOnlyUsesCFG(); } +}; - // Register Pass using default constructor explicitly... - RegisterAnalysis(const char *PassArg, const char *Name, Pass *(*ctor)()) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), - PassInfo::Analys, 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 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) { } +}; - // Register Pass using TargetData constructor... - RegisterAnalysis(const char *PassArg, const char *Name, - Pass *(*datactor)(const TargetData &)) { - registerPass(new PassInfo(Name, PassArg, typeid(PassName), - PassInfo::Analysis, 0, datactor)); +/// 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); } }; + //===--------------------------------------------------------------------------- -// 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. - // + /// 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. - // + /// 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. - // + /// passEnumerate - Callback function invoked when someone calls + /// enumeratePasses on this PassRegistrationListener object. + /// virtual void passEnumerate(const PassInfo *P) {} }; + +//===--------------------------------------------------------------------------- +/// 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