-
Notifications
You must be signed in to change notification settings - Fork 474
feat: cross language LTO #3162
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
base: main
Are you sure you want to change the base?
feat: cross language LTO #3162
Conversation
Will take a look at the CI failures. FWIW I tested this locally with clang-18 and Rust 1.83 and it indeed works. When LTO is enabled for both Rust and C I see in-lining occurring across the language boundary |
args = [] | ||
|
||
# proc-macros do not benefit from LTO, and cannot be dynamically linked with LTO. | ||
if mode in ["thin", "fat", "off"] and not is_exec_configuration(ctx) and crate_info.type != "proc-macro": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you revert this intentionally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I was experimenting, but I switched this back to how it was before!
cfdef01
to
307b3c0
Compare
This PR enables cross language LTO for our release builds, meaning function calls from external C dependencies like `libdecimal` can potentially get inlined into Rust code. The way this works is when building our final binaries, e.g. `environmentd` and `clusterd`, we specify the `-Clinker-plugin-lto` flag to `rustc` which has our linker (`lld`) run the LTO passes instead of `rustc`. At which point all of our Rust and C code has been compiled to LLVM bitcode so to `lld` is free to optimize across languages. This only works when building for Linux. Arguments that `rustc` passes to the linker when targetting macOS don't seem to be supported by `ld64.lld`? See rust-lang/rust#60059 for some more investigation. ### Motivation Faster runtime performance. ### Tips for reviewer The commits are broken down as follows: 1. Some Bazel configuration so we can detect when the cross language LTO is requested _and_ when we're building on a Linux machine. 2. Updates to cargo-gazelle so we specify the right `rustc` flags. Theoretically something like this could be upstreamed into `rules_rust` which I started working on in bazelbuild/rules_rust#3162. But for now updating cargo-gazelle is a lot easier. 3. Running `bin/bazel gen` ### Checklist - [ ] This PR has adequate test coverage / QA involvement has been duly considered. ([trigger-ci for additional test/nightly runs](https://trigger-ci.dev.materialize.com/)) - [ ] This PR has an associated up-to-date [design doc](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/design/README.md), is a design doc ([template](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/design/00000000_template.md)), or is sufficiently small to not require a design. <!-- Reference the design in the description. --> - [ ] If this PR evolves [an existing `$T ⇔ Proto$T` mapping](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/command-and-response-binary-encoding.md) (possibly in a backwards-incompatible way), then it is tagged with a `T-proto` label. - [ ] If this PR will require changes to cloud orchestration or tests, there is a companion cloud PR to account for those changes that is tagged with the release-blocker label ([example](MaterializeInc/cloud#5021)). <!-- Ask in #team-cloud on Slack if you need help preparing the cloud PR. --> - [ ] If this PR includes major [user-facing behavior changes](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/guide-changes.md#what-changes-require-a-release-note), I have pinged the relevant PM to schedule a changelog post.
If you're using Clang for your C toolchain, it's possible to do cross language optimizations between Rust and C, see Rust's Linker-plugin-based LTO docs for more info.
This PR adds a new
@rules_rust//rust/settings:experimental_cross_language_lto
(off by default) which when building a Rust binary will set-Clinker-plugin-lto
. If LTO is enabled for both Rust and C will then delay optimizations to the linker, resulting in cross language optimizations.This feature is highly experimental. To have it work correctly you need to be using a Clang toolchain with
lld
as the linker that is recent enough to understand the bitcode emitted byrustc
. There is much more we can do here to make the feature more stable, but this seemed like a good starting point?