Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
llvm-plugin-rs
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.
Usage
When importing this crate in your Cargo.toml
, you will need to specify the LLVM version to use with a corresponding feature flag:
[]
= { = "0.2", = ["llvm10-0"] }
Supported versions:
LLVM Version | Cargo Feature Flag | Linux | Windows | MacOS |
---|---|---|---|---|
10.0.x | llvm10-0 | ✓ | ✗ | ✓ |
11.0.x | llvm11-0 | ✓ | ✓ | ✓ |
12.0.x | llvm12-0 | ✓ | ✓ | ✓ |
13.0.x | llvm13-0 | ✓ | ✓ | ✓ |
14.0.x | llvm14-0 | ✓ | ✓ | ✓ |
Getting Started
An LLVM plugin is merely a dylib that is given a PassBuilder by the LLVM tool (e.g. opt, lld)
loading it.
Therefore, you must add the following line in your Cargo.toml
:
[]
= ["cdylib"]
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:
use Module;
use ;
// A name and version is required.
;
Now, executing this command would run our custom pass on some input module.bc
:
However, executing this command would not (custom-pass2
cannot be parsed by our plugin):
More callbacks are available, read the documentation for more details.
To learn more about how to sequentially apply more than one pass, read this opt guide.
Linux & MacOS Requirements
Your LLVM toolchain should dynamically link the LLVM library. Fortunately, this is the case for toolchains
distributed on apt
and homebrew
registeries.
If you are not in this case, you have to compile LLVM from sources by specifying the LLVM_LINK_LLVM_DYLIB=ON
cmake flag.
$ wget https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.0/llvm-14.0.0.src.tar.xz
$ tar xf llvm-14.0.0.src.tar.xz && cd llvm-14.0.0.src
$ mkdir build && cd build
$ cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$HOME/llvm" \
-DLLVM_LINK_LLVM_DYLIB=ON \
-G Ninja
$ ninja install
Windows Requirements
You have to compile LLVM from sources in any case, because you need to apply some patches to the LLVM
code base before compiling. Then, you need to specify the LLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON
cmake flag
while leaving the LLVM_TARGETS_TO_BUILD
flag to its default value.
$ wget https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.0/llvm-14.0.0.src.tar.xz
$ tar xf llvm-14.0.0.src.tar.xz && cd llvm-14.0.0.src
$ cat ../ci/windows/llvm-14.patch | patch -p1
$ mkdir build && cd build
$ cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="C:\\llvm" \
-DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON \
-G Ninja
$ ninja install
$ cp lib/opt.lib /c/llvm/lib
Don't forget to update your PATH
environment variable with your LLVM installation path.
Missing Features
- Support for loop passes (
Inkwell
doesn't currently provide safe wrappers) - Support for CGSCC passes (
Inkwell
doesn't currently provide safe wrappers) - FFI over the full manager proxy API (only a subset is currently implemented)
- FFI over the full analysis invalidation API (only a subset is currently implemented)
- FFI over builtin LLVM analyses (e.g. dominator tree)
Contributions are very welcome, make sure to check out the Contributing Guide first!