blob: 18a8cca56fc7b7869826535e09b2403b6f26863c [file] [log] [blame]
Owen Anderson660466e2010-07-20 19:23:55 +00001//===- 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"
Owen Anderson41540612010-07-20 21:22:24 +000016#include "llvm/Support/Compiler.h"
17#include "llvm/Support/ManagedStatic.h"
18
19static PassRegistry *PassRegistryObj = 0;
20PassRegistry *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
43namespace {
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.
50void cleanupPassRegistry(void*) {
51 if (PassRegistryObj) {
52 delete PassRegistryObj;
53 PassRegistryObj = 0;
54 }
55}
56ManagedCleanup<&cleanupPassRegistry> registryCleanup ATTRIBUTE_USED;
57
58}
Owen Anderson660466e2010-07-20 19:23:55 +000059
60const 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
66const 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
72void 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
80void 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
90void 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.
99void 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}