Index: include/llvm/PassInfo.h =================================================================== --- /dev/null +++ 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 +#include + +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 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 &getInterfacesImplemented() const { + return ItfImpl; + } + +private: + void operator=(const PassInfo &) LLVM_DELETED_FUNCTION; + PassInfo(const PassInfo &) LLVM_DELETED_FUNCTION; +}; + +} + +#endif Index: include/llvm/PassRegistry.h =================================================================== --- include/llvm/PassRegistry.h +++ 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 namespace llvm { @@ -33,11 +39,26 @@ /// threads simultaneously, you will need to use a separate PassRegistry on /// each thread. class PassRegistry { - mutable void *pImpl; - void *getImpl() const; + mutable sys::SmartRWMutex Lock; + + /// PassInfoMap - Keep track of the PassInfo object for each registered pass. + typedef DenseMap MapType; + MapType PassInfoMap; + + typedef StringMap StringMapType; + StringMapType PassInfoStringMap; + + /// AnalysisGroupInfo - Keep track of information for each analysis group. + struct AnalysisGroupInfo { + SmallPtrSet Implementations; + }; + DenseMap AnalysisGroupInfoMap; + + std::vector> ToFree; + std::vector Listeners; public: - PassRegistry() : pImpl(nullptr) { } + PassRegistry() { } ~PassRegistry(); /// getPassRegistry - Access the global registry object, which is Index: include/llvm/PassSupport.h =================================================================== --- include/llvm/PassSupport.h +++ 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 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 &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; \ Index: lib/IR/Pass.cpp =================================================================== --- lib/IR/Pass.cpp +++ lib/IR/Pass.cpp @@ -199,14 +199,6 @@ 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 //===----------------------------------------------------------------------===// Index: lib/IR/PassRegistry.cpp =================================================================== --- lib/IR/PassRegistry.cpp +++ 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 @@ -36,65 +32,23 @@ return &*PassRegistryObj; } -static ManagedStatic > Lock; - -//===----------------------------------------------------------------------===// -// PassRegistryImpl -// - -namespace { -struct PassRegistryImpl { - /// PassInfoMap - Keep track of the PassInfo object for each registered pass. - typedef DenseMap MapType; - MapType PassInfoMap; - - typedef StringMap StringMapType; - StringMapType PassInfoStringMap; - - /// AnalysisGroupInfo - Keep track of information for each analysis group. - struct AnalysisGroupInfo { - SmallPtrSet Implementations; - }; - DenseMap AnalysisGroupInfoMap; - - std::vector> ToFree; - std::vector 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(pImpl); - delete Impl; - pImpl = nullptr; } const PassInfo *PassRegistry::getPassInfo(const void *TI) const { - sys::SmartScopedReader Guard(*Lock); - PassRegistryImpl *Impl = static_cast(getImpl()); - PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.find(TI); - return I != Impl->PassInfoMap.end() ? I->second : nullptr; + sys::SmartScopedReader 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 Guard(*Lock); - PassRegistryImpl *Impl = static_cast(getImpl()); - PassRegistryImpl::StringMapType::const_iterator - I = Impl->PassInfoStringMap.find(Arg); - return I != Impl->PassInfoStringMap.end() ? I->second : nullptr; + sys::SmartScopedReader Guard(Lock); + StringMapType::const_iterator I = PassInfoStringMap.find(Arg); + return I != PassInfoStringMap.end() ? I->second : nullptr; } //===----------------------------------------------------------------------===// @@ -102,39 +56,34 @@ // void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { - sys::SmartScopedWriter Guard(*Lock); - PassRegistryImpl *Impl = static_cast(getImpl()); + sys::SmartScopedWriter 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::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(&PI)); + if (ShouldFree) ToFree.push_back(std::unique_ptr(&PI)); } void PassRegistry::unregisterPass(const PassInfo &PI) { - sys::SmartScopedWriter Guard(*Lock); - PassRegistryImpl *Impl = static_cast(getImpl()); - PassRegistryImpl::MapType::iterator I = - Impl->PassInfoMap.find(PI.getTypeInfo()); - assert(I != Impl->PassInfoMap.end() && "Pass registered but not in map!"); + sys::SmartScopedWriter 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 Guard(*Lock); - PassRegistryImpl *Impl = static_cast(getImpl()); - for (PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.begin(), - E = Impl->PassInfoMap.end(); I != E; ++I) + sys::SmartScopedReader Guard(Lock); + for (auto I = PassInfoMap.begin(), E = PassInfoMap.end(); I != E; ++I) L->passEnumerate(I->second); } @@ -159,15 +108,13 @@ assert(ImplementationInfo && "Must register pass before adding to AnalysisGroup!"); - sys::SmartScopedWriter Guard(*Lock); + sys::SmartScopedWriter Guard(Lock); // Make sure we keep track of the fact that the implementation implements // the interface. ImplementationInfo->addInterfaceImplemented(InterfaceInfo); - PassRegistryImpl *Impl = static_cast(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 @@ } } - PassRegistryImpl *Impl = static_cast(getImpl()); if (ShouldFree) - Impl->ToFree.push_back(std::unique_ptr(&Registeree)); + ToFree.push_back(std::unique_ptr(&Registeree)); } void PassRegistry::addRegistrationListener(PassRegistrationListener *L) { - sys::SmartScopedWriter Guard(*Lock); - PassRegistryImpl *Impl = static_cast(getImpl()); - Impl->Listeners.push_back(L); + sys::SmartScopedWriter Guard(Lock); + Listeners.push_back(L); } void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) { - sys::SmartScopedWriter 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 Guard(Lock); - PassRegistryImpl *Impl = static_cast(getImpl()); - std::vector::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); }