Extract some shared code from codegen backend target feature handling by RalfJung · Pull Request #140920 · rust-lang/rust (original) (raw)
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 andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Conversation64 Commits6 Checks18 Files changed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
[ Show hidden characters]({{ revealButtonHref }})
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 second commit also cleans up a bunch of unneeded complexity added in #135927.
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 featurexthat impliesfeatwe would not add-xto 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
xfromcfg(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 beforetcxso we can't use that... - Previously, if feature "a" implied "b" and "b" was unstable, then using
-Ctarget-feature=+awould also emit a warning aboutb. 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.
The last commit does some further cleanup:
- Get rid of RUSTC_SPECIAL_FEATURES. It was only needed for s390x "backchain", but since LLVM 19 that is always a regular target feature so we don't need this hack any more. The hack also has various unintended side-effects so we don't want to keep it. Fixes When should cfg(target_feature = "backchain") (s390x target feature) be enabled? #142412.
- Move RUSTC_SPECIFIC_FEATURES handling into the shared parse_rust_feature_flag helper so all consumers of
-Ctarget-featurethat only care about actual target features (and not "crt-static") have it. Previously, we actually setcfg(target_feature = "crt-static")twice: once in the backend target feature logic, and once specifically for that one feature. IIUC, some targets are meant to ignore-Ctarget-feature=+crt-static, it seems like before this PR that flag still incorrectly enabledcfg(target_feature = "crt-static")(but I didn't test this). - Move fixed_x18 handling together with retpoline handling.
- Forbid setting fixed_x18 as a regular target feature, even unstably. It must be set via the
-Zflag.
@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. :)
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 added the T-compiler
Relevant to the compiler team, which will review and decide on the PR/issue.
label
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.
This comment has been minimized.
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
This comment has been minimized.
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-featureflag to populatecfg(target_feature). That seems odd, since the-Ctarget-featureflag is used to populate the return value ofglobal_gcc_featureswhich controls the target features actually used by GCC. @GuillaumeGomez @antoyo is there a reasontarget_configignores-Ctarget-featurebutglobal_gcc_featuresdoes 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.
This comment has been minimized.
This comment has been minimized.
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.
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...
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.
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_ssatorustc_middleshould be left where it is. (E.g. you movedrustc_codegen_ssa/src/target_features.rstorustc_middle.) - Anything moved from
rustc_codegen_{llvm,gcc}torustc_middleshould instead be moved torustc_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.
github-actions bot pushed a commit to model-checking/verify-rust-std that referenced this pull request
…iaskrgr
Rollup of 9 pull requests
Successful merges:
- rust-lang#128425 (Make
missing_fragment_specifieran unconditional error) - rust-lang#135927 (retpoline and retpoline-external-thunk flags (target modifiers) to enable retpoline-related target features)
- rust-lang#140770 (add
extern "custom"functions) - rust-lang#142176 (tests: Split dont-shuffle-bswaps along opt-levels and arches)
- rust-lang#142248 (Add supported asm types for LoongArch32)
- rust-lang#142267 (assert more in release in
rustc_ast_lowering) - rust-lang#142274 (Update the stdarch submodule)
- rust-lang#142276 (Update dependencies in
library/Cargo.lock) - rust-lang#142308 (Upgrade
object,addr2line, andunwindingin the standard library)
Failed merges:
- rust-lang#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
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r=nnethercote,WaffleLapkin after conflict resolution
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.
@bors r=nnethercote,WaffleLapkin
📌 Commit 0c4b0f5 has been approved by nnethercote,WaffleLapkin
It is now in the queue for this repository.
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-review
Status: Awaiting review from the assignee but also interested parties.
labels
I've merged #142500 into this, there's no longer a reason to have them separate...
@bors r=nnethercote,WaffleLapkin
📌 Commit a50a3b8 has been approved by nnethercote,WaffleLapkin
It is now in the queue for this repository.
tgross35 added a commit to tgross35/rust that referenced this pull request
…n, r=nnethercote,WaffleLapkin
Extract some shared code from codegen backend target feature handling
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 second commit also cleans up a bunch of unneeded complexity added in rust-lang#135927.
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 featurexthat impliesfeatwe would not add-xto the backend target feature set. Now, we do. This fixes rust-lang#134792. - The logic that removes
xfromcfg(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 beforetcxso we can't use that... - Previously, if feature "a" implied "b" and "b" was unstable, then using
-Ctarget-feature=+awould also emit a warning aboutb. 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.
The last commit does some further cleanup:
- Get rid of RUSTC_SPECIAL_FEATURES. It was only needed for s390x "backchain", but since LLVM 19 that is always a regular target feature so we don't need this hack any more. The hack also has various unintended side-effects so we don't want to keep it. Fixes rust-lang#142412.
- Move RUSTC_SPECIFIC_FEATURES handling into the shared parse_rust_feature_flag helper so all consumers of
-Ctarget-featurethat only care about actual target features (and not "crt-static") have it. Previously, we actually setcfg(target_feature = "crt-static")twice: once in the backend target feature logic, and once specifically for that one feature. IIUC, some targets are meant to ignore-Ctarget-feature=+crt-static, it seems like before this PR that flag still incorrectly enabledcfg(target_feature = "crt-static")(but I didn't test this). - Move fixed_x18 handling together with retpoline handling.
- Forbid setting fixed_x18 as a regular target feature, even unstably. It must be set via the
-Zflag.
@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
bors added a commit that referenced this pull request
Rollup of 8 pull requests
Successful merges:
- #138291 (rewrite
optimizeattribute to use new attribute parsing infrastructure) - #140920 (Extract some shared code from codegen backend target feature handling)
- #141990 (Implement send_signal for unix child processes)
- #142597 (error on calls to ABIs that cannot be called)
- #142668 (vec_deque/fmt/vec tests: remove static mut)
- #142687 (Reduce uses of
hir_crate.) - #142699 (Update books)
- #142714 (add comment to
src/bootstrap/build.rs)
r? @ghost
@rustbot modify labels: rollup
bors added a commit that referenced this pull request
Rollup of 8 pull requests
Successful merges:
- #138291 (rewrite
optimizeattribute to use new attribute parsing infrastructure) - #140920 (Extract some shared code from codegen backend target feature handling)
- #141990 (Implement send_signal for unix child processes)
- #142668 (vec_deque/fmt/vec tests: remove static mut)
- #142687 (Reduce uses of
hir_crate.) - #142699 (Update books)
- #142714 (add comment to
src/bootstrap/build.rs) - #142753 (Update library dependencies)
r? @ghost
@rustbot modify labels: rollup
rust-timer added a commit that referenced this pull request
Rollup merge of #140920 - RalfJung:target-feature-unification, r=nnethercote,WaffleLapkin
Extract some shared code from codegen backend target feature handling
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 second commit also cleans up a bunch of unneeded complexity added in #135927.
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 featurexthat impliesfeatwe would not add-xto the backend target feature set. Now, we do. This fixes #134792. - The logic that removes
xfromcfg(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 beforetcxso we can't use that... - Previously, if feature "a" implied "b" and "b" was unstable, then using
-Ctarget-feature=+awould also emit a warning aboutb. 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.
The last commit does some further cleanup:
- Get rid of RUSTC_SPECIAL_FEATURES. It was only needed for s390x "backchain", but since LLVM 19 that is always a regular target feature so we don't need this hack any more. The hack also has various unintended side-effects so we don't want to keep it. Fixes #142412.
- Move RUSTC_SPECIFIC_FEATURES handling into the shared parse_rust_feature_flag helper so all consumers of
-Ctarget-featurethat only care about actual target features (and not "crt-static") have it. Previously, we actually setcfg(target_feature = "crt-static")twice: once in the backend target feature logic, and once specifically for that one feature. IIUC, some targets are meant to ignore-Ctarget-feature=+crt-static, it seems like before this PR that flag still incorrectly enabledcfg(target_feature = "crt-static")(but I didn't test this). - Move fixed_x18 handling together with retpoline handling.
- Forbid setting fixed_x18 as a regular target feature, even unstably. It must be set via the
-Zflag.
@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
RalfJung deleted the target-feature-unification branch
antoyo pushed a commit to rust-lang/rustc_codegen_gcc that referenced this pull request
Labels
Area: Attributes (`#[…]`, `#![…]`)
Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.
Area: Rustdoc JSON backend
Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Relevant to the compiler team, which will review and decide on the PR/issue.
