diff options
-rw-r--r-- | include/llvm/PassInfo.h | 147 | ||||
-rw-r--r-- | include/llvm/PassRegistry.h | 27 | ||||
-rw-r--r-- | include/llvm/PassSupport.h | 115 | ||||
-rw-r--r-- | lib/IR/Pass.cpp | 8 | ||||
-rw-r--r-- | lib/IR/PassRegistry.cpp | 117 |
5 files changed, 198 insertions, 216 deletions
diff --git a/include/llvm/PassInfo.h b/include/llvm/PassInfo.h new file mode 100644 index 0000000000..d53daf1cf7 --- /dev/null +++ b/include/llvm/PassInfo.h @@ -0,0 +1,147 @@ +//===- llvm/PassInfo.h - Pass Info class ------------------------*- 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 and implements the PassInfo class. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_PASSINFO_H +#define LLVM_PASSINFO_H + +#include <cassert> +#include <vector> + +namespace llvm { + +class Pass; +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. +/// +class PassInfo { +public: + typedef Pass* (*NormalCtor_t)(); + typedef Pass *(*TargetMachineCtor_t)(TargetMachine *); + +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<const PassInfo*> ItfImpl;// Interfaces implemented by this pass + + NormalCtor_t NormalCtor; + TargetMachineCtor_t TargetMachineCtor; + +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, + TargetMachineCtor_t machine = nullptr) + : PassName(name), PassArgument(arg), PassID(pi), + IsCFGOnlyPass(isCFGOnly), + IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal), + TargetMachineCtor(machine) {} + /// 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(nullptr), + TargetMachineCtor(nullptr) {} + + /// 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 id object for the pass... + /// TODO : Rename + const void *getTypeInfo() const { return PassID; } + + /// 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; } + + /// 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(NormalCtor_t Ctor) { + NormalCtor = Ctor; + } + + /// getTargetMachineCtor - Return a pointer to a function, that when called + /// with a TargetMachine, creates an instance of the pass and returns it. + /// This pointer may be null if there is no constructor with a TargetMachine + /// for the pass. + /// + TargetMachineCtor_t getTargetMachineCtor() const { return TargetMachineCtor; } + void setTargetMachineCtor(TargetMachineCtor_t Ctor) { + TargetMachineCtor = Ctor; + } + + /// createPass() - Use this method to create an instance of this pass. + Pass *createPass() const { + assert((!isAnalysisGroup() || NormalCtor) && + "No default implementation found for analysis group!"); + assert(NormalCtor && + "Cannot call createPass on PassInfo without default ctor!"); + return NormalCtor(); + } + + /// 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); + } + + /// getInterfacesImplemented - Return a list of all of the analysis group + /// interfaces implemented by this pass. + /// + const std::vector<const PassInfo*> &getInterfacesImplemented() const { + return ItfImpl; + } + +private: + void operator=(const PassInfo &) LLVM_DELETED_FUNCTION; + PassInfo(const PassInfo &) LLVM_DELETED_FUNCTION; +}; + +} + +#endif diff --git a/include/llvm/PassRegistry.h b/include/llvm/PassRegistry.h index 7f2a01426e..1558c51bde 100644 --- a/include/llvm/PassRegistry.h +++ b/include/llvm/PassRegistry.h @@ -18,8 +18,14 @@ #define LLVM_PASSREGISTRY_H #include "llvm-c/Core.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/PassInfo.h" #include "llvm/Support/CBindingWrapping.h" +#include "llvm/Support/RWMutex.h" +#include <vector> namespace llvm { @@ -33,11 +39,26 @@ struct PassRegistrationListener; /// threads simultaneously, you will need to use a separate PassRegistry on /// each thread. class PassRegistry { - mutable void *pImpl; - void *getImpl() const; + mutable sys::SmartRWMutex<true> Lock; + + /// PassInfoMap - Keep track of the PassInfo object for each registered pass. + typedef DenseMap<const void*, const PassInfo*> MapType; + MapType PassInfoMap; + + typedef StringMap<const PassInfo*> StringMapType; + StringMapType PassInfoStringMap; + + /// AnalysisGroupInfo - Keep track of information for each analysis group. + struct AnalysisGroupInfo { + SmallPtrSet<const PassInfo *, 8> Implementations; + }; + DenseMap<const PassInfo*, AnalysisGroupInfo> AnalysisGroupInfoMap; + + std::vector<std::unique_ptr<const PassInfo>> ToFree; + std::vector<PassRegistrationListener*> Listeners; public: - PassRegistry() : pImpl(nullptr) { } + PassRegistry() { } ~PassRegistry(); /// getPassRegistry - Access the global registry object, which is diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h index b8efbb2835..a4ef09d679 100644 --- a/include/llvm/PassSupport.h +++ b/include/llvm/PassSupport.h @@ -23,6 +23,7 @@ #include "Pass.h" #include "llvm/InitializePasses.h" +#include "llvm/PassInfo.h" #include "llvm/PassRegistry.h" #include "llvm/Support/Atomic.h" #include "llvm/Support/Valgrind.h" @@ -31,120 +32,6 @@ 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. -/// -class PassInfo { -public: - typedef Pass* (*NormalCtor_t)(); - typedef Pass *(*TargetMachineCtor_t)(TargetMachine *); - -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<const PassInfo*> ItfImpl;// Interfaces implemented by this pass - - NormalCtor_t NormalCtor; - TargetMachineCtor_t TargetMachineCtor; - -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, - TargetMachineCtor_t machine = nullptr) - : PassName(name), PassArgument(arg), PassID(pi), - IsCFGOnlyPass(isCFGOnly), - IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal), - TargetMachineCtor(machine) {} - /// 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(nullptr), - TargetMachineCtor(nullptr) {} - - /// 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 id object for the pass... - /// TODO : Rename - const void *getTypeInfo() const { return PassID; } - - /// 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; } - - /// 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(NormalCtor_t Ctor) { - NormalCtor = Ctor; - } - - /// getTargetMachineCtor - Return a pointer to a function, that when called - /// with a TargetMachine, creates an instance of the pass and returns it. - /// This pointer may be null if there is no constructor with a TargetMachine - /// for the pass. - /// - TargetMachineCtor_t getTargetMachineCtor() const { return TargetMachineCtor; } - void setTargetMachineCtor(TargetMachineCtor_t Ctor) { - TargetMachineCtor = Ctor; - } - - /// createPass() - Use this method to create an instance of this pass. - Pass *createPass() const; - - /// 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); - } - - /// getInterfacesImplemented - Return a list of all of the analysis group - /// interfaces implemented by this pass. - /// - const std::vector<const PassInfo*> &getInterfacesImplemented() const { - return ItfImpl; - } - -private: - void operator=(const PassInfo &) LLVM_DELETED_FUNCTION; - PassInfo(const PassInfo &) LLVM_DELETED_FUNCTION; -}; #define CALL_ONCE_INITIALIZATION(function) \ static volatile sys::cas_flag initialized = 0; \ diff --git a/lib/IR/Pass.cpp b/lib/IR/Pass.cpp index 916d79b4cb..91d86ae40d 100644 --- a/lib/IR/Pass.cpp +++ b/lib/IR/Pass.cpp @@ -199,14 +199,6 @@ Pass *Pass::createPass(AnalysisID ID) { return PI->createPass(); } -Pass *PassInfo::createPass() const { - assert((!isAnalysisGroup() || NormalCtor) && - "No default implementation found for analysis group!"); - assert(NormalCtor && - "Cannot call createPass on PassInfo without default ctor!"); - return NormalCtor(); -} - //===----------------------------------------------------------------------===// // Analysis Group Implementation Code //===----------------------------------------------------------------------===// diff --git a/lib/IR/PassRegistry.cpp b/lib/IR/PassRegistry.cpp index e85fabffb8..91940a9c7f 100644 --- a/lib/IR/PassRegistry.cpp +++ b/lib/IR/PassRegistry.cpp @@ -13,14 +13,10 @@ //===----------------------------------------------------------------------===// #include "llvm/PassRegistry.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/StringMap.h" #include "llvm/IR/Function.h" #include "llvm/PassSupport.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Mutex.h" #include "llvm/Support/RWMutex.h" #include <vector> @@ -36,65 +32,23 @@ PassRegistry *PassRegistry::getPassRegistry() { return &*PassRegistryObj; } -static ManagedStatic<sys::SmartRWMutex<true> > Lock; - -//===----------------------------------------------------------------------===// -// PassRegistryImpl -// - -namespace { -struct PassRegistryImpl { - /// PassInfoMap - Keep track of the PassInfo object for each registered pass. - typedef DenseMap<const void*, const PassInfo*> MapType; - MapType PassInfoMap; - - typedef StringMap<const PassInfo*> StringMapType; - StringMapType PassInfoStringMap; - - /// AnalysisGroupInfo - Keep track of information for each analysis group. - struct AnalysisGroupInfo { - SmallPtrSet<const PassInfo *, 8> Implementations; - }; - DenseMap<const PassInfo*, AnalysisGroupInfo> AnalysisGroupInfoMap; - - std::vector<std::unique_ptr<const PassInfo>> ToFree; - std::vector<PassRegistrationListener*> Listeners; -}; -} // end anonymous namespace - -void *PassRegistry::getImpl() const { - if (!pImpl) - pImpl = new PassRegistryImpl(); - return pImpl; -} - //===----------------------------------------------------------------------===// // Accessors // PassRegistry::~PassRegistry() { - // Don't acquire the mutex here. This is destroyed during static execution of - // static destructors, after llvm_shutdown() has been called, so all instances - // of all ManagedStatics (including the Mutex), will have been destroyed as - // well. - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(pImpl); - delete Impl; - pImpl = nullptr; } const PassInfo *PassRegistry::getPassInfo(const void *TI) const { - sys::SmartScopedReader<true> Guard(*Lock); - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); - PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.find(TI); - return I != Impl->PassInfoMap.end() ? I->second : nullptr; + sys::SmartScopedReader<true> Guard(Lock); + MapType::const_iterator I = PassInfoMap.find(TI); + return I != PassInfoMap.end() ? I->second : nullptr; } const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { - sys::SmartScopedReader<true> Guard(*Lock); - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); - PassRegistryImpl::StringMapType::const_iterator - I = Impl->PassInfoStringMap.find(Arg); - return I != Impl->PassInfoStringMap.end() ? I->second : nullptr; + sys::SmartScopedReader<true> Guard(Lock); + StringMapType::const_iterator I = PassInfoStringMap.find(Arg); + return I != PassInfoStringMap.end() ? I->second : nullptr; } //===----------------------------------------------------------------------===// @@ -102,39 +56,34 @@ const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { // void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { - sys::SmartScopedWriter<true> Guard(*Lock); - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); + sys::SmartScopedWriter<true> Guard(Lock); bool Inserted = - Impl->PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second; + PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second; assert(Inserted && "Pass registered multiple times!"); (void)Inserted; - Impl->PassInfoStringMap[PI.getPassArgument()] = &PI; + PassInfoStringMap[PI.getPassArgument()] = &PI; // Notify any listeners. for (std::vector<PassRegistrationListener*>::iterator - I = Impl->Listeners.begin(), E = Impl->Listeners.end(); I != E; ++I) + I = Listeners.begin(), E = Listeners.end(); I != E; ++I) (*I)->passRegistered(&PI); - if (ShouldFree) Impl->ToFree.push_back(std::unique_ptr<const PassInfo>(&PI)); + if (ShouldFree) ToFree.push_back(std::unique_ptr<const PassInfo>(&PI)); } void PassRegistry::unregisterPass(const PassInfo &PI) { - sys::SmartScopedWriter<true> Guard(*Lock); - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); - PassRegistryImpl::MapType::iterator I = - Impl->PassInfoMap.find(PI.getTypeInfo()); - assert(I != Impl->PassInfoMap.end() && "Pass registered but not in map!"); + sys::SmartScopedWriter<true> Guard(Lock); + MapType::iterator I = PassInfoMap.find(PI.getTypeInfo()); + assert(I != PassInfoMap.end() && "Pass registered but not in map!"); // Remove pass from the map. - Impl->PassInfoMap.erase(I); - Impl->PassInfoStringMap.erase(PI.getPassArgument()); + PassInfoMap.erase(I); + PassInfoStringMap.erase(PI.getPassArgument()); } void PassRegistry::enumerateWith(PassRegistrationListener *L) { - sys::SmartScopedReader<true> Guard(*Lock); - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); - for (PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.begin(), - E = Impl->PassInfoMap.end(); I != E; ++I) + sys::SmartScopedReader<true> Guard(Lock); + for (auto I = PassInfoMap.begin(), E = PassInfoMap.end(); I != E; ++I) L->passEnumerate(I->second); } @@ -159,15 +108,13 @@ void PassRegistry::registerAnalysisGroup(const void *InterfaceID, assert(ImplementationInfo && "Must register pass before adding to AnalysisGroup!"); - sys::SmartScopedWriter<true> Guard(*Lock); + sys::SmartScopedWriter<true> Guard(Lock); // Make sure we keep track of the fact that the implementation implements // the interface. ImplementationInfo->addInterfaceImplemented(InterfaceInfo); - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); - PassRegistryImpl::AnalysisGroupInfo &AGI = - Impl->AnalysisGroupInfoMap[InterfaceInfo]; + AnalysisGroupInfo &AGI = AnalysisGroupInfoMap[InterfaceInfo]; assert(AGI.Implementations.count(ImplementationInfo) == 0 && "Cannot add a pass to the same analysis group more than once!"); AGI.Implementations.insert(ImplementationInfo); @@ -182,30 +129,18 @@ void PassRegistry::registerAnalysisGroup(const void *InterfaceID, } } - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); if (ShouldFree) - Impl->ToFree.push_back(std::unique_ptr<const PassInfo>(&Registeree)); + ToFree.push_back(std::unique_ptr<const PassInfo>(&Registeree)); } void PassRegistry::addRegistrationListener(PassRegistrationListener *L) { - sys::SmartScopedWriter<true> Guard(*Lock); - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); - Impl->Listeners.push_back(L); + sys::SmartScopedWriter<true> Guard(Lock); + Listeners.push_back(L); } void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) { - sys::SmartScopedWriter<true> Guard(*Lock); - - // NOTE: This is necessary, because removeRegistrationListener() can be called - // as part of the llvm_shutdown sequence. Since we have no control over the - // order of that sequence, we need to gracefully handle the case where the - // PassRegistry is destructed before the object that triggers this call. - if (!pImpl) return; + sys::SmartScopedWriter<true> Guard(Lock); - PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); - std::vector<PassRegistrationListener*>::iterator I = - std::find(Impl->Listeners.begin(), Impl->Listeners.end(), L); - assert(I != Impl->Listeners.end() && - "PassRegistrationListener not registered!"); - Impl->Listeners.erase(I); + auto I = std::find(Listeners.begin(), Listeners.end(), L); + Listeners.erase(I); } |