10b57cec5SDimitry Andric //===- llvm/PassSupport.h - Pass Support code -------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines stuff that is used to define and "use" Passes. This file 100b57cec5SDimitry Andric // is automatically #included by Pass.h, so: 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric // NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY 130b57cec5SDimitry Andric // 140b57cec5SDimitry Andric // Instead, #include Pass.h. 150b57cec5SDimitry Andric // 160b57cec5SDimitry Andric // This file defines Pass registration code and classes used for it. 170b57cec5SDimitry Andric // 180b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 190b57cec5SDimitry Andric 205ffd83dbSDimitry Andric #if !defined(LLVM_PASS_H) || defined(LLVM_PASSSUPPORT_H) 215ffd83dbSDimitry Andric #error "Do not include <PassSupport.h>; include <Pass.h> instead" 225ffd83dbSDimitry Andric #endif 235ffd83dbSDimitry Andric 240b57cec5SDimitry Andric #ifndef LLVM_PASSSUPPORT_H 250b57cec5SDimitry Andric #define LLVM_PASSSUPPORT_H 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 280b57cec5SDimitry Andric #include "llvm/PassInfo.h" 290b57cec5SDimitry Andric #include "llvm/PassRegistry.h" 30bdd1243dSDimitry Andric #include "llvm/Support/Error.h" 310b57cec5SDimitry Andric #include "llvm/Support/Threading.h" 320b57cec5SDimitry Andric #include <functional> 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric namespace llvm { 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric class Pass; 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric #define INITIALIZE_PASS(passName, arg, name, cfg, analysis) \ 390b57cec5SDimitry Andric static void *initialize##passName##PassOnce(PassRegistry &Registry) { \ 400b57cec5SDimitry Andric PassInfo *PI = new PassInfo( \ 410b57cec5SDimitry Andric name, arg, &passName::ID, \ 420b57cec5SDimitry Andric PassInfo::NormalCtor_t(callDefaultCtor<passName>), cfg, analysis); \ 430b57cec5SDimitry Andric Registry.registerPass(*PI, true); \ 440b57cec5SDimitry Andric return PI; \ 450b57cec5SDimitry Andric } \ 460b57cec5SDimitry Andric static llvm::once_flag Initialize##passName##PassFlag; \ 470b57cec5SDimitry Andric void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ 480b57cec5SDimitry Andric llvm::call_once(Initialize##passName##PassFlag, \ 490b57cec5SDimitry Andric initialize##passName##PassOnce, std::ref(Registry)); \ 500b57cec5SDimitry Andric } 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric #define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis) \ 530b57cec5SDimitry Andric static void *initialize##passName##PassOnce(PassRegistry &Registry) { 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric #define INITIALIZE_PASS_DEPENDENCY(depName) initialize##depName##Pass(Registry); 560b57cec5SDimitry Andric #define INITIALIZE_AG_DEPENDENCY(depName) \ 570b57cec5SDimitry Andric initialize##depName##AnalysisGroup(Registry); 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric #define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis) \ 600b57cec5SDimitry Andric PassInfo *PI = new PassInfo( \ 610b57cec5SDimitry Andric name, arg, &passName::ID, \ 620b57cec5SDimitry Andric PassInfo::NormalCtor_t(callDefaultCtor<passName>), cfg, analysis); \ 630b57cec5SDimitry Andric Registry.registerPass(*PI, true); \ 640b57cec5SDimitry Andric return PI; \ 650b57cec5SDimitry Andric } \ 660b57cec5SDimitry Andric static llvm::once_flag Initialize##passName##PassFlag; \ 670b57cec5SDimitry Andric void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ 680b57cec5SDimitry Andric llvm::call_once(Initialize##passName##PassFlag, \ 690b57cec5SDimitry Andric initialize##passName##PassOnce, std::ref(Registry)); \ 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric #define INITIALIZE_PASS_WITH_OPTIONS(PassName, Arg, Name, Cfg, Analysis) \ 730b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(PassName, Arg, Name, Cfg, Analysis) \ 740b57cec5SDimitry Andric PassName::registerOptions(); \ 750b57cec5SDimitry Andric INITIALIZE_PASS_END(PassName, Arg, Name, Cfg, Analysis) 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric #define INITIALIZE_PASS_WITH_OPTIONS_BEGIN(PassName, Arg, Name, Cfg, Analysis) \ 780b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(PassName, Arg, Name, Cfg, Analysis) \ 790b57cec5SDimitry Andric PassName::registerOptions(); 800b57cec5SDimitry Andric 81bdd1243dSDimitry Andric template < 82bdd1243dSDimitry Andric class PassName, 83bdd1243dSDimitry Andric std::enable_if_t<std::is_default_constructible<PassName>{}, bool> = true> 84bdd1243dSDimitry Andric Pass *callDefaultCtor() { 85bdd1243dSDimitry Andric return new PassName(); 86bdd1243dSDimitry Andric } 87bdd1243dSDimitry Andric 88bdd1243dSDimitry Andric template < 89bdd1243dSDimitry Andric class PassName, 90bdd1243dSDimitry Andric std::enable_if_t<!std::is_default_constructible<PassName>{}, bool> = true> 91bdd1243dSDimitry Andric Pass *callDefaultCtor() { 92bdd1243dSDimitry Andric // Some codegen passes should only be testable via 93bdd1243dSDimitry Andric // `llc -{start|stop}-{before|after}=<passname>`, not via `opt -<passname>`. 94bdd1243dSDimitry Andric report_fatal_error("target-specific codegen-only pass"); 95bdd1243dSDimitry Andric } 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric //===--------------------------------------------------------------------------- 980b57cec5SDimitry Andric /// RegisterPass<t> template - This template class is used to notify the system 990b57cec5SDimitry Andric /// that a Pass is available for use, and registers it into the internal 1000b57cec5SDimitry Andric /// database maintained by the PassManager. Unless this template is used, opt, 1010b57cec5SDimitry Andric /// for example will not be able to see the pass and attempts to create the pass 1020b57cec5SDimitry Andric /// will fail. This template is used in the follow manner (at global scope, in 1030b57cec5SDimitry Andric /// your .cpp file): 1040b57cec5SDimitry Andric /// 1050b57cec5SDimitry Andric /// static RegisterPass<YourPassClassName> tmp("passopt", "My Pass Name"); 1060b57cec5SDimitry Andric /// 1070b57cec5SDimitry Andric /// This statement will cause your pass to be created by calling the default 1080b57cec5SDimitry Andric /// constructor exposed by the pass. 1090b57cec5SDimitry Andric template <typename passName> struct RegisterPass : public PassInfo { 1100b57cec5SDimitry Andric // Register Pass using default constructor... 1110b57cec5SDimitry Andric RegisterPass(StringRef PassArg, StringRef Name, bool CFGOnly = false, 1120b57cec5SDimitry Andric bool is_analysis = false) 1130b57cec5SDimitry Andric : PassInfo(Name, PassArg, &passName::ID, 1140b57cec5SDimitry Andric PassInfo::NormalCtor_t(callDefaultCtor<passName>), CFGOnly, 1150b57cec5SDimitry Andric is_analysis) { 1160b57cec5SDimitry Andric PassRegistry::getPassRegistry()->registerPass(*this); 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric }; 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric /// RegisterAnalysisGroup - Register a Pass as a member of an analysis _group_. 1210b57cec5SDimitry Andric /// Analysis groups are used to define an interface (which need not derive from 1220b57cec5SDimitry Andric /// Pass) that is required by passes to do their job. Analysis Groups differ 1230b57cec5SDimitry Andric /// from normal analyses because any available implementation of the group will 1240b57cec5SDimitry Andric /// be used if it is available. 1250b57cec5SDimitry Andric /// 1260b57cec5SDimitry Andric /// If no analysis implementing the interface is available, a default 1270b57cec5SDimitry Andric /// implementation is created and added. A pass registers itself as the default 1280b57cec5SDimitry Andric /// implementation by specifying 'true' as the second template argument of this 1290b57cec5SDimitry Andric /// class. 1300b57cec5SDimitry Andric /// 1310b57cec5SDimitry Andric /// In addition to registering itself as an analysis group member, a pass must 1320b57cec5SDimitry Andric /// register itself normally as well. Passes may be members of multiple groups 1330b57cec5SDimitry Andric /// and may still be "required" specifically by name. 1340b57cec5SDimitry Andric /// 1350b57cec5SDimitry Andric /// The actual interface may also be registered as well (by not specifying the 1360b57cec5SDimitry Andric /// second template argument). The interface should be registered to associate 1370b57cec5SDimitry Andric /// a nice name with the interface. 1380b57cec5SDimitry Andric class RegisterAGBase : public PassInfo { 1390b57cec5SDimitry Andric public: 1400b57cec5SDimitry Andric RegisterAGBase(StringRef Name, const void *InterfaceID, 1410b57cec5SDimitry Andric const void *PassID = nullptr, bool isDefault = false); 1420b57cec5SDimitry Andric }; 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric template <typename Interface, bool Default = false> 1450b57cec5SDimitry Andric struct RegisterAnalysisGroup : public RegisterAGBase { RegisterAnalysisGroupRegisterAnalysisGroup1460b57cec5SDimitry Andric explicit RegisterAnalysisGroup(PassInfo &RPB) 1470b57cec5SDimitry Andric : RegisterAGBase(RPB.getPassName(), &Interface::ID, RPB.getTypeInfo(), 1480b57cec5SDimitry Andric Default) {} 1490b57cec5SDimitry Andric RegisterAnalysisGroupRegisterAnalysisGroup1500b57cec5SDimitry Andric explicit RegisterAnalysisGroup(const char *Name) 1510b57cec5SDimitry Andric : RegisterAGBase(Name, &Interface::ID) {} 1520b57cec5SDimitry Andric }; 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric #define INITIALIZE_ANALYSIS_GROUP(agName, name, defaultPass) \ 1550b57cec5SDimitry Andric static void *initialize##agName##AnalysisGroupOnce(PassRegistry &Registry) { \ 1560b57cec5SDimitry Andric initialize##defaultPass##Pass(Registry); \ 1570b57cec5SDimitry Andric PassInfo *AI = new PassInfo(name, &agName::ID); \ 1580b57cec5SDimitry Andric Registry.registerAnalysisGroup(&agName::ID, 0, *AI, false, true); \ 1590b57cec5SDimitry Andric return AI; \ 1600b57cec5SDimitry Andric } \ 1610b57cec5SDimitry Andric static llvm::once_flag Initialize##agName##AnalysisGroupFlag; \ 1620b57cec5SDimitry Andric void llvm::initialize##agName##AnalysisGroup(PassRegistry &Registry) { \ 1630b57cec5SDimitry Andric llvm::call_once(Initialize##agName##AnalysisGroupFlag, \ 1640b57cec5SDimitry Andric initialize##agName##AnalysisGroupOnce, \ 1650b57cec5SDimitry Andric std::ref(Registry)); \ 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric #define INITIALIZE_AG_PASS(passName, agName, arg, name, cfg, analysis, def) \ 1690b57cec5SDimitry Andric static void *initialize##passName##PassOnce(PassRegistry &Registry) { \ 1700b57cec5SDimitry Andric if (!def) \ 1710b57cec5SDimitry Andric initialize##agName##AnalysisGroup(Registry); \ 1720b57cec5SDimitry Andric PassInfo *PI = new PassInfo( \ 1730b57cec5SDimitry Andric name, arg, &passName::ID, \ 1740b57cec5SDimitry Andric PassInfo::NormalCtor_t(callDefaultCtor<passName>), cfg, analysis); \ 1750b57cec5SDimitry Andric Registry.registerPass(*PI, true); \ 1760b57cec5SDimitry Andric \ 1770b57cec5SDimitry Andric PassInfo *AI = new PassInfo(name, &agName::ID); \ 1780b57cec5SDimitry Andric Registry.registerAnalysisGroup(&agName::ID, &passName::ID, *AI, def, \ 1790b57cec5SDimitry Andric true); \ 1800b57cec5SDimitry Andric return AI; \ 1810b57cec5SDimitry Andric } \ 1820b57cec5SDimitry Andric static llvm::once_flag Initialize##passName##PassFlag; \ 1830b57cec5SDimitry Andric void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ 1840b57cec5SDimitry Andric llvm::call_once(Initialize##passName##PassFlag, \ 1850b57cec5SDimitry Andric initialize##passName##PassOnce, std::ref(Registry)); \ 1860b57cec5SDimitry Andric } 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric #define INITIALIZE_AG_PASS_BEGIN(passName, agName, arg, n, cfg, analysis, def) \ 1890b57cec5SDimitry Andric static void *initialize##passName##PassOnce(PassRegistry &Registry) { \ 1900b57cec5SDimitry Andric if (!def) \ 1910b57cec5SDimitry Andric initialize##agName##AnalysisGroup(Registry); 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric #define INITIALIZE_AG_PASS_END(passName, agName, arg, n, cfg, analysis, def) \ 1940b57cec5SDimitry Andric PassInfo *PI = new PassInfo( \ 1950b57cec5SDimitry Andric n, arg, &passName::ID, \ 1960b57cec5SDimitry Andric PassInfo::NormalCtor_t(callDefaultCtor<passName>), cfg, analysis); \ 1970b57cec5SDimitry Andric Registry.registerPass(*PI, true); \ 1980b57cec5SDimitry Andric \ 1990b57cec5SDimitry Andric PassInfo *AI = new PassInfo(n, &agName::ID); \ 2000b57cec5SDimitry Andric Registry.registerAnalysisGroup(&agName::ID, &passName::ID, *AI, def, true); \ 2010b57cec5SDimitry Andric return AI; \ 2020b57cec5SDimitry Andric } \ 2030b57cec5SDimitry Andric static llvm::once_flag Initialize##passName##PassFlag; \ 2040b57cec5SDimitry Andric void llvm::initialize##passName##Pass(PassRegistry &Registry) { \ 2050b57cec5SDimitry Andric llvm::call_once(Initialize##passName##PassFlag, \ 2060b57cec5SDimitry Andric initialize##passName##PassOnce, std::ref(Registry)); \ 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric //===--------------------------------------------------------------------------- 2100b57cec5SDimitry Andric /// PassRegistrationListener class - This class is meant to be derived from by 2110b57cec5SDimitry Andric /// clients that are interested in which passes get registered and unregistered 2120b57cec5SDimitry Andric /// at runtime (which can be because of the RegisterPass constructors being run 2130b57cec5SDimitry Andric /// as the program starts up, or may be because a shared object just got 2140b57cec5SDimitry Andric /// loaded). 2150b57cec5SDimitry Andric struct PassRegistrationListener { 2160b57cec5SDimitry Andric PassRegistrationListener() = default; 2170b57cec5SDimitry Andric virtual ~PassRegistrationListener() = default; 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric /// Callback functions - These functions are invoked whenever a pass is loaded 2200b57cec5SDimitry Andric /// or removed from the current executable. passRegisteredPassRegistrationListener2210b57cec5SDimitry Andric virtual void passRegistered(const PassInfo *) {} 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric /// enumeratePasses - Iterate over the registered passes, calling the 2240b57cec5SDimitry Andric /// passEnumerate callback on each PassInfo object. 2250b57cec5SDimitry Andric void enumeratePasses(); 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric /// passEnumerate - Callback function invoked when someone calls 2280b57cec5SDimitry Andric /// enumeratePasses on this PassRegistrationListener object. passEnumeratePassRegistrationListener2290b57cec5SDimitry Andric virtual void passEnumerate(const PassInfo *) {} 2300b57cec5SDimitry Andric }; 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric } // end namespace llvm 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric #endif // LLVM_PASSSUPPORT_H 235