After #113716, we can make `#![no_builtins]` crates participate in LTO again.
`#![no_builtins]` with LTO does not result in undefined references to the error.
linker: also pass debuginfo compression flags
We support compressing debuginfo during codegen, but until this patch we didn't pass the flag to the linker. Doing so means we'll respect the requested compression even when building binaries or dylibs. This produces much smaller binaries: in my testing a debug build of ripgrep goes from 85M to 32M, and the target/ directory (after a clean build in both cases) goes from 508M to 329M just by enabling zlib compression of debuginfo.
We support compressing debuginfo during codegen, but until this patch we
didn't pass the flag to the linker. Doing so means we'll respect the
requested compression even when building binaries or dylibs. This
produces much smaller binaries: in my testing a debug build of ripgrep
goes from 85M to 32M, and the target/ directory (after a clean build in
both cases) goes from 508M to 329M just by enabling zlib compression of
debuginfo.
Remove cgu_reuse_tracker from Session
This removes a bit of global mutable state.
It will now miss post-lto cgu reuse when ThinLTO determines that a cgu doesn't get changed, but there weren't any tests for this anyway and a test for it would be fragile to the exact implementation of ThinLTO in LLVM.
stabilize combining +bundle and +whole-archive link modifiers
Per discussion on https://github.com/rust-lang/rust/issues/108081 combining +bundle and +whole-archive already works and can be stabilized independently of other aspects of the packed_bundled_libs feature. There is no risk of regression because this was not previously allowed.
r? `@petrochenkov`
This fixes the changes brought to codegen tests when effect params are
added to libcore, by not attempting to monomorphize functions that get
the host param by being `const fn`.
As of Xcode 15 Apple's linker has become a bit more strict about the
warnings it produces. One of those new warnings requires all valid
Mach-O object files in an archive to have a LC_BUILD_VERSION load
command:
```
ld: warning: no platform load command found in 'ARCHIVE[arm64][2106](lib.rmeta)', assuming: iOS-simulator
```
This was already being done for Mac Catalyst so this change expands this
logic to include it for all Apple platforms. I filed this behavior
change as FB12546320 and was told it was the new intentional behavior.
Currently, combining +bundle and +whole-archive works only with
#![feature(packed_bundled_libs)]
This crate feature is independent of the -Zpacked-bundled-libs
command line option.
This commit stabilizes the #![feature(packed_bundled_libs)] crate
feature and implicitly enables it only when the +bundle and
+whole-archive link modifiers are combined. This allows rlib
crates to use the +whole-archive link modifier with native
libraries and have all symbols included in the linked library
to be included in downstream staticlib crates that use the rlib as
a dependency. Other cases requiring the packed_bundled_libs
behavior still require the -Zpacked-bundled-libs command line
option, which can be stabilized independently in the future.
Per discussion on https://github.com/rust-lang/rust/issues/108081
there is no risk of regression stabilizing the crate feature in
this way because the combination of +bundle,+whole-archive link
modifiers was previously not allowed.
Infer `Lld::No` linker hint when the linker stem is a generic compiler driver
This PR basically reverts the temporary solution in https://github.com/rust-lang/rust/pull/113631 to a more long-term solution.
r? ``@petrochenkov``
In [this comment](https://github.com/rust-lang/rust/pull/113631#issuecomment-1634598238), you had ideas about a long-term solution:
> I wonder what a good non-temporary solution for the inference would look like.
>
> * If the default is `(Cc::No, Lld::Yes)` (e.g. `rust-lld`)
>
> * and we switch to some specific platform compiler (e.g. `-C linker=arm-none-eabi-gcc`), should we change to `Lld::No`? Maybe yes?
> * and we switch to some non-default but generic compiler `-C linker=clang`? Then maybe not?
>
> * If the default is `(Cc::Yes, Lld::Yes)` (e.g. future x86_64 linux with default LLD)
>
> * and we switch to some specific platform compiler (e.g. `-C linker=arm-none-eabi-gcc`), should we change to `Lld::No`? Maybe yes?
> * and we switch to some non-default but generic compiler `-C linker=clang`? Then maybe not?
>
I believe that we should infer the `Lld::No` linker hint for any `-Clinker` override, and all the cases above:
- the linker drivers have their own defaults, so in my mind `-Clinker` is a signal to use its default linker / flavor, rather than ours or the target's. In the case of generic compilers, it's more likely than not going to be `Lld::No`. I would expect this to be the case in general, even when including platform-specific compilers.
- the guess will be wrong if the linker driver uses lld by default (and we also don't want to search for `-fuse-ld` link args), but will work in the more common cases. And the minority of other cases can fix the wrong guess by opting into the precise linker flavor.
- this also ensures backwards-compatibility: today, even on targets with an lld default and overriding the linker, rustc will not use lld. That includes `thumbv6m-none-eabi` where issue #113597 happened.
It looks like the simplest option, and the one with least churn: we maintain the current behavior in ambiguous cases.
I've tested that this works on #113597, as expected from the failure.
(I also have a no-std `run-make` test using a custom target json spec: basically simulating a future `x86_64-unknown-linux-gnu` using an lld flavor by default, to check that e.g. `-Clinker=clang` doesn't use lld. I could add that test to this PR, but IIUC such a custom target requires `cargo -Z build-std` and we have no tests depending on this cargo feature yet. Let me know if you want to add this test of the linker inference for such targets.)
What do you think ?
Restrict linker version script of proc-macro crates to just its two symbols
Restrict linker version script of proc-macro crates to just the two symbols of each proc-macro crate.
The main known effect of doing this is to stop including `#[no_mangle]` symbols in the linker version script.
Background:
The combination of a proc-macro crate with an import of another crate that itself exports a no_mangle function was broken for a period of time, because:
* In PR #99944 we stopped exporting no_mangle symbols from proc-macro crates; proc-macro crates have a very limited interface and are meant to be treated as a blackbox to everything except rustc itself. However: he constructed linker version script still referred to them, but resolving that discrepancy was left as a FIXME in the code, tagged with issue #99978.
* In PR #108017 we started telling the linker to check (via the`--no-undefined-version` linker invocation flag) that every symbol referenced in the "linker version script" is provided as linker input. So the unresolved discrepancy from #99978 started surfacing as a compile-time error (e.g. #111888).
Fix#111888Fix#99978.
Avoid exporting __rust_alloc_error_handler_should_panic more than once.
Exporting `__rust_alloc_error_handler_should_panic` multiple times causes `ld.gold` to balk with: `error: version script assignment of to symbol __rust_alloc_error_handler_should_panic failed: symbol not defined`
Specifically this breaks builds of 1.70.0 and newer on DragonFly and YoctoProject with `ld.gold`. Builds with `ld.bfd` and `lld` should be unaffected.
http://errors.yoctoproject.org/Errors/Details/708194/
Exporting `__rust_alloc_error_handler_should_panic` multiple times
causes ld.gold to balk with: `error: version script assignment of to
symbol __rust_alloc_error_handler_should_panic failed: symbol not
defined`
Specifically this breaks builds on DragonFly and YoctoProject with
ld.gold. Builds with ld.bfd should be unaffected.
This function has some shared code for the thin LTO and fat LTO cases,
but those cases have so little in common that it's actually clearer to
treat them fully separately.
PR #112946 tweaked the naming of LLVM threads, but messed things up
slightly, resulting in threads on Windows having names like `optimize
module {} regex.f10ba03eb5ec7975-cgu.0`.
This commit removes the extraneous `{} `.
The main loop has a *very* complex condition, which includes two
mentions of `codegen_state`. The body of the loop then immediately
switches on the `codegen_state`.
I find it easier to understand if it's a `loop` and we check for exit
conditions after switching on `codegen_state`. We end up with a tiny bit
of code duplication, but it's clear that (a) we never exit in the
`Ongoing` case, (b) we exit in the `Completed` state only if several
things are true (and there's interaction with LTO there), and (c) we
exit in the `Aborted` state if a couple of things are true. Also, the
exit conditions are all simple conjunctions.
This loop condition involves `codegen_state`, `work_items`, and
`running_with_own_token`. But the body of the loop cannot modify
`codegen_state`, so repeatedly checking it is unnecessary.
`CodegenContext` is immutable except for the `worker` field - we clone
`CodegenContext` in multiple places, changing the `worker` field each
time. It's simpler to move the `worker` field out of `CodegenContext`.
It took me some time to understand how the main thread can lend a
jobserver token to an LLVM thread. This commit renames a couple of
things to make it clearer.
- Rename the `LLVMing` variant as `Lending`, because that is a clearer
description of what is happening.
- Rename `running` as `running_with_own_token`, which makes it clearer
that there might be one additional LLVM thread running (with a loaned
token). Also add a comment to its definition.
And rename the `Compiled` variant as `Finished`, because that name makes
it clearer there is nothing left to do, contrasting nicely with the
`Needs*` variants.