cg_llvm: Use fewer FFI calls to check the target CPU's features - #163143
Conversation
|
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
cg_llvm: Use fewer FFI calls to check the target CPU's features
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (e047fe3): comparison URL. Overall result: no relevant changes - no action neededBenchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up. @rustbot label: -S-waiting-on-perf -perf-regression Instruction countThis perf run didn't have relevant results for this metric. Max RSS (memory usage)Results (secondary 2.7%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (primary 2.8%, secondary 0.1%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeResults (primary 0.0%, secondary 0.0%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Bootstrap: 487.826s -> 488.235s (0.08%) |
|
No measurable perf effect, but I think this still makes sense on its own, as the Rust-side and C++-side code are both simpler. |
811b1bd to
acd485c
Compare
| // `has_feature` is moderately expensive. On targets with many | ||
| // features (e.g. x86) these calls take a non-trivial fraction of runtime | ||
| // when compiling very small programs. |
There was a problem hiding this comment.
I believe this comment was made obsolete by llvm/llvm-project#130936, which is included in LLVM 21.
|
r? @davidtwco rustbot has assigned @davidtwco. Use Why was this reviewer chosen?The reviewer was selected based on:
|
acd485c to
bdc4b77
Compare
| pub(crate) fn has_features(&self, features: llvm_util::LLVMFeature<'_>) -> bool { | ||
| // Convert to a feature string expected by LLVM's `SubtargetFeatures`. | ||
| // All of the required LLVM features must be enabled. | ||
| let features = features.into_iter().flat_map(|feat| ["+", feat, ","]).collect::<String>(); |
There was a problem hiding this comment.
I assume there's no issues with the trailing comma here at the end?
There was a problem hiding this comment.
Yeah, the split-on-commas in LLVM's SubtargetFeatures::Split sets KeepEmpty=false, so the empty segment after the trailing comma is safely discarded.
I added a comment to mention this.
The existing code makes a separate FFI call to `MCSubtargetInfo::checkFeatures` for each feature-dependency of the feature being checked, and also performs string-manipulation on the C++ side to add a leading '+' to each feature name. What we can do instead is prepare a single string on the Rust side in the form `"+foo,+bar,+baz,"` for each Rust target feature, and pass that string to LLVM. LLVM already knows how to check that all of the listed features are present. (The trailing comma is not a problem, because `SubtargetFeatures::Split` will automatically discard empty substrings after splitting on commas.)
bdc4b77 to
733daee
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
Added a comment about the trailing comma being OK. @bors r=davidtwco |
…uwer Rollup of 14 pull requests Successful merges: - #162976 (fix quadratic naming of duplicate sidebar links) - #161275 (Refactor `core::cmp::{smallest, largest}` & add `mir-opt` test) - #163143 (cg_llvm: Use fewer FFI calls to check the target CPU's features) - #163188 (Adjust for Arm64EC name mangling when checking for exported symbols) - #163211 (`rustc_builtin_macros` cleanup, part 6) - #161386 (Don't merge distinct impl candidates) - #162942 (Remove `StashKey::AssociatedTypeSuggestion`) - #163096 (Don't suggest `std::` rustfix paths in `#![no_std]` crates) - #163110 (Mark `std::os::wasip2` with correct doc-cfgs, mark as unstable) - #163185 (properly decrement available_depth on cycles and provisional cache hits) - #163214 (revert r14 register names for arm) - #163226 (miri subtree update) - #163228 (Add regression test for trait predicate with escaping bounds) - #163234 (`rustc_dump_symbol_name`: add demangling information as a note instead)
Rollup merge of #163143 - Zalathar:check-features, r=davidtwco cg_llvm: Use fewer FFI calls to check the target CPU's features The existing code makes a separate FFI call to `MCSubtargetInfo::checkFeatures` for each feature-dependency of the feature being checked, and also performs string-manipulation on the C++ side to add a leading `+` to each feature name. What we can do instead is prepare a single string on the Rust side in the form `"+foo,+bar,+baz,"` for each Rust target feature, and pass that to LLVM as a pointer/length string. LLVM already knows how to check that all of the listed features are present. This change makes the code simpler overall. All of the string manipulation now takes place either in Rust code or in LLVM itself, and not in our C++ wrapper. There should be no change to compiler output.
…uwer Rollup of 14 pull requests Successful merges: - rust-lang/rust#162976 (fix quadratic naming of duplicate sidebar links) - rust-lang/rust#161275 (Refactor `core::cmp::{smallest, largest}` & add `mir-opt` test) - rust-lang/rust#163143 (cg_llvm: Use fewer FFI calls to check the target CPU's features) - rust-lang/rust#163188 (Adjust for Arm64EC name mangling when checking for exported symbols) - rust-lang/rust#163211 (`rustc_builtin_macros` cleanup, part 6) - rust-lang/rust#161386 (Don't merge distinct impl candidates) - rust-lang/rust#162942 (Remove `StashKey::AssociatedTypeSuggestion`) - rust-lang/rust#163096 (Don't suggest `std::` rustfix paths in `#![no_std]` crates) - rust-lang/rust#163110 (Mark `std::os::wasip2` with correct doc-cfgs, mark as unstable) - rust-lang/rust#163185 (properly decrement available_depth on cycles and provisional cache hits) - rust-lang/rust#163214 (revert r14 register names for arm) - rust-lang/rust#163226 (miri subtree update) - rust-lang/rust#163228 (Add regression test for trait predicate with escaping bounds) - rust-lang/rust#163234 (`rustc_dump_symbol_name`: add demangling information as a note instead)
|
perf triage: Looks like this caused a small compile time regression for CTFE stress test in #163244. This can also be just noise (well, it definitely is at least partially), but some part of the increase persisted. Does that make sense for this PR? Do we know where this could come from? |
|
This PR had an earlier perf run at #163143 (comment) that gave sub-threshold improvement in ctfe-stress, so it would be weird for that to suddenly turn into a measurable regression. In terms of the actual changes, it would also be surprising for this PR to only affect one benchmark, as I believe it’s touching code that only runs once per session and doesn’t scale with input size. |
|
Yea, this is probably just noise. As I went through the rest of the PRs in the rollup, I encountered the same regression again on ~4 of them. |
The existing code makes a separate FFI call to
MCSubtargetInfo::checkFeaturesfor each feature-dependency of the feature being checked, and also performs string-manipulation on the C++ side to add a leading+to each feature name.What we can do instead is prepare a single string on the Rust side in the form
"+foo,+bar,+baz,"for each Rust target feature, and pass that to LLVM as a pointer/length string. LLVM already knows how to check that all of the listed features are present.This change makes the code simpler overall. All of the string manipulation now takes place either in Rust code or in LLVM itself, and not in our C++ wrapper.
There should be no change to compiler output.