-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow loading of LLVM plugins [when dynamically built rust] #82734
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @varkor (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
So is this intended to be used via |
Precisely! It currently, however, may require a shared library LLVM build of rustc. As an example, this (along with shared library build) enables https://github.com/wsmoses/Enzyme to provide automatic differentiation of rust code.
|
Why is it necessary for LLVM to be built shared for this to work? We build a shared libLLVM on dist-x86_64-linux to use ThinLTO, but I believe most other targets link it statically. |
The reasons (at least for my test cases) that's needed is because of symbol resolution. The header in this patch needs to be included when arguments are parsed (thus loading the plugin). Arguments are currently parsed on rustc_llvm in a custom C++ routine. However, the rustc_llvm library does not contain most of the llvm symbols that a plugin may use (for example |
My worry is that this being exposed as a stable interface (like, sadly, many other flags) really limit us in what we can do in the future in terms of changing how rust relates to LLVM. In this particular example, we wouldn't be able to link to LLVM statically without breaking people utilizing LLVM plugin loading interface, or even upgrade LLVM, as it does not provide stable APIs between releases. (In retrospective |
I'll also note that we only ship dynamically linked LLVM on x86_64-unknown-linux-gnu today I think, so plugin support feels pretty limited too in that sense. |
I'm not as worried about the LLVM ABI problems, perhaps because I believe that any plugin should have to be built against the current rustc's packaged LLVM. Certainly this would mean that plugins using LLVM have to be updated upon an LLVM major release upgrade, but it shouldn't prevent rustc from upgrading LLVM. How often does rust upgrade its LLVM? I assume its during a major (or perhaps) minor release? |
Another way we could handle plugins is to do something like this: wsmoses@0149bc4 In it we could define an unstable flag listing potential plugins to be loaded. Obviously it would still have the dynamic LLVM requirement, but perhaps the unstable flag would be better? |
I'm not familiar with the nuances of this decision, so I'm going to reassign. r? @nagisa |
I think a change like this warrants a RFC or at least a MCP. |
We have wanted something like this for Fedora and RHEL in order to support annobin. Our |
Created MCP here: rust-lang/compiler-team#419 |
Given that MCP is not progressing much at all, I think this may have a better chance of progressing if loading of LLVM plugins was explicitly unstable (i.e. only usable via a |
I think the PR referenced above resolves most of my concerns surrounding stability, and being an unstable flag does not require the MCP process, which seems to have gotten stuck. I think we should proceed with that one. |
Allow loading of llvm plugins on nightly Based on a discussion in rust-lang#82734 / with `@wsmoses.` Mainly moves [this](wsmoses@0149bc4) behind a -Z flag, so it can only be used on nightly, as requested by `@nagisa` in rust-lang#82734 (comment) This change allows loading of llvm plugins like Enzyme. Right now it also requires a shared library LLVM build of rustc for symbol resolution. ```rust // test.rs extern { fn __enzyme_autodiff(_: usize, ...) -> f64; } fn square(x : f64) -> f64 { return x * x; } fn main() { unsafe { println!("Hello, world {} {}!", square(3.0), __enzyme_autodiff(square as usize, 3.0)); } } ``` ``` ./rustc test.rs -Z llvm-plugins="./LLVMEnzyme-12.so" -C passes="enzyme" ./test Hello, world 9 6! ``` I will try to figure out how to simplify the usage and get this into stable in a later iteration, but having this on nightly will already help testing further steps.
No description provided.