10b57cec5SDimitry Andric //===- llvm/Passes/PassPlugin.h - Public Plugin API -----------------------===// 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 defines the public entry point for new-PM pass plugins. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_PASSES_PASSPLUGIN_H 140b57cec5SDimitry Andric #define LLVM_PASSES_PASSPLUGIN_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 170b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 180b57cec5SDimitry Andric #include "llvm/Support/DynamicLibrary.h" 190b57cec5SDimitry Andric #include "llvm/Support/Error.h" 200b57cec5SDimitry Andric #include <cstdint> 210b57cec5SDimitry Andric #include <string> 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric namespace llvm { 240b57cec5SDimitry Andric class PassBuilder; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric /// \macro LLVM_PLUGIN_API_VERSION 270b57cec5SDimitry Andric /// Identifies the API version understood by this plugin. 280b57cec5SDimitry Andric /// 290b57cec5SDimitry Andric /// When a plugin is loaded, the driver will check it's supported plugin version 300b57cec5SDimitry Andric /// against that of the plugin. A mismatch is an error. The supported version 310b57cec5SDimitry Andric /// will be incremented for ABI-breaking changes to the \c PassPluginLibraryInfo 320b57cec5SDimitry Andric /// struct, i.e. when callbacks are added, removed, or reordered. 330b57cec5SDimitry Andric #define LLVM_PLUGIN_API_VERSION 1 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric extern "C" { 360b57cec5SDimitry Andric /// Information about the plugin required to load its passes 370b57cec5SDimitry Andric /// 380b57cec5SDimitry Andric /// This struct defines the core interface for pass plugins and is supposed to 390b57cec5SDimitry Andric /// be filled out by plugin implementors. LLVM-side users of a plugin are 400b57cec5SDimitry Andric /// expected to use the \c PassPlugin class below to interface with it. 410b57cec5SDimitry Andric struct PassPluginLibraryInfo { 420b57cec5SDimitry Andric /// The API version understood by this plugin, usually \c 430b57cec5SDimitry Andric /// LLVM_PLUGIN_API_VERSION 440b57cec5SDimitry Andric uint32_t APIVersion; 450b57cec5SDimitry Andric /// A meaningful name of the plugin. 460b57cec5SDimitry Andric const char *PluginName; 470b57cec5SDimitry Andric /// The version of the plugin. 480b57cec5SDimitry Andric const char *PluginVersion; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric /// The callback for registering plugin passes with a \c PassBuilder 510b57cec5SDimitry Andric /// instance 520b57cec5SDimitry Andric void (*RegisterPassBuilderCallbacks)(PassBuilder &); 530b57cec5SDimitry Andric }; 540b57cec5SDimitry Andric } 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric /// A loaded pass plugin. 570b57cec5SDimitry Andric /// 580b57cec5SDimitry Andric /// An instance of this class wraps a loaded pass plugin and gives access to 590b57cec5SDimitry Andric /// its interface defined by the \c PassPluginLibraryInfo it exposes. 600b57cec5SDimitry Andric class PassPlugin { 610b57cec5SDimitry Andric public: 620b57cec5SDimitry Andric /// Attempts to load a pass plugin from a given file. 630b57cec5SDimitry Andric /// 640b57cec5SDimitry Andric /// \returns Returns an error if either the library cannot be found or loaded, 650b57cec5SDimitry Andric /// there is no public entry point, or the plugin implements the wrong API 660b57cec5SDimitry Andric /// version. 670b57cec5SDimitry Andric static Expected<PassPlugin> Load(const std::string &Filename); 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric /// Get the filename of the loaded plugin. getFilename()700b57cec5SDimitry Andric StringRef getFilename() const { return Filename; } 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric /// Get the plugin name getPluginName()730b57cec5SDimitry Andric StringRef getPluginName() const { return Info.PluginName; } 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric /// Get the plugin version getPluginVersion()760b57cec5SDimitry Andric StringRef getPluginVersion() const { return Info.PluginVersion; } 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric /// Get the plugin API version getAPIVersion()790b57cec5SDimitry Andric uint32_t getAPIVersion() const { return Info.APIVersion; } 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric /// Invoke the PassBuilder callback registration registerPassBuilderCallbacks(PassBuilder & PB)820b57cec5SDimitry Andric void registerPassBuilderCallbacks(PassBuilder &PB) const { 830b57cec5SDimitry Andric Info.RegisterPassBuilderCallbacks(PB); 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric private: PassPlugin(const std::string & Filename,const sys::DynamicLibrary & Library)870b57cec5SDimitry Andric PassPlugin(const std::string &Filename, const sys::DynamicLibrary &Library) 880b57cec5SDimitry Andric : Filename(Filename), Library(Library), Info() {} 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric std::string Filename; 910b57cec5SDimitry Andric sys::DynamicLibrary Library; 920b57cec5SDimitry Andric PassPluginLibraryInfo Info; 930b57cec5SDimitry Andric }; 940b57cec5SDimitry Andric } 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric /// The public entry point for a pass plugin. 970b57cec5SDimitry Andric /// 980b57cec5SDimitry Andric /// When a plugin is loaded by the driver, it will call this entry point to 990b57cec5SDimitry Andric /// obtain information about this plugin and about how to register its passes. 1000b57cec5SDimitry Andric /// This function needs to be implemented by the plugin, see the example below: 1010b57cec5SDimitry Andric /// 1020b57cec5SDimitry Andric /// ``` 1030b57cec5SDimitry Andric /// extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK 1040b57cec5SDimitry Andric /// llvmGetPassPluginInfo() { 1050b57cec5SDimitry Andric /// return { 1060b57cec5SDimitry Andric /// LLVM_PLUGIN_API_VERSION, "MyPlugin", "v0.1", [](PassBuilder &PB) { ... } 1070b57cec5SDimitry Andric /// }; 1080b57cec5SDimitry Andric /// } 1090b57cec5SDimitry Andric /// ``` 1100b57cec5SDimitry Andric extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK 1110b57cec5SDimitry Andric llvmGetPassPluginInfo(); 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric #endif /* LLVM_PASSES_PASSPLUGIN_H */ 114