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.
getFilename()70   StringRef getFilename() const { return Filename; }
71 
72   /// Get the plugin name
getPluginName()73   StringRef getPluginName() const { return Info.PluginName; }
74 
75   /// Get the plugin version
getPluginVersion()76   StringRef getPluginVersion() const { return Info.PluginVersion; }
77 
78   /// Get the plugin API version
getAPIVersion()79   uint32_t getAPIVersion() const { return Info.APIVersion; }
80 
81   /// Invoke the PassBuilder callback registration
registerPassBuilderCallbacks(PassBuilder & PB)82   void registerPassBuilderCallbacks(PassBuilder &PB) const {
83     Info.RegisterPassBuilderCallbacks(PB);
84   }
85 
86 private:
PassPlugin(const std::string & Filename,const sys::DynamicLibrary & Library)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