1 | //===- llvm/Passes/PassPlugin.h - Public Plugin API -----------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This defines the public entry point for new-PM pass plugins. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_PASSES_PASSPLUGIN_H |
14 | #define LLVM_PASSES_PASSPLUGIN_H |
15 | |
16 | #include "llvm/ADT/StringRef.h" |
17 | #include "llvm/Support/Compiler.h" |
18 | #include "llvm/Support/DynamicLibrary.h" |
19 | #include "llvm/Support/Error.h" |
20 | #include <cstdint> |
21 | #include <string> |
22 | |
23 | namespace llvm { |
24 | class PassBuilder; |
25 | |
26 | /// \macro LLVM_PLUGIN_API_VERSION |
27 | /// Identifies the API version understood by this plugin. |
28 | /// |
29 | /// When a plugin is loaded, the driver will check it's supported plugin version |
30 | /// against that of the plugin. A mismatch is an error. The supported version |
31 | /// will be incremented for ABI-breaking changes to the \c PassPluginLibraryInfo |
32 | /// struct, i.e. when callbacks are added, removed, or reordered. |
33 | #define LLVM_PLUGIN_API_VERSION 1 |
34 | |
35 | extern "C" { |
36 | /// Information about the plugin required to load its passes |
37 | /// |
38 | /// This struct defines the core interface for pass plugins and is supposed to |
39 | /// be filled out by plugin implementors. LLVM-side users of a plugin are |
40 | /// expected to use the \c PassPlugin class below to interface with it. |
41 | struct PassPluginLibraryInfo { |
42 | /// The API version understood by this plugin, usually \c |
43 | /// LLVM_PLUGIN_API_VERSION |
44 | uint32_t APIVersion; |
45 | /// A meaningful name of the plugin. |
46 | const char *PluginName; |
47 | /// The version of the plugin. |
48 | const char *PluginVersion; |
49 | |
50 | /// The callback for registering plugin passes with a \c PassBuilder |
51 | /// instance |
52 | void (*RegisterPassBuilderCallbacks)(PassBuilder &); |
53 | }; |
54 | } |
55 | |
56 | /// A loaded pass plugin. |
57 | /// |
58 | /// An instance of this class wraps a loaded pass plugin and gives access to |
59 | /// its interface defined by the \c PassPluginLibraryInfo it exposes. |
60 | class PassPlugin { |
61 | public: |
62 | /// Attempts to load a pass plugin from a given file. |
63 | /// |
64 | /// \returns Returns an error if either the library cannot be found or loaded, |
65 | /// there is no public entry point, or the plugin implements the wrong API |
66 | /// version. |
67 | static Expected<PassPlugin> Load(const std::string &Filename); |
68 | |
69 | /// Get the filename of the loaded plugin. |
70 | StringRef getFilename() const { return Filename; } |
71 | |
72 | /// Get the plugin name |
73 | StringRef getPluginName() const { return Info.PluginName; } |
74 | |
75 | /// Get the plugin version |
76 | StringRef getPluginVersion() const { return Info.PluginVersion; } |
77 | |
78 | /// Get the plugin API version |
79 | uint32_t getAPIVersion() const { return Info.APIVersion; } |
80 | |
81 | /// Invoke the PassBuilder callback registration |
82 | void registerPassBuilderCallbacks(PassBuilder &PB) const { |
83 | Info.RegisterPassBuilderCallbacks(PB); |
84 | } |
85 | |
86 | private: |
87 | PassPlugin(const std::string &Filename, const sys::DynamicLibrary &Library) |
88 | : Filename(Filename), Library(Library), Info() {} |
89 | |
90 | std::string Filename; |
91 | sys::DynamicLibrary Library; |
92 | PassPluginLibraryInfo Info; |
93 | }; |
94 | } |
95 | |
96 | /// The public entry point for a pass plugin. |
97 | /// |
98 | /// When a plugin is loaded by the driver, it will call this entry point to |
99 | /// obtain information about this plugin and about how to register its passes. |
100 | /// This function needs to be implemented by the plugin, see the example below: |
101 | /// |
102 | /// ``` |
103 | /// extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK |
104 | /// llvmGetPassPluginInfo() { |
105 | /// return { |
106 | /// LLVM_PLUGIN_API_VERSION, "MyPlugin", "v0.1", [](PassBuilder &PB) { ... } |
107 | /// }; |
108 | /// } |
109 | /// ``` |
110 | extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK |
111 | llvmGetPassPluginInfo(); |
112 | |
113 | #endif /* LLVM_PASSES_PASSPLUGIN_H */ |
114 | |