Crate llvm_plugin
source ·Expand description
This crate gives the ability to safely implement passes for the new LLVM pass manager, by leveraging the strongly typed interface provided by Inkwell.
If you have never developed LLVM passes before, you can take a look at the available examples. They will (hopefully) give you a better idea of how to use this crate.
If you want a deeper understanding of the many concepts surrounding the new LLVM pass manager, you should read the official LLVM documentation.
§Getting started
An LLVM plugin is merely a dylib that is given a PassBuilder by the LLVM tool (e.g. opt, lld) loading it. A PassBuilder allows registering callbacks on specific actions being performed by the LLVM tool.
For instance, the --passes
parameter of opt allows specifying a custom pass pipeline
to be run on a given IR module. A plugin could therefore register a callback for
parsing an element of the given pipeline (e.g. a pass name), in order to insert a custom
pass to run by opt.
The following code illustrates the idea:
// A name and version is required.
#[llvm_plugin::plugin(name = "plugin_name", version = "0.1")]
fn plugin_registrar(builder: &mut PassBuilder) {
// Add a callback to parse a name from the textual representation of
// the pipeline to be run.
builder.add_module_pipeline_parsing_callback(|name, manager| {
if name == "custom-pass" {
// the input pipeline contains the name "custom-pass",
// so we add our custom pass to the pass manager
manager.add_pass(CustomPass);
// we notify the caller that we were able to parse
// the given name
PipelineParsing::Parsed
} else {
// in any other cases, we notify the caller that our
// callback wasn't able to parse the given name
PipelineParsing::NotParsed
}
});
}
struct CustomPass;
impl LlvmModulePass for CustomPass {
fn run_pass(
&self,
module: &mut Module,
manager: &ModuleAnalysisManager
) -> PreservedAnalyses {
// transform the IR
}
}
Now, executing this command would run our custom pass on the input module:
opt --load-pass-plugin=libplugin.so --passes=custom-pass module.bc -disable-output
However, executing this command would not (custom-pass2
cannot be parsed by our plugin):
opt --load-pass-plugin=libplugin.so --passes=custom-pass2 module.bc -disable-output
More callbacks are available, read the PassBuilder documentation for more details.
§A note on Windows
On this platform, LLVM plugins need the LLVM symbols directly from the executable loading
them (most of the time opt.exe
or lld.exe
). Therefore, you need to specify the
additional feature win-link-opt
or win-link-lld
while building a plugin. The former
will link the plugin to opt.lib
, the latter being for lld.lib
.
Re-exports§
pub use inkwell;
Structs§
- Struct allowing to query the pass manager for the result of analyses on function IR.
- Struct allowing to make queries to the pass manager about function-level analyses.
- Struct allowing to add passes on LLVM IR functions to the pass manager pipeline.
- Struct allowing to query the pass manager for the result of analyses on module IR.
- Struct allowing to add passes on LLVM IR modules to the pass manager pipeline.
- Main struct for registering callbacks.
Enums§
- Enum for the LLVM-provided high-level optimization levels.
- Enum describing whether a pipeline parsing callback successfully parsed its given pipeline element.
- Enum specifying whether analyses on an IR unit are not preserved due to the modification of such unit by a transformation pass.
Traits§
- Trait to use for implementing an analysis pass on an LLVM function.
- Trait to use for implementing a transformation pass on an LLVM function.
- Trait to use for implementing an analysis pass on an LLVM module.
- Trait to use for implementing a transformation pass on an LLVM module.
Attribute Macros§
- plugin
macros
Macro for defining a new LLVM plugin.