-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Compile rustc crates with the initial-exec TLS model #78201
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
cc @eddyb |
Trying this out to see if it provides a performance improvement. @bors try @rust-timer queue |
Awaiting bors try build completion |
⌛ Trying commit 328401119c35ff10758630aafe5eb7a04925c399 with merge a612e191b94bc6e23963dbadbab26b6486a51dc3... |
src/bootstrap/bin/rustc.rs
Outdated
if crate_name.map_or(false, |n| n.starts_with("rustc_") || n.starts_with("rustc-")) { | ||
cmd.arg("-Z").arg("tls-model=initial-exec"); | ||
} |
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.
I wonder if we should also check that the path includes compiler/rustc_
because there's some stuff on crates.io that also starts with rustc_
or rustc-
and it might not be strictly a rustc_driver
dependency.
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.
We need a much better way to handle this, yes; this was just the simplest way to test the impact of this change.
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.
Best bet is probably to modify builder.rs to set RUSTC_IS_COMPILING_THE_COMPILER for cargo and then read that here.
This may be silly, but, if we want to exactly track which crates are using TLS, so that we can list them out in the wrapper, we could:
This could get confusing so we might want to make it an internal |
@eddyb If we're going to go that far, I would rather just see this mechanism fixed to make the TLS model depend on the top-level artifact(s), such as "if you're building a binary use local-exec, if you're building a cdylib use global-dynamic for pub and local-dynamic for private". This shouldn't depend on the individual library crate, it should depend on the top-level crate. |
Oh yeah I forgot I wanted that too (should be possible, based on my experiments an |
☀️ Try build successful - checks-actions, checks-azure |
Queued a612e191b94bc6e23963dbadbab26b6486a51dc3 with parent 1d27267, future comparison URL. |
Finished benchmarking try commit (a612e191b94bc6e23963dbadbab26b6486a51dc3): comparison url. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. Please note that if the perf results are neutral, you should likely undo the rollup=never given below by specifying Importantly, though, if the results of this run are non-neutral do not roll this PR up -- it will mask other regressions or improvements in the roll up. @bors rollup=never |
Looks like this is definitely worth doing, and we just need to figure out the best way to capture the set of crates we can safely do it for. Ideally, we'd apply this to every crate that isn't a proc macro or compiled into a dynamically linkable version of |
If you tell the linker about the storage model instead of LLVM it should rewrite all TLS accesses to use that storage model I think. You could do that using a build.rs for rustc_driver. That will apply it to exactly the dylib that it should be applied to. |
Hm, so when you ask "Ideally, we'd apply this to every crate that isn't a proc macro or compiled into a dynamically linkable version of std. How can we most easily capture that set here?" -- do you mean to do that as an end-user visible change (rather than just to crates compiled by rustbuild? It seems to me that rustc shouldn't really be special here in some sense. That's probably not quite true because we have the somewhat odd case of compiling to dylibs that aren't intended to be dlopen'd (rather just linked directly), but I'm not sure that's important. I think the best thing is probably to start out with just a change to how we compile rustc which should be somewhat easier to land and see impacts of though. To do so we probably want to set the -Z flag via rustflags if possible, something like this diff. This will set it for pretty much everything except std workspace and crates that don't get rustflags (e.g., proc macros and other build deps). Note that this includes e.g. cargo and clippy too, but I think that's the right thing? diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 707c1ff3efa..0f6a74b01ce 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1114,6 +1114,10 @@ impl<'a> Builder<'a> {
}
}
+ if mode != Mode::Std {
+ rustflags.arg("-Ztls-model=initial-exec");
+ }
+
if self.config.incremental {
cargo.env("CARGO_INCREMENTAL", "1");
} else { |
3284011
to
15068d4
Compare
@Mark-Simulacrum Yeah, that looks perfect. That's exactly the set of crates that should work with this. @bors try @rust-timer queue |
Awaiting bors try build completion |
⌛ Trying commit 15068d492e48e3aefc563baa5aa9bd6ee9223a80 with merge e33e3c8a267474be0fabf07c0eb7b6e3f7e00e37... |
☀️ Try build successful - checks-actions |
Looks spurious?
|
@bors retry - agreed that this seems spurious
|
⌛ Testing commit 0328e69 with merge e012fa10bed4afe82574679760549a76eb053951... |
💔 Test failed - checks-actions |
The same error again on apple. |
This is a known issue which is unrelated to this PR: https://rust-lang.zulipchat.com/#narrow/stream/242791-t-infra/topic/apple-x86_64.20gha.20checks |
@bors retry |
☀️ Test successful - checks-actions |
Pkgsrc changes: * Adjust patches, convert tabs to spaces so that tests pass. * Remove patches which are no longer needed (upstream changed) * Minor adjustments for SunOS, e.g. disable stack probes. * Adjust cargo checksum patching accordingly. * Remove commented-out use of PATCHELF on NetBSD, which doesn't work anyway... Upstream changes: Version 1.49.0 (2020-12-31) ============================ Language ----------------------- - [Unions can now implement `Drop`, and you can now have a field in a union with `ManuallyDrop<T>`.][77547] - [You can now cast uninhabited enums to integers.][76199] - [You can now bind by reference and by move in patterns.][76119] This allows you to selectively borrow individual components of a type. E.g. ```rust #[derive(Debug)] struct Person { name: String, age: u8, } let person = Person { name: String::from("Alice"), age: 20, }; // `name` is moved out of person, but `age` is referenced. let Person { name, ref age } = person; println!("{} {}", name, age); ``` Compiler ----------------------- - [Added tier 1\* support for `aarch64-unknown-linux-gnu`.][78228] - [Added tier 2 support for `aarch64-apple-darwin`.][75991] - [Added tier 2 support for `aarch64-pc-windows-msvc`.][75914] - [Added tier 3 support for `mipsel-unknown-none`.][78676] - [Raised the minimum supported LLVM version to LLVM 9.][78848] - [Output from threads spawned in tests is now captured.][78227] - [Change os and vendor values to "none" and "unknown" for some targets][78951] \* Refer to Rust's [platform support page][forge-platform-support] for more information on Rust's tiered platform support. Libraries ----------------------- - [`RangeInclusive` now checks for exhaustion when calling `contains` and indexing.][78109] - [`ToString::to_string` now no longer shrinks the internal buffer in the default implementation.][77997] - [`ops::{Index, IndexMut}` are now implemented for fixed sized arrays of any length.][74989] Stabilized APIs --------------- - [`slice::select_nth_unstable`] - [`slice::select_nth_unstable_by`] - [`slice::select_nth_unstable_by_key`] The following previously stable methods are now `const`. - [`Poll::is_ready`] - [`Poll::is_pending`] Cargo ----------------------- - [Building a crate with `cargo-package` should now be independently reproducible.][cargo/8864] - [`cargo-tree` now marks proc-macro crates.][cargo/8765] - [Added `CARGO_PRIMARY_PACKAGE` build-time environment variable.] [cargo/8758] This variable will be set if the crate being built is one the user selected to build, either with `-p` or through defaults. - [You can now use glob patterns when specifying packages & targets.][cargo/8752] Compatibility Notes ------------------- - [Demoted `i686-unknown-freebsd` from host tier 2 to target tier 2 support.][78746] - [Macros that end with a semi-colon are now treated as statements even if they expand to nothing.][78376] - [Rustc will now check for the validity of some built-in attributes on enum variants.][77015] Previously such invalid or unused attributes could be ignored. - Leading whitespace is stripped more uniformly in documentation comments, which may change behavior. You read [this post about the changes][rustdoc-ws-post] for more details. - [Trait bounds are no longer inferred for associated types.][79904] Internal Only ------------- These changes provide no direct user facing benefits, but represent significant improvements to the internals and overall performance of rustc and related tools. - [rustc's internal crates are now compiled using the `initial-exec` Thread Local Storage model.][78201] - [Calculate visibilities once in resolve.][78077] - [Added `system` to the `llvm-libunwind` bootstrap config option.][77703] - [Added `--color` for configuring terminal color support to bootstrap.][79004] [75991]: rust-lang/rust#75991 [78951]: rust-lang/rust#78951 [78848]: rust-lang/rust#78848 [78746]: rust-lang/rust#78746 [78376]: rust-lang/rust#78376 [78228]: rust-lang/rust#78228 [78227]: rust-lang/rust#78227 [78201]: rust-lang/rust#78201 [78109]: rust-lang/rust#78109 [78077]: rust-lang/rust#78077 [77997]: rust-lang/rust#77997 [77703]: rust-lang/rust#77703 [77547]: rust-lang/rust#77547 [77015]: rust-lang/rust#77015 [76199]: rust-lang/rust#76199 [76119]: rust-lang/rust#76119 [75914]: rust-lang/rust#75914 [74989]: rust-lang/rust#74989 [79004]: rust-lang/rust#79004 [78676]: rust-lang/rust#78676 [79904]: rust-lang/rust#79904 [cargo/8864]: rust-lang/cargo#8864 [cargo/8765]: rust-lang/cargo#8765 [cargo/8758]: rust-lang/cargo#8758 [cargo/8752]: rust-lang/cargo#8752 [`slice::select_nth_unstable`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.select_nth_unstable [`slice::select_nth_unstable_by`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.select_nth_unstable_by [`slice::select_nth_unstable_by_key`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.select_nth_unstable_by_key [`hint::spin_loop`]: https://doc.rust-lang.org/stable/std/hint/fn.spin_loop.html [`Poll::is_ready`]: https://doc.rust-lang.org/stable/std/task/enum.Poll.html#method.is_ready [`Poll::is_pending`]: https://doc.rust-lang.org/stable/std/task/enum.Poll.html#method.is_pending [rustdoc-ws-post]: https://blog.guillaume-gomez.fr/articles/2020-11-11+New+doc+comment+handling+in+rustdoc
This change broke the Rust compiler on 32-bit PowerPC, see: #81334 |
This should produce more efficient code, with fewer calls to
__tls_get_addr. The tradeoff is that libraries using it won't work with
dlopen, but that shouldn't be a problem for rustc's internal libraries.