Skip to content

Conversation

@x17jiri
Copy link
Contributor

@x17jiri x17jiri commented Jan 26, 2024

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:

  • added a new cold_path() intrinsic
  • likely() and unlikely() changed to regular functions implemented using cold_path()

@rustbot
Copy link
Collaborator

rustbot commented Jan 26, 2024

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 (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jan 26, 2024
@rustbot
Copy link
Collaborator

rustbot commented Jan 26, 2024

This PR changes MIR

cc @oli-obk, @RalfJung, @JakobDegen, @davidtwco, @celinval, @vakaras

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

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

Comment on lines 424 to 421
True, // condition is probably true
False, // condition is probably false
Unpredictable,
Copy link
Member

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.

Copy link
Contributor Author

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 }),
Copy link
Member

Choose a reason for hiding this comment

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

Why 2000?

Copy link
Contributor Author

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)
}
Copy link
Member

@RalfJung RalfJung Jan 26, 2024

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(..)) => {}
Copy link
Member

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(_) => {}
?

Copy link
Contributor Author

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

Copy link
Member

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.

Copy link
Contributor Author

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

@rustbot
Copy link
Collaborator

rustbot commented Jan 26, 2024

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

}
} else {
ExpectKind::None
};
Copy link
Contributor

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>?

Copy link
Contributor Author

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()
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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),
Copy link
Contributor

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 Operand is an unused local?
  • DeadStoreElimination: when the operand is a local that is never read again?
  • SimplifyConstCondition: when the operand if a constant?

Copy link
Contributor Author

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
)]
Copy link
Contributor

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.

Copy link
Contributor Author

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
)]

Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@cjgillot cjgillot 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-review Status: Awaiting review from the assignee but also interested parties. labels Jan 27, 2024
@x17jiri
Copy link
Contributor Author

x17jiri commented Jan 29, 2024

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 29, 2024
@rustbot rustbot added has-merge-commits PR has merge commits, merge with caution. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 7, 2024
@rustbot
Copy link
Collaborator

rustbot commented Feb 7, 2024

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:

$ # rebase
$ git rebase -i master
$ # delete any merge commits in the editor that appears
$ git push --force-with-lease

The following commits are merge commits:

@x17jiri x17jiri force-pushed the likely_unlikely_fix branch from 12a1bb3 to 2d49c41 Compare February 7, 2024 14:35
@rustbot rustbot removed has-merge-commits PR has merge commits, merge with caution. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 7, 2024
@rust-log-analyzer

This comment has been minimized.

@x17jiri
Copy link
Contributor Author

x17jiri commented Feb 8, 2024

@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

Copy link
Member

@Noratrieb Noratrieb left a 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)

Comment on lines 416 to 421
/// condition is probably true
True,

/// condition is probably false
False,

/// condition is unpredictable by hardware
Unpredictable,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// 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,

@bors
Copy link
Collaborator

bors commented Feb 16, 2024

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

@x17jiri x17jiri force-pushed the likely_unlikely_fix branch from e4cc72b to d31b045 Compare February 17, 2024 07:36
@rust-log-analyzer

This comment has been minimized.

@klensy
Copy link
Contributor

klensy commented Nov 18, 2024

I think this fix will be nice to have in relnotes?

@RalfJung
Copy link
Member

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.

@Kobzol
Copy link
Member

Kobzol commented Nov 18, 2024

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.

@RalfJung
Copy link
Member

Relnotes generally don't mention changes to nightly features either. They document what changed with a stable release.

@klensy
Copy link
Contributor

klensy commented Nov 18, 2024

Someone used them to tune some perf and now they see that this actually only started working as expected, so less surprises.

@RalfJung
Copy link
Member

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.

@Kobzol
Copy link
Member

Kobzol commented Nov 18, 2024

Right, I meant the detailed release notes, which also mention internal changes and interesting pieces of information like this, not the main blog post.

@RalfJung
Copy link
Member

How often do these detailed release notes talk about nightly features? In my understand, not very often. But maybe I misremember.

@klensy
Copy link
Contributor

klensy commented Nov 18, 2024

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.

@RalfJung
Copy link
Member

That would announce such changes on average 9 weeks too late. I don't think it makes a lot of sense.

@klensy
Copy link
Contributor

klensy commented Nov 18, 2024

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?

@RalfJung
Copy link
Member

Such updates can and often are posted to the tracking issues, and we expect interested users to follow those.

With release cycle of 6 weeks this will be only <= 6 weeks if placed in nearest relnotes.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged-by-bors This PR was explicitly merged by bors. perf-regression Performance regression. perf-regression-triaged The performance regression has been triaged. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.