Skip to content

Extract some shared code from codegen backend target feature handling #140920

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

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

RalfJung
Copy link
Member

@RalfJung RalfJung commented May 11, 2025

There's a bunch of code duplication between the GCC and LLVM backends in target feature handling. This moves that into new shared helper functions in rustc_codegen_ssa.

The first two commits should be purely refactoring. I am fairly sure the LLVM-side behavior stays the same; if the GCC side deliberately diverges from this then I may have missed that. I did account for one divergence, which I do not know is deliberate or not: GCC does not seem to use the -Ctarget-feature flag to populate cfg(target_feature). That seems odd, since the -Ctarget-feature flag is used to populate the return value of global_gcc_features which controls the target features actually used by GCC. @GuillaumeGomez @antoyo is there a reason target_config ignores -Ctarget-feature but global_gcc_features does not?

The third commit extracts some shared logic out of the functions that populate cfg(target_feature) and the backend target feature set, respectively. This one actually has some slight functional changes:

  • Before, with -Ctarget-feature=-feat, if there is some other feature x that implies feat we would not add -x to the backend target feature set. Now, we do. This fixes Target feature implications for negative features are handled inconsistently between codegen and cfg(target_feature) #134792.
  • The logic that removes x from cfg(target_feature) in this case also changed a bit, avoiding a large number of calls to the (uncached) sess.target.implied_target_features (if there were a large number of positive features listed before a negative feature) but instead constructing a full inverse implication map when encountering the first negative feature. Ideally this would be done with queries but the backend target feature logic runs before tcx so we can't use that...
  • Previously, if feature "a" implied "b" and "b" was unstable, then using -Ctarget-feature=+a would also emit a warning about b. I had to remove this since when accounting for negative implications, this emits a ton of warnings in a bunch of existing tests... I assume this was unintentional anyway.

The fourth commit increases consistency of the GCC backend with the LLVM backend.

@bjorn3 I did not touch the cranelift backend here, since AFAIK it doesn't really support target features. But if you ever do, please use the new helpers. :)

Cc @workingjubilee

@rustbot
Copy link
Collaborator

rustbot commented May 11, 2025

r? @compiler-errors

rustbot has assigned @compiler-errors.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added A-attributes Area: Attributes (`#[…]`, `#![…]`) S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 11, 2025
@rustbot
Copy link
Collaborator

rustbot commented May 11, 2025

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

Some changes occurred in compiler/rustc_codegen_ssa/src/codegen_attrs.rs

cc @jdonszelmann

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label May 11, 2025
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a lot more logic in this file that seems like it should be shared across backends (almost all of fn codegen_fn_attrs), but I shied away from the huge refactor that would have been.

@rust-log-analyzer

This comment has been minimized.

@RalfJung RalfJung force-pushed the target-feature-unification branch from 8175ae7 to b0607f4 Compare May 11, 2025 10:07
@RalfJung
Copy link
Member Author

Turns out properly adding negative implications to the target_features we set for LLVM tends to add a lot of target features -- we have some quite extensive implication chains. Is that a problem? Cc @nikic @taiki-e

@rust-log-analyzer

This comment has been minimized.

@antoyo
Copy link
Contributor

antoyo commented May 11, 2025

if the GCC side deliberately diverges from this then I may have missed that. I did account for one divergence, which I do not know is deliberate or not: GCC does not seem to use the -Ctarget-feature flag to populate cfg(target_feature). That seems odd, since the -Ctarget-feature flag is used to populate the return value of global_gcc_features which controls the target features actually used by GCC. @GuillaumeGomez @antoyo is there a reason target_config ignores -Ctarget-feature but global_gcc_features does not?

There is no reason for that. I probably missed some stuff when I implemented this.
I'd be happy to have the same behavior as LLVM here.

@RalfJung RalfJung force-pushed the target-feature-unification branch from b0607f4 to e3f260f Compare May 11, 2025 10:51
@rust-log-analyzer

This comment has been minimized.

@RalfJung RalfJung force-pushed the target-feature-unification branch from e3f260f to e973da1 Compare May 11, 2025 11:28
@rust-log-analyzer

This comment has been minimized.

@RalfJung RalfJung force-pushed the target-feature-unification branch 2 times, most recently from c46d167 to 891f35e Compare May 11, 2025 12:09
@nikic
Copy link
Contributor

nikic commented May 11, 2025

Turns out properly adding negative implications to the target_features we set for LLVM tends to add a lot of target features -- we have some quite extensive implication chains. Is that a problem? Cc @nikic @taiki-e

Anything in particular you're concerned about? But generally, no, it shouldn't be a problem.

@RalfJung
Copy link
Member Author

I can imagine two concerns:

  • So many attributes cause some sort of perf issue?
  • We actually have more implications in rustc than LLVM recognizes, so now we're disabling more things than before. This is probably a bugfix but still it'd be good to know if there is such a case...

@bors
Copy link
Collaborator

bors commented May 19, 2025

☔ The latest upstream changes (presumably #141238) made this pull request unmergeable. Please resolve the merge conflicts.

@RalfJung RalfJung force-pushed the target-feature-unification branch from 891f35e to 9fc38d1 Compare May 19, 2025 11:24
@compiler-errors
Copy link
Member

r? compiler

@bors
Copy link
Collaborator

bors commented May 23, 2025

☔ The latest upstream changes (presumably #135160) made this pull request unmergeable. Please resolve the merge conflicts.

@RalfJung RalfJung force-pushed the target-feature-unification branch from 9fc38d1 to 1a58c68 Compare May 23, 2025 06:20
@RalfJung
Copy link
Member Author

RalfJung commented May 23, 2025

This is somewhat bitrotty... and to my knowledge rather outside your typical review areas, @nnethercote.

@workingjubilee @bjorn3 @nikic maybe one of you could take this?

@RalfJung RalfJung force-pushed the target-feature-unification branch from 1a58c68 to 8915a90 Compare May 23, 2025 06:31
@nnethercote
Copy link
Contributor

There's a bunch of code duplication between the GCC and LLVM backends in target feature handling. This moves that into new shared helper functions.

That sounds reasonable.

I placed those in rustc_middle since I couldn't think of a better place to put them... I'm open for suggestions. :)

I think you've gotten off-track here.

rustc_codegen_ssa is the logical spot for stuff shared between backends, because all backends depend on it. The doc comment at the top of its lib.rs says //! This crate contains codegen code that is used by all codegen backends (LLVM and others).

Also, rustc_middle is already too big and shouldn't get anything added to it that doesn't need to be.

Here's part of the crate graph. You can see how rustc_codegen_llvm depends directly on rustc_codegen_ssa, while rustc_middle is several layers further down. rustc_codegen_gcc isn't included, I think because it's in a sub-repo, but it would sit next to rustc_codegen_llvm and also depend directly on rustc_codegen_ssa.

Screenshot from 2025-05-29 19-08-49

Crate graph generated with:

cargo +nightly depgraph --all-deps --dedup-transitive-deps --workspace-only > ~/graph.dot;
dot -Tpng ~/graph.dot > ~/graph.png

Based on this, I think significant parts of this PR are unnecessary:

  • Anything moved from rustc_codegen_ssa to rustc_middle should be left where it is. (E.g. you moved rustc_codegen_ssa/src/target_features.rs to rustc_middle.)
  • Anything moved from rustc_codegen_{llvm,gcc} to rustc_middle should instead be moved to rustc_codegen_ssa.

This will significantly reduce the size of the PR, e.g. the entire first commit would disappear, along with part of the third commit.

@RalfJung
Copy link
Member Author

I added a reference to #142412 since I think RUSTC_SPECIAL_FEATURES needs to die a fiery death... but that's for a future PR. This one should be good to go then, thanks all. :)

@bors r=nnethercote,WaffleLapkin

@bors
Copy link
Collaborator

bors commented Jun 12, 2025

📌 Commit e790e54 has been approved by nnethercote,WaffleLapkin

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 12, 2025
@workingjubilee
Copy link
Member

Thank you for doing this cleanup, and thank you @nnethercote and @WaffleLapkin for covering the review!

bors added a commit that referenced this pull request Jun 13, 2025
Rollup of 9 pull requests

Successful merges:

 - #128425 (Make `missing_fragment_specifier` an unconditional error)
 - #135927 (retpoline and retpoline-external-thunk flags (target modifiers) to enable retpoline-related target features)
 - #140770 (add `extern "custom"` functions)
 - #142176 (tests: Split dont-shuffle-bswaps along opt-levels and arches)
 - #142248 (Add supported asm types for LoongArch32)
 - #142267 (assert more in release in `rustc_ast_lowering`)
 - #142274 (Update the stdarch submodule)
 - #142276 (Update dependencies in `library/Cargo.lock`)
 - #142308 (Upgrade `object`, `addr2line`, and `unwinding` in the standard library)

Failed merges:

 - #140920 (Extract some shared code from codegen backend target feature handling)

r? `@ghost`
`@rustbot` modify labels: rollup

try-job: aarch64-apple
try-job: x86_64-msvc-1
try-job: x86_64-gnu
try-job: dist-i586-gnu-i586-i686-musl
try-job: test-various
bors added a commit that referenced this pull request Jun 13, 2025
Rollup of 9 pull requests

Successful merges:

 - #128425 (Make `missing_fragment_specifier` an unconditional error)
 - #135927 (retpoline and retpoline-external-thunk flags (target modifiers) to enable retpoline-related target features)
 - #140770 (add `extern "custom"` functions)
 - #142176 (tests: Split dont-shuffle-bswaps along opt-levels and arches)
 - #142248 (Add supported asm types for LoongArch32)
 - #142267 (assert more in release in `rustc_ast_lowering`)
 - #142274 (Update the stdarch submodule)
 - #142276 (Update dependencies in `library/Cargo.lock`)
 - #142308 (Upgrade `object`, `addr2line`, and `unwinding` in the standard library)

Failed merges:

 - #140920 (Extract some shared code from codegen backend target feature handling)

r? `@ghost`
`@rustbot` modify labels: rollup

try-job: aarch64-apple
try-job: x86_64-msvc-1
try-job: x86_64-gnu
try-job: dist-i586-gnu-i586-i686-musl
try-job: test-various
@bors
Copy link
Collaborator

bors commented Jun 13, 2025

☔ The latest upstream changes (presumably #142443) made this pull request unmergeable. Please resolve the merge conflicts.

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Jun 13, 2025
@RalfJung
Copy link
Member Author

RalfJung commented Jun 13, 2025

I'm afraid this will need another review... the conflicts with #135927 were enormous. Also, that PR added some spaghetti to target_features that I found easier to remove during conflict resolution, than to incorporate into this PR. So this PR is now also a cleanup of retpoline flag handling, removing a bunch of unneeded complexity. Only the 2nd commit ("move -Ctarget-feature handling into shared code") saw major changes.

@rust-log-analyzer

This comment has been minimized.

@RalfJung RalfJung force-pushed the target-feature-unification branch 4 times, most recently from f6affd7 to 83872bf Compare June 13, 2025 22:37
@rust-log-analyzer

This comment has been minimized.

@RalfJung RalfJung force-pushed the target-feature-unification branch 2 times, most recently from 147d25a to 9c1898b Compare June 13, 2025 22:54
@rust-log-analyzer

This comment has been minimized.

RalfJung added 4 commits June 14, 2025 01:21
This does change the logic a bit: previously, we didn't forward reverse
implications of negated features to the backend, instead relying on the backend
to handle the implication itself.
@RalfJung RalfJung force-pushed the target-feature-unification branch from 9c1898b to b471447 Compare June 13, 2025 23:21
@rustbot rustbot added the A-rustdoc-json Area: Rustdoc JSON backend label Jun 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-rustdoc-json Area: Rustdoc JSON backend S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Target feature implications for negative features are handled inconsistently between codegen and cfg(target_feature)