diff options
Diffstat (limited to 'llvm/lib/IR/PassRegistry.cpp')
| -rw-r--r-- | llvm/lib/IR/PassRegistry.cpp | 128 | 
1 files changed, 128 insertions, 0 deletions
| diff --git a/llvm/lib/IR/PassRegistry.cpp b/llvm/lib/IR/PassRegistry.cpp new file mode 100644 index 0000000000000..92c188b118983 --- /dev/null +++ b/llvm/lib/IR/PassRegistry.cpp @@ -0,0 +1,128 @@ +//===- PassRegistry.cpp - Pass Registration Implementation ----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the PassRegistry, with which passes are registered on +// initialization, and supports the PassManager in dependency resolution. +// +//===----------------------------------------------------------------------===// + +#include "llvm/PassRegistry.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/PassInfo.h" +#include "llvm/PassSupport.h" +#include "llvm/Support/ManagedStatic.h" +#include <cassert> +#include <memory> +#include <utility> + +using namespace llvm; + +// FIXME: We use ManagedStatic to erase the pass registrar on shutdown. +// Unfortunately, passes are registered with static ctors, and having +// llvm_shutdown clear this map prevents successful resurrection after +// llvm_shutdown is run.  Ideally we should find a solution so that we don't +// leak the map, AND can still resurrect after shutdown. +static ManagedStatic<PassRegistry> PassRegistryObj; +PassRegistry *PassRegistry::getPassRegistry() { +  return &*PassRegistryObj; +} + +//===----------------------------------------------------------------------===// +// Accessors +// + +PassRegistry::~PassRegistry() = default; + +const PassInfo *PassRegistry::getPassInfo(const void *TI) const { +  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); +  StringMapType::const_iterator I = PassInfoStringMap.find(Arg); +  return I != PassInfoStringMap.end() ? I->second : nullptr; +} + +//===----------------------------------------------------------------------===// +// Pass Registration mechanism +// + +void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { +  sys::SmartScopedWriter<true> Guard(Lock); +  bool Inserted = +      PassInfoMap.insert(std::make_pair(PI.getTypeInfo(), &PI)).second; +  assert(Inserted && "Pass registered multiple times!"); +  (void)Inserted; +  PassInfoStringMap[PI.getPassArgument()] = &PI; + +  // Notify any listeners. +  for (auto *Listener : Listeners) +    Listener->passRegistered(&PI); + +  if (ShouldFree) +    ToFree.push_back(std::unique_ptr<const PassInfo>(&PI)); +} + +void PassRegistry::enumerateWith(PassRegistrationListener *L) { +  sys::SmartScopedReader<true> Guard(Lock); +  for (auto PassInfoPair : PassInfoMap) +    L->passEnumerate(PassInfoPair.second); +} + +/// Analysis Group Mechanisms. +void PassRegistry::registerAnalysisGroup(const void *InterfaceID, +                                         const void *PassID, +                                         PassInfo &Registeree, bool isDefault, +                                         bool ShouldFree) { +  PassInfo *InterfaceInfo = const_cast<PassInfo *>(getPassInfo(InterfaceID)); +  if (!InterfaceInfo) { +    // First reference to Interface, register it now. +    registerPass(Registeree); +    InterfaceInfo = &Registeree; +  } +  assert(Registeree.isAnalysisGroup() && +         "Trying to join an analysis group that is a normal pass!"); + +  if (PassID) { +    PassInfo *ImplementationInfo = const_cast<PassInfo *>(getPassInfo(PassID)); +    assert(ImplementationInfo && +           "Must register pass before adding to AnalysisGroup!"); + +    sys::SmartScopedWriter<true> Guard(Lock); + +    // Make sure we keep track of the fact that the implementation implements +    // the interface. +    ImplementationInfo->addInterfaceImplemented(InterfaceInfo); + +    if (isDefault) { +      assert(InterfaceInfo->getNormalCtor() == nullptr && +             "Default implementation for analysis group already specified!"); +      assert( +          ImplementationInfo->getNormalCtor() && +          "Cannot specify pass as default if it does not have a default ctor"); +      InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor()); +    } +  } + +  if (ShouldFree) +    ToFree.push_back(std::unique_ptr<const PassInfo>(&Registeree)); +} + +void PassRegistry::addRegistrationListener(PassRegistrationListener *L) { +  sys::SmartScopedWriter<true> Guard(Lock); +  Listeners.push_back(L); +} + +void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) { +  sys::SmartScopedWriter<true> Guard(Lock); + +  auto I = llvm::find(Listeners, L); +  Listeners.erase(I); +} | 
