-
Notifications
You must be signed in to change notification settings - Fork 14k
Likely unlikely fix #120370
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
Likely unlikely fix #120370
Conversation
|
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @cjgillot (or someone else) soon. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
|
This PR changes MIR cc @oli-obk, @RalfJung, @JakobDegen, @davidtwco, @celinval, @vakaras Some changes occurred in compiler/rustc_codegen_gcc Some changes occurred in compiler/rustc_codegen_cranelift cc @bjorn3 Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri This PR changes Stable MIR cc @oli-obk, @celinval, @spastorino, @ouz-a Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt |
| True, // condition is probably true | ||
| False, // condition is probably false | ||
| Unpredictable, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make these doc comments, and also explain the last variant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
| // 'then' branch weight | ||
| self.cx.const_u32(if expect == ExpectKind::True { 2000 } else { 1 }), | ||
| // 'else' branch weight | ||
| self.cx.const_u32(if expect == ExpectKind::True { 1 } else { 2000 }), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why 2000?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what Clang emits. I will add a comment
| } | ||
| sym::unlikely => { | ||
| self.expect(args[0].immediate(), false) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are similar match arms here that can be cleaned up now.
EDIT: Ah, you already did. :)
| let op_val = self.codegen_operand(bx, op); | ||
| bx.assume(op_val.immediate()); | ||
| } | ||
| mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::Expect(..)) => {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please also add this at
| NonDivergingIntrinsic::Assume(_) => {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Normally, only the LLVM backend is build, right? Because I didn't get any compile time errors in GCC or Cranelift
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
./x.py check should check all backends. ./x.py build only builds backends other than LLVM if you tell the build system to with the rust.codegen-backends option in config.toml.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I updated this and one more match in Cranelift
|
Some changes occurred in src/tools/clippy cc @rust-lang/clippy |
| } | ||
| } else { | ||
| ExpectKind::None | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: could this be a Option<mir::ExpectKind>?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Updated
| let lltrue = helper.llbb_with_cleanup(self, target); | ||
| let llfalse = helper.llbb_with_cleanup(self, targets.otherwise()); | ||
| if switch_ty == bx.tcx().types.bool { | ||
| let expect = if let Some(x) = self.mir[bb].statements.last() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the Expect is not the last statement? This could happen because of MIR opts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could it also be moved to a different BB? Or is that something worth considering?
I was also thinking it could be useful to emit a warning if there is Expect which cannot be paired with a branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to handle expect anywhere in a BB
| Assume(Operand<'tcx>), | ||
|
|
||
| // Denotes a call to the intrinsic functions `likely`, `unlikely` and `unpredictable`. | ||
| Expect(Operand<'tcx>, ExpectKind), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For MIR opts:
- SimplifyLocals: should this statement be removed when
Operandis an unused local? - DeadStoreElimination: when the operand is a local that is never read again?
- SimplifyConstCondition: when the operand if a constant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opt passes updated
| HashStable, | ||
| TypeFoldable, | ||
| TypeVisitable | ||
| )] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: please split the derives in 2 lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean like this?
#[derive(
Clone, TyEncodable, TyDecodable, Debug, PartialEq,
Hash, HashStable, TypeFoldable, TypeVisitable
)]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean:
#[derive(Clone, TyEncodable, TyDecodable, Debug, PartialEq)]
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
To avoid rustfmt using a dozen lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
@rustbot ready |
|
There are merge commits (commits with multiple parents) in your changes. We have a no merge policy so these commits will need to be removed for this pull request to be merged. You can start a rebase with the following commands: The following commits are merge commits: |
12a1bb3 to
2d49c41
Compare
This comment has been minimized.
This comment has been minimized.
|
@cjgillot I found I introduced a bug in simplify_branches.rs 🤦 It should be fixed now. Anyway, the number of affected files is getting quite big. If there is anything I can do to make the review easier, please let me know |
Noratrieb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small style nit (in case you're touching this code again, if you aren't it's fine to not implement it)
| /// condition is probably true | ||
| True, | ||
|
|
||
| /// condition is probably false | ||
| False, | ||
|
|
||
| /// condition is unpredictable by hardware | ||
| Unpredictable, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /// condition is probably true | |
| True, | |
| /// condition is probably false | |
| False, | |
| /// condition is unpredictable by hardware | |
| Unpredictable, | |
| /// Condition is probably true | |
| True, | |
| /// Condition is probably false | |
| False, | |
| /// Condition is unpredictable by hardware | |
| Unpredictable, |
|
☔ The latest upstream changes (presumably #120500) made this pull request unmergeable. Please resolve the merge conflicts. |
e4cc72b to
d31b045
Compare
This comment has been minimized.
This comment has been minimized.
|
I think this fix will be nice to have in relnotes? |
|
This is completely internal to the standard library implementation. Why would the relnotes mention it, and what would they say? We typically only document things that users need to be aware of. "Some functions are now hopefully a bit faster" doesn't go into relnotes. |
|
If the likely/unlikely intrinsics were broken before, and now they are fixed, then that information could be quite important to some users. Both to let them know that they can now again rely on these intrinsics doing something, and also to let them know that on previous versions of Rust it probably did nothing. Assuming that this PR is about the unstable likely/unlikely intrinsics that are available to nightly users, and thus it's not completely internal to the standard library. |
|
Relnotes generally don't mention changes to nightly features either. They document what changed with a stable release. |
|
Someone used them to tune some perf and now they see that this actually only started working as expected, so less surprises. |
|
Given that this is on nightly now, and relnotes will be put out in ~7 weeks, it also wouldn't make a lot of sense to attach this to the Rust 1.84 relnotes. |
|
Right, I meant the detailed release notes, which also mention internal changes and interesting pieces of information like this, not the main blog post. |
|
How often do these detailed release notes talk about nightly features? In my understand, not very often. But maybe I misremember. |
|
Personally, i think that release notes also should contain block for nightly changes, i.e. new added\removed unstable features to help users discover them, but this not related to current PR. |
|
That would announce such changes on average 9 weeks too late. I don't think it makes a lot of sense. |
With release cycle of 6 weeks this will be only <= 6 weeks if placed in nearest relnotes. How currently users can discover new features (before stabilization), excluding ones that manually track this repo? This gives lot less possible testing for that features. Or i miss something? |
|
Such updates can and often are posted to the tracking issues, and we expect interested users to follow those.
That would be really strange, since the codebase that is released there doesn't contain these changes. If we want to do something like this IMO it should be a completely separate "nightly feature release notes" announcement, not part of the regular release notes. It doesn't even have to use the same 6 week cadence. |
RFC 1131 ( #26179 ) added likely/unlikely intrinsics, but they have been broken for a while: #96276 , #96275 , #88767 . This PR tries to fix them.
Changes:
cold_path()intrinsiclikely()andunlikely()changed to regular functions implemented usingcold_path()