1ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson//===- PassRegistry.cpp - Pass Registration Implementation ----------------===// 2ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson// 3ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson// The LLVM Compiler Infrastructure 4ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson// 5ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson// This file is distributed under the University of Illinois Open Source 6ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson// License. See LICENSE.TXT for details. 7ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson// 8ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson//===----------------------------------------------------------------------===// 9ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson// 10ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson// This file implements the PassRegistry, with which passes are registered on 11ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson// initialization, and supports the PassManager in dependency resolution. 12ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson// 13ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson//===----------------------------------------------------------------------===// 14ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson 15ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson#include "llvm/PassRegistry.h" 160b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/PassSupport.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/Compiler.h" 19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/ManagedStatic.h" 2040488cf13973dc5364f017c1a403fe93e6c46d6fChad Rosier#include "llvm/Support/RWMutex.h" 216bcd3a02653c45b87094577517547b7eb9f76395Owen Anderson#include <vector> 22aac07eaeef0b29690f18061abc148a2608cd77deOwen Anderson 23539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Andersonusing namespace llvm; 24539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Anderson 25381f17ee7c07b5a80d7dcdeae3d62e497902ef85Owen Anderson// FIXME: We use ManagedStatic to erase the pass registrar on shutdown. 26aac07eaeef0b29690f18061abc148a2608cd77deOwen Anderson// Unfortunately, passes are registered with static ctors, and having 277a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner// llvm_shutdown clear this map prevents successful resurrection after 28aac07eaeef0b29690f18061abc148a2608cd77deOwen Anderson// llvm_shutdown is run. Ideally we should find a solution so that we don't 29aac07eaeef0b29690f18061abc148a2608cd77deOwen Anderson// leak the map, AND can still resurrect after shutdown. 30381f17ee7c07b5a80d7dcdeae3d62e497902ef85Owen Andersonstatic ManagedStatic<PassRegistry> PassRegistryObj; 31381f17ee7c07b5a80d7dcdeae3d62e497902ef85Owen AndersonPassRegistry *PassRegistry::getPassRegistry() { 32381f17ee7c07b5a80d7dcdeae3d62e497902ef85Owen Anderson return &*PassRegistryObj; 33aac07eaeef0b29690f18061abc148a2608cd77deOwen Anderson} 34ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson 356bcd3a02653c45b87094577517547b7eb9f76395Owen Anderson//===----------------------------------------------------------------------===// 366bcd3a02653c45b87094577517547b7eb9f76395Owen Anderson// Accessors 376bcd3a02653c45b87094577517547b7eb9f76395Owen Anderson// 386bcd3a02653c45b87094577517547b7eb9f76395Owen Anderson 39381f17ee7c07b5a80d7dcdeae3d62e497902ef85Owen AndersonPassRegistry::~PassRegistry() { 40381f17ee7c07b5a80d7dcdeae3d62e497902ef85Owen Anderson} 41381f17ee7c07b5a80d7dcdeae3d62e497902ef85Owen Anderson 4290c579de5a383cee278acc3f7e7b9d0a656e6a35Owen Andersonconst PassInfo *PassRegistry::getPassInfo(const void *TI) const { 43cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines sys::SmartScopedReader<true> Guard(Lock); 44cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MapType::const_iterator I = PassInfoMap.find(TI); 45cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return I != PassInfoMap.end() ? I->second : nullptr; 46ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson} 47ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson 48ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Andersonconst PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { 49cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines sys::SmartScopedReader<true> Guard(Lock); 50cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringMapType::const_iterator I = PassInfoStringMap.find(Arg); 51cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return I != PassInfoStringMap.end() ? I->second : nullptr; 52ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson} 53ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson 54539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Anderson//===----------------------------------------------------------------------===// 55539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Anderson// Pass Registration mechanism 56539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Anderson// 57539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Anderson 5875f6df283f726c289b240fe8c5f2f42cdfff5d5fOwen Andersonvoid PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { 59cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines sys::SmartScopedWriter<true> Guard(Lock); 60ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson bool Inserted = 61cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second; 627008f1e9ab3e455955bac764282b62d51b5ae523Jakob Stoklund Olesen assert(Inserted && "Pass registered multiple times!"); 637008f1e9ab3e455955bac764282b62d51b5ae523Jakob Stoklund Olesen (void)Inserted; 64cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines PassInfoStringMap[PI.getPassArgument()] = &PI; 65539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Anderson 66539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Anderson // Notify any listeners. 67539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Anderson for (std::vector<PassRegistrationListener*>::iterator 68cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines I = Listeners.begin(), E = Listeners.end(); I != E; ++I) 69539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Anderson (*I)->passRegistered(&PI); 7075f6df283f726c289b240fe8c5f2f42cdfff5d5fOwen Anderson 71cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ShouldFree) ToFree.push_back(std::unique_ptr<const PassInfo>(&PI)); 72ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson} 73ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson 74ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Andersonvoid PassRegistry::unregisterPass(const PassInfo &PI) { 75cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines sys::SmartScopedWriter<true> Guard(Lock); 76cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MapType::iterator I = PassInfoMap.find(PI.getTypeInfo()); 77cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(I != PassInfoMap.end() && "Pass registered but not in map!"); 78ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson 79ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson // Remove pass from the map. 80cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines PassInfoMap.erase(I); 81cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines PassInfoStringMap.erase(PI.getPassArgument()); 82ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson} 83ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson 84ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Andersonvoid PassRegistry::enumerateWith(PassRegistrationListener *L) { 85cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines sys::SmartScopedReader<true> Guard(Lock); 86cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (auto I = PassInfoMap.begin(), E = PassInfoMap.end(); I != E; ++I) 87ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson L->passEnumerate(I->second); 88ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson} 89ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson 90ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson 91ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson/// Analysis Group Mechanisms. 9290c579de5a383cee278acc3f7e7b9d0a656e6a35Owen Andersonvoid PassRegistry::registerAnalysisGroup(const void *InterfaceID, 9390c579de5a383cee278acc3f7e7b9d0a656e6a35Owen Anderson const void *PassID, 949650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson PassInfo& Registeree, 9575f6df283f726c289b240fe8c5f2f42cdfff5d5fOwen Anderson bool isDefault, 9675f6df283f726c289b240fe8c5f2f42cdfff5d5fOwen Anderson bool ShouldFree) { 979650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson PassInfo *InterfaceInfo = const_cast<PassInfo*>(getPassInfo(InterfaceID)); 98dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!InterfaceInfo) { 999650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson // First reference to Interface, register it now. 1009650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson registerPass(Registeree); 1019650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson InterfaceInfo = &Registeree; 1029650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson } 1039650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson assert(Registeree.isAnalysisGroup() && 1049650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson "Trying to join an analysis group that is a normal pass!"); 1059650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson 1069650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson if (PassID) { 1079650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson PassInfo *ImplementationInfo = const_cast<PassInfo*>(getPassInfo(PassID)); 1089650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson assert(ImplementationInfo && 1099650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson "Must register pass before adding to AnalysisGroup!"); 1109650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson 111cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines sys::SmartScopedWriter<true> Guard(Lock); 1121e3e6362c8def5abcbc9a89c02619a0912177f7eOwen Anderson 1139650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson // Make sure we keep track of the fact that the implementation implements 1149650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson // the interface. 1159650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson ImplementationInfo->addInterfaceImplemented(InterfaceInfo); 1169650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson 117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines AnalysisGroupInfo &AGI = AnalysisGroupInfoMap[InterfaceInfo]; 1189650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson assert(AGI.Implementations.count(ImplementationInfo) == 0 && 1199650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson "Cannot add a pass to the same analysis group more than once!"); 1209650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson AGI.Implementations.insert(ImplementationInfo); 1219650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson if (isDefault) { 122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(InterfaceInfo->getNormalCtor() == nullptr && 1239650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson "Default implementation for analysis group already specified!"); 1249650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson assert(ImplementationInfo->getNormalCtor() && 1259650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson "Cannot specify pass as default if it does not have a default ctor"); 1269650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor()); 12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines InterfaceInfo->setTargetMachineCtor( 12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ImplementationInfo->getTargetMachineCtor()); 1299650983b9a30804d3479aeffb2a7f8bdb6b33942Owen Anderson } 130ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson } 13175f6df283f726c289b240fe8c5f2f42cdfff5d5fOwen Anderson 132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (ShouldFree) 133cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ToFree.push_back(std::unique_ptr<const PassInfo>(&Registeree)); 134ee9886ed3dfac7b4459c9cb5bf8845b27e241792Owen Anderson} 135539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Anderson 136539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Andersonvoid PassRegistry::addRegistrationListener(PassRegistrationListener *L) { 137cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines sys::SmartScopedWriter<true> Guard(Lock); 138cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Listeners.push_back(L); 139539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Anderson} 140539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Anderson 141539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Andersonvoid PassRegistry::removeRegistrationListener(PassRegistrationListener *L) { 142cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines sys::SmartScopedWriter<true> Guard(Lock); 143381f17ee7c07b5a80d7dcdeae3d62e497902ef85Owen Anderson 144cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines auto I = std::find(Listeners.begin(), Listeners.end(), L); 145cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Listeners.erase(I); 146539673579ec79b75a95ef9daefc6a8b2fc8552f5Owen Anderson} 147