Move more functionality from Pass.cpp to PassRegistry.cpp. This global will go away...
[oota-llvm.git] / lib / VMCore / PassRegistry.cpp
1 //===- PassRegistry.cpp - Pass Registration Implementation ----------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the PassRegistry, with which passes are registered on
11 // initialization, and supports the PassManager in dependency resolution.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/PassRegistry.h"
16 #include "llvm/Support/Compiler.h"
17 #include "llvm/Support/ManagedStatic.h"
18
19 static PassRegistry *PassRegistryObj = 0;
20 PassRegistry *PassRegistry::getPassRegistry() {
21   // Use double-checked locking to safely initialize the registrar when
22   // we're running in multithreaded mode.
23   PassRegistry* tmp = PassRegistryObj;
24   if (llvm_is_multithreaded()) {
25     sys::MemoryFence();
26     if (!tmp) {
27       llvm_acquire_global_lock();
28       tmp = PassRegistryObj;
29       if (!tmp) {
30         tmp = new PassRegistry();
31         sys::MemoryFence();
32         PassRegistryObj = tmp;
33       }
34       llvm_release_global_lock();
35     }
36   } else if (!tmp) {
37     PassRegistryObj = new PassRegistry();
38   }
39   
40   return PassRegistryObj;
41 }
42
43 namespace {
44
45 // FIXME: We use ManagedCleanup to erase the pass registrar on shutdown.
46 // Unfortunately, passes are registered with static ctors, and having
47 // llvm_shutdown clear this map prevents successful ressurection after 
48 // llvm_shutdown is run.  Ideally we should find a solution so that we don't
49 // leak the map, AND can still resurrect after shutdown.
50 void cleanupPassRegistry(void*) {
51   if (PassRegistryObj) {
52     delete PassRegistryObj;
53     PassRegistryObj = 0;
54   }
55 }
56 ManagedCleanup<&cleanupPassRegistry> registryCleanup ATTRIBUTE_USED;
57
58 }
59
60 const PassInfo *PassRegistry::getPassInfo(intptr_t TI) const {
61   sys::SmartScopedLock<true> Guard(Lock);
62   MapType::const_iterator I = PassInfoMap.find(TI);
63   return I != PassInfoMap.end() ? I->second : 0;
64 }
65
66 const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {
67   sys::SmartScopedLock<true> Guard(Lock);
68   StringMapType::const_iterator I = PassInfoStringMap.find(Arg);
69   return I != PassInfoStringMap.end() ? I->second : 0;
70 }
71
72 void PassRegistry::registerPass(const PassInfo &PI) {
73   sys::SmartScopedLock<true> Guard(Lock);
74   bool Inserted =
75     PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second;
76   assert(Inserted && "Pass registered multiple times!"); Inserted=Inserted;
77   PassInfoStringMap[PI.getPassArgument()] = &PI;
78 }
79
80 void PassRegistry::unregisterPass(const PassInfo &PI) {
81   sys::SmartScopedLock<true> Guard(Lock);
82   MapType::iterator I = PassInfoMap.find(PI.getTypeInfo());
83   assert(I != PassInfoMap.end() && "Pass registered but not in map!");
84   
85   // Remove pass from the map.
86   PassInfoMap.erase(I);
87   PassInfoStringMap.erase(PI.getPassArgument());
88 }
89
90 void PassRegistry::enumerateWith(PassRegistrationListener *L) {
91   sys::SmartScopedLock<true> Guard(Lock);
92   for (MapType::const_iterator I = PassInfoMap.begin(),
93        E = PassInfoMap.end(); I != E; ++I)
94     L->passEnumerate(I->second);
95 }
96
97
98 /// Analysis Group Mechanisms.
99 void PassRegistry::registerAnalysisGroup(PassInfo *InterfaceInfo,
100                                          const PassInfo *ImplementationInfo,
101                                          bool isDefault) {
102   sys::SmartScopedLock<true> Guard(Lock);
103   AnalysisGroupInfo &AGI = AnalysisGroupInfoMap[InterfaceInfo];
104   assert(AGI.Implementations.count(ImplementationInfo) == 0 &&
105          "Cannot add a pass to the same analysis group more than once!");
106   AGI.Implementations.insert(ImplementationInfo);
107   if (isDefault) {
108     assert(InterfaceInfo->getNormalCtor() == 0 &&
109            "Default implementation for analysis group already specified!");
110     assert(ImplementationInfo->getNormalCtor() &&
111          "Cannot specify pass as default if it does not have a default ctor");
112     InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor());
113   }
114 }