Move metadata symbol export from exported_non_generic_symbols to exported_symbols
The metadata symbol must not be encoded in the crate metadata, and must be exported from proc-macros. Handling the export of the metadata symbol in exported_symbols handles both things at once without requiring manual fixups elsewhere.
coverage: Remove all unstable support for MC/DC instrumentation
Preliminary support for a partial implementation of “Modified Condition/Decision Coverage” instrumentation was added behind the unstable flag `-Zcoverage-options=mcdc` in 2024. These are the most substantial PRs involved:
- rust-lang/rust#123409
- rust-lang/rust#126733
At the time, I accepted these PRs with relatively modest scrutiny, because I did not want to stand in the way of independent work on MC/DC instrumentation. My hope was that ongoing work by interested contributors would lead to the code becoming clearer and more maintainable over time.
---
However, that MC/DC code has proven itself to be a major burden on overall maintenance of coverage instrumentation, and a major obstacle to other planned improvements, such as internal changes needed for proper support of macro expansion regions.
I have also become reluctant to accept any further MC/DC-related changes that would increase this burden.
That tension has resulted in an unhappy impasse. On one hand, the present MC/DC implementation is not yet complete, and shows little sign of being complete at an acceptable level of code quality in the foreseeable future. On the other hand, the continued existence of this partial MC/DC implementation is imposing serious maintenance burdens on every other aspect of coverage instrumentation, and is preventing some of the very improvements that would make it easier to accept expanded MC/DC support in the future.
While I know this will be disappointing to some, I think the healthy way forward is accept that I made the wrong call in accepting the current implementation, and to remove it entirely from the compiler.
Print CGU reuse statistics in `-Zprint-mono-items`
I'm trying to expose more information about incremental profiling from rustc (https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Profiling.2Fanalysis.20of.20incremental.20builds/with/531383501). One of the things that would be quite useful to expose is the CGU reuse state, so that when you do a rebuild, you can see all the CGUs (and all the functions) that had to be recompiled.
Currently, we have (AFAIK) two ways of outputting monomorphization statistics:
1) `-Zdump-mono-stats` outputs statistics about number of instantiations and expected compilation cost of individual functions in the local crate being compiled. It can be outputted either as Markdown or JSON.
2) `-Zprint-mono-items` outputs a pair (item, CGU) for each monomorphized item.
I was thinking about recording CGU statistics in the self-profile output, but I realized that as a simpler step, we could just add CGU reuse data to `-Zprint-mono-items`, as an additional output. That is what this PR does.
[codegen] assume the tag, not the relative discriminant
Address the issue mentioned in <https://github.com/llvm/llvm-project/issues/134024#issuecomment-3131782555> by changing discriminant calculation to `assume` on the originally-loaded `tag`, rather than on `cast(tag)-OFFSET`.
The previous way does make the *purpose* of the assume clearer, IMHO, since you see `assume(x != 4); if p { x } else { 4 }`, but doing it this way instead means that the `add`s optimize away in LLVM21, which is more important. And this new way is still easily thought of as being like metadata on the load saying specifically which value is impossible.
Demo of the LLVM20 vs LLVM21 difference: <https://llvm.godbolt.org/z/n54x5Mq1T>
r? ``@nikic``
The metadata symbol must not be encoded in the crate metadata, and must
be exported from proc-macros. Handling the export of the metadata symbol
in exported_symbols handles both things at once without requiring manual
fixups elsewhere.
Instead of collecting pretty printers transitively when building
executables/staticlibs/cdylibs, let the debugger find each crate's
pretty printers via its .debug_gdb_scripts section. This covers the case
where libraries defining custom pretty printers are loaded dynamically.
Make sure that compiler and linker don't optimize the section's contents
away by adding the global holding the data to "llvm.used". The volatile
load in the main shim is retained because "llvm.used", which translates
to SHF_GNU_RETAIN on ELF targets, requires a reasonably recent linker;
emitting the volatile load ensures compatibility with older linkers, at
least when libstd is used.
Pretty printers in dylib dependencies are now emitted by the main crate
instead of the dylib; apart from matching how rlibs are handled, this
approach has the advantage that `omit_gdb_pretty_printer_section` keeps
working with dylib dependencies.
Fix linker-plugin-lto only doing thin lto
When rust provides LLVM bitcode files to lld and the bitcode contains
function summaries as used for thin lto, lld defaults to using thin lto.
This prevents some optimizations that are only applied for fat lto.
We solve this by not creating function summaries when fat lto is
enabled. The bitcode for the module is just directly written out.
An alternative solution would be to set the `ThinLTO=0` module flag to
signal lld to do fat lto.
The code in clang that sets this flag is here:
560149b5e3/clang/lib/CodeGen/BackendUtil.cpp (L1150)
The code in LLVM that queries the flag and defaults to thin lto if not
set is here:
e258bca950/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp (L4441-L4446)
try-job: x86_64-gnu-debug
try-job: aarch64-gnu-debug
When rust provides LLVM bitcode files to lld and the bitcode contains
function summaries as used for thin lto, lld defaults to using thin lto.
This prevents some optimizations that are only applied for fat lto.
We solve this by not creating function summaries when fat lto is
enabled. The bitcode for the module is just directly written out.
An alternative solution would be to set the `ThinLTO=0` module flag to
signal lld to do fat lto.
The code in clang that sets this flag is here:
560149b5e3/clang/lib/CodeGen/BackendUtil.cpp (L1150)
The code in LLVM that queries the flag and defaults to thin lto if not
set is here:
e258bca950/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp (L4441-L4446)
Only extract lang items once in codegen_fn_attrs
This one should be obvious. These two extraction points used to be far apart but now that they're refactored to be close it was rather obvious we're just doing double work....
r? ``@WaffleLapkin``
Buils on rust-lang/rust#144655
Implement support for `become` and explicit tail call codegen for the LLVM backend
This PR implements codegen of explicit tail calls via `become` in `rustc_codegen_ssa` and support within the LLVM backend. Completes a task on (https://github.com/rust-lang/rust/issues/112788). This PR implements all the necessary bits to make explicit tail calls usable, other backends have received stubs for now and will ICE if you use `become` on them. I suspect there is some bikeshedding to be done on how we should go about implementing this for other backends, but it should be relatively straightforward for GCC after this is merged.
During development I also put together a POC bytecode VM based on tail call dispatch to test these changes out and analyze the codegen to make sure it generates expected assembly. That is available [here](https://github.com/xacrimon/tcvm).
Rollup of 7 pull requests
Successful merges:
- rust-lang/rust#144072 (update `Atomic*::from_ptr` and `Atomic*::as_ptr` docs)
- rust-lang/rust#144151 (`tests/ui/issues/`: The Issues Strike Back [1/N])
- rust-lang/rust#144300 (Clippy fixes for miropt-test-tools)
- rust-lang/rust#144399 (Add a ratchet for moving all standard library tests to separate packages)
- rust-lang/rust#144472 (str: Mark unstable `round_char_boundary` feature functions as const)
- rust-lang/rust#144503 (Various refactors to the codegen coordinator code (part 3))
- rust-lang/rust#144530 (coverage: Infer `instances_used` from `pgo_func_name_var_map`)
r? `@ghost`
`@rustbot` modify labels: rollup
Various refactors to the codegen coordinator code (part 3)
Continuing from https://github.com/rust-lang/rust/pull/144062 this removes an option without any known users, uses the object crate in favor of LLVM for getting the LTO bitcode and improves the coordinator channel handling.
Don't special-case llvm.* as nounwind
Certain LLVM intrinsics, such as `llvm.wasm.throw`, can unwind. Marking them as nounwind causes us to skip cleanup of locals and optimize out `catch_unwind` under inlining or when `llvm.wasm.throw` is used directly by user code.
The motivation for forcibly marking llvm.* as nounwind is no longer present: most intrinsics are linked as `extern "C"` or other non-unwinding ABIs, so we won't codegen `invoke` for them anyway.
Closesrust-lang/rust#132416.
`@rustbot` label +T-compiler +A-panic
No longer need `alloca`s for consuming `Result<!, i32>` and similar
In optimized builds GVN gets rid of these already, but in `opt-level=0` we actually make `alloca`s for this, which particularly impacts `?`-style things that use actually-only-one-variant types like this.
While doing so, rewrite `LocalAnalyzer::process_place` to be non-recursive, solving a 6+ year old FIXME.
r? codegen
Let `codegen_transmute_operand` just handle everything
When combined with rust-lang/rust#143720, this means `rvalue_creates_operand` can just return `true` for *every* `Rvalue`. (A future PR could consider removing it, though just letting it optimize out is fine for now.)
It's nicer anyway, IMHO, because it avoids needing the layout checks to be consistent in the two places, and thus is an overall reduction in code. Plus it's a more helpful building block when used in other places this way.
(TBH, it probably would have been better to have it this way the whole time, but I clearly didn't understand `rvalue_creates_operand` when I originally wrote rust-lang/rust#109843.)
Nobody seems to actually use this, while still adding some extra
complexity to the already rather complex codegen coordinator code.
It is also not supported by any backend other than the LLVM backend.
Don't emit two `assume`s in transmutes when one is a subset of the other
For example, transmuting between `bool` and `Ordering` doesn't need two `assume`s because one range is a superset of the other.
Multiple are still used for things like `char` <-> `NonZero<u32>`, which overlap but where neither fully contains the other.
Rollup of 15 pull requests
Successful merges:
- rust-lang/rust#143374 (Unquerify extern_mod_stmt_cnum.)
- rust-lang/rust#143838 (std: net: uefi: Add support to query connection data)
- rust-lang/rust#144014 (don't link to the nightly version of the Edition Guide in stable lints)
- rust-lang/rust#144094 (Ensure we codegen the main fn)
- rust-lang/rust#144218 (Use serde for target spec json deserialize)
- rust-lang/rust#144221 (generate elf symbol version in raw-dylib)
- rust-lang/rust#144240 (Add more test case to check if the false note related to sealed trait suppressed)
- rust-lang/rust#144247 (coretests/num: use ldexp instead of hard-coding a power of 2)
- rust-lang/rust#144276 (Use less HIR in check_private_in_public.)
- rust-lang/rust#144278 (add Rev::into_inner)
- rust-lang/rust#144317 (pass build.npm from bootstrap to tidy and use it for npm install)
- rust-lang/rust#144320 (rustdoc: avoid allocating a temp String for aliases in search index)
- rust-lang/rust#144334 (rustc_resolve: get rid of unused rustdoc::span_of_fragments_with_expansion)
- rust-lang/rust#144335 (Don't suggest assoc ty bound on non-angle-bracketed problematic assoc ty binding)
- rust-lang/rust#144358 (Stop using the old `validate_attr` logic for stability attributes)
r? `@ghost`
`@rustbot` modify labels: rollup
generate elf symbol version in raw-dylib
For link names like `aaa@bbb`, it generates a symbol named `aaa` and a version named `bbb`.
For link names like `aaa\0bbb`, `aaa@`@bbb`` or `aa@bb@cc`, it emits errors.
It adds a test that the executable is linked with glibc using raw-dylib.
cc rust-lang/rust#135694
Various refactors to the LTO handling code (part 2)
Continuing from https://github.com/rust-lang/rust/pull/143388 this removes a bit of dead code and moves the LTO symbol export calculation from individual backends to cg_ssa.
For example, transmuting between `bool` and `Ordering` doesn't need two `assume`s because one range is a superset of the other.
Multiple are still used for things like `char` <-> `NonZero<u32>`, which overlap but where neither fully contains the other.
When combined with 143720, this means `rvalue_creates_operand` can just return `true` for *every* `Rvalue`. (A future PR could consider removing it, though just letting it optimize out is fine for now.)
It's nicer anyway, IMHO, because it avoids needing the layout checks to be consistent in the two places, and thus is an overall reduction in code. Plus it's a more helpful building block when used in other places this way.
In optimized builds GVN gets rid of these already, but in `opt-level=0` we actually make `alloca`s for this, which particularly impacts `?`-style things that use actually-only-one-variant types like this.
Certain LLVM intrinsics, such as `llvm.wasm.throw`, can unwind. Marking
them as nounwind causes us to skip cleanup of locals and optimize out
`catch_unwind` under inlining or when `llvm.wasm.throw` is used directly
by user code.
The motivation for forcibly marking llvm.* as nounwind is no longer
present: most intrinsics are linked as `extern "C"` or other
non-unwinding ABIs, so we won't codegen `invoke` for them anyway.
gpu offload host code generation
r? ghost
This will generate most of the host side code to use llvm's offload feature.
The first PR will only handle automatic mem-transfers to and from the device.
So if a user calls a kernel, we will copy inputs back and forth, but we won't do the actual kernel launch.
Before merging, we will use LLVM's Info infrastructure to verify that the memcopies match what openmp offloa generates in C++. `LIBOMPTARGET_INFO=-1 ./my_rust_binary` should print that a memcpy to and later from the device is happening.
A follow-up PR will generate the actual device-side kernel which will then do computations on the GPU.
A third PR will implement manual host2device and device2host functionality, but the goal is to minimize cases where a user has to overwrite our default handling due to performance issues.
I'm trying to get a full MVP out first, so this just recognizes GPU functions based on magic names. The final frontend will obviously move this over to use proper macros, like I'm already doing it for the autodiff work.
This work will also be compatible with std::autodiff, so one can differentiate GPU kernels.
Tracking:
- https://github.com/rust-lang/rust/issues/131513