123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- llvm/PassSupport.h - Pass Support code -------------------*- C++ -*-===//
- //
- // 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 defines stuff that is used to define and "use" Passes. This file
- // is automatically #included by Pass.h, so:
- //
- // NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY
- //
- // Instead, #include Pass.h.
- //
- // This file defines Pass registration code and classes used for it.
- //
- //===----------------------------------------------------------------------===//
- #if !defined(LLVM_PASS_H) || defined(LLVM_PASSSUPPORT_H)
- #error "Do not include <PassSupport.h>; include <Pass.h> instead"
- #endif
- #ifndef LLVM_PASSSUPPORT_H
- #define LLVM_PASSSUPPORT_H
- #include "llvm/ADT/StringRef.h"
- #include "llvm/PassInfo.h"
- #include "llvm/PassRegistry.h"
- #include "llvm/Support/Error.h"
- #include "llvm/Support/Threading.h"
- #include <functional>
- namespace llvm {
- class Pass;
- #define INITIALIZE_PASS(passName, arg, name, cfg, analysis) \
- static void *initialize##passName##PassOnce(PassRegistry &Registry) { \
- PassInfo *PI = new PassInfo( \
- name, arg, &passName::ID, \
- PassInfo::NormalCtor_t(callDefaultCtor<passName>), cfg, analysis); \
- Registry.registerPass(*PI, true); \
- return PI; \
- } \
- static llvm::once_flag Initialize##passName##PassFlag; \
- void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
- llvm::call_once(Initialize##passName##PassFlag, \
- initialize##passName##PassOnce, std::ref(Registry)); \
- }
- #define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis) \
- static void *initialize##passName##PassOnce(PassRegistry &Registry) {
- #define INITIALIZE_PASS_DEPENDENCY(depName) initialize##depName##Pass(Registry);
- #define INITIALIZE_AG_DEPENDENCY(depName) \
- initialize##depName##AnalysisGroup(Registry);
- #define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis) \
- PassInfo *PI = new PassInfo( \
- name, arg, &passName::ID, \
- PassInfo::NormalCtor_t(callDefaultCtor<passName>), cfg, analysis); \
- Registry.registerPass(*PI, true); \
- return PI; \
- } \
- static llvm::once_flag Initialize##passName##PassFlag; \
- void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
- llvm::call_once(Initialize##passName##PassFlag, \
- initialize##passName##PassOnce, std::ref(Registry)); \
- }
- #define INITIALIZE_PASS_WITH_OPTIONS(PassName, Arg, Name, Cfg, Analysis) \
- INITIALIZE_PASS_BEGIN(PassName, Arg, Name, Cfg, Analysis) \
- PassName::registerOptions(); \
- INITIALIZE_PASS_END(PassName, Arg, Name, Cfg, Analysis)
- #define INITIALIZE_PASS_WITH_OPTIONS_BEGIN(PassName, Arg, Name, Cfg, Analysis) \
- INITIALIZE_PASS_BEGIN(PassName, Arg, Name, Cfg, Analysis) \
- PassName::registerOptions();
- template <
- class PassName,
- std::enable_if_t<std::is_default_constructible<PassName>{}, bool> = true>
- Pass *callDefaultCtor() {
- return new PassName();
- }
- template <
- class PassName,
- std::enable_if_t<!std::is_default_constructible<PassName>{}, bool> = true>
- Pass *callDefaultCtor() {
- // Some codegen passes should only be testable via
- // `llc -{start|stop}-{before|after}=<passname>`, not via `opt -<passname>`.
- report_fatal_error("target-specific codegen-only pass");
- }
- //===---------------------------------------------------------------------------
- /// RegisterPass<t> template - This template class is used to notify the system
- /// that a Pass is available for use, and registers it into the internal
- /// database maintained by the PassManager. Unless this template is used, opt,
- /// for example will not be able to see the pass and attempts to create the pass
- /// will fail. This template is used in the follow manner (at global scope, in
- /// your .cpp file):
- ///
- /// static RegisterPass<YourPassClassName> tmp("passopt", "My Pass Name");
- ///
- /// This statement will cause your pass to be created by calling the default
- /// constructor exposed by the pass.
- template <typename passName> struct RegisterPass : public PassInfo {
- // Register Pass using default constructor...
- RegisterPass(StringRef PassArg, StringRef Name, bool CFGOnly = false,
- bool is_analysis = false)
- : PassInfo(Name, PassArg, &passName::ID,
- PassInfo::NormalCtor_t(callDefaultCtor<passName>), CFGOnly,
- is_analysis) {
- PassRegistry::getPassRegistry()->registerPass(*this);
- }
- };
- /// RegisterAnalysisGroup - Register a Pass as a member of an analysis _group_.
- /// Analysis groups are used to define an interface (which need not derive from
- /// Pass) that is required by passes to do their job. Analysis Groups differ
- /// from normal analyses because any available implementation of the group will
- /// be used if it is available.
- ///
- /// If no analysis implementing the interface is available, a default
- /// implementation is created and added. A pass registers itself as the default
- /// implementation by specifying 'true' as the second template argument of this
- /// class.
- ///
- /// In addition to registering itself as an analysis group member, a pass must
- /// register itself normally as well. Passes may be members of multiple groups
- /// and may still be "required" specifically by name.
- ///
- /// The actual interface may also be registered as well (by not specifying the
- /// second template argument). The interface should be registered to associate
- /// a nice name with the interface.
- class RegisterAGBase : public PassInfo {
- public:
- RegisterAGBase(StringRef Name, const void *InterfaceID,
- const void *PassID = nullptr, bool isDefault = false);
- };
- template <typename Interface, bool Default = false>
- struct RegisterAnalysisGroup : public RegisterAGBase {
- explicit RegisterAnalysisGroup(PassInfo &RPB)
- : RegisterAGBase(RPB.getPassName(), &Interface::ID, RPB.getTypeInfo(),
- Default) {}
- explicit RegisterAnalysisGroup(const char *Name)
- : RegisterAGBase(Name, &Interface::ID) {}
- };
- #define INITIALIZE_ANALYSIS_GROUP(agName, name, defaultPass) \
- static void *initialize##agName##AnalysisGroupOnce(PassRegistry &Registry) { \
- initialize##defaultPass##Pass(Registry); \
- PassInfo *AI = new PassInfo(name, &agName::ID); \
- Registry.registerAnalysisGroup(&agName::ID, 0, *AI, false, true); \
- return AI; \
- } \
- static llvm::once_flag Initialize##agName##AnalysisGroupFlag; \
- void llvm::initialize##agName##AnalysisGroup(PassRegistry &Registry) { \
- llvm::call_once(Initialize##agName##AnalysisGroupFlag, \
- initialize##agName##AnalysisGroupOnce, \
- std::ref(Registry)); \
- }
- #define INITIALIZE_AG_PASS(passName, agName, arg, name, cfg, analysis, def) \
- static void *initialize##passName##PassOnce(PassRegistry &Registry) { \
- if (!def) \
- initialize##agName##AnalysisGroup(Registry); \
- PassInfo *PI = new PassInfo( \
- name, arg, &passName::ID, \
- PassInfo::NormalCtor_t(callDefaultCtor<passName>), cfg, analysis); \
- Registry.registerPass(*PI, true); \
- \
- PassInfo *AI = new PassInfo(name, &agName::ID); \
- Registry.registerAnalysisGroup(&agName::ID, &passName::ID, *AI, def, \
- true); \
- return AI; \
- } \
- static llvm::once_flag Initialize##passName##PassFlag; \
- void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
- llvm::call_once(Initialize##passName##PassFlag, \
- initialize##passName##PassOnce, std::ref(Registry)); \
- }
- #define INITIALIZE_AG_PASS_BEGIN(passName, agName, arg, n, cfg, analysis, def) \
- static void *initialize##passName##PassOnce(PassRegistry &Registry) { \
- if (!def) \
- initialize##agName##AnalysisGroup(Registry);
- #define INITIALIZE_AG_PASS_END(passName, agName, arg, n, cfg, analysis, def) \
- PassInfo *PI = new PassInfo( \
- n, arg, &passName::ID, \
- PassInfo::NormalCtor_t(callDefaultCtor<passName>), cfg, analysis); \
- Registry.registerPass(*PI, true); \
- \
- PassInfo *AI = new PassInfo(n, &agName::ID); \
- Registry.registerAnalysisGroup(&agName::ID, &passName::ID, *AI, def, true); \
- return AI; \
- } \
- static llvm::once_flag Initialize##passName##PassFlag; \
- void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
- llvm::call_once(Initialize##passName##PassFlag, \
- initialize##passName##PassOnce, std::ref(Registry)); \
- }
- //===---------------------------------------------------------------------------
- /// PassRegistrationListener class - This class is meant to be derived from by
- /// clients that are interested in which passes get registered and unregistered
- /// at runtime (which can be because of the RegisterPass constructors being run
- /// as the program starts up, or may be because a shared object just got
- /// loaded).
- struct PassRegistrationListener {
- PassRegistrationListener() = default;
- virtual ~PassRegistrationListener() = default;
- /// Callback functions - These functions are invoked whenever a pass is loaded
- /// or removed from the current executable.
- virtual void passRegistered(const PassInfo *) {}
- /// enumeratePasses - Iterate over the registered passes, calling the
- /// passEnumerate callback on each PassInfo object.
- void enumeratePasses();
- /// passEnumerate - Callback function invoked when someone calls
- /// enumeratePasses on this PassRegistrationListener object.
- virtual void passEnumerate(const PassInfo *) {}
- };
- } // end namespace llvm
- #endif // LLVM_PASSSUPPORT_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|