Skip to content
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

Optimise fast path of checked_ops with unlikely #73938

Merged
merged 1 commit into from
Jul 2, 2020

Conversation

nbdd0121
Copy link
Contributor

@nbdd0121 nbdd0121 commented Jul 1, 2020

This PR marks paths returning None in checked_ops as unlikely to improvde codegen.

Fixes #73731

@LeSeulArtichaut
Copy link
Contributor

r? @nagisa

@leonardo-m
Copy link

Do you have unit tests that enforce that the resulting asm contains the correct happy path?

@nbdd0121
Copy link
Contributor Author

nbdd0121 commented Jul 1, 2020

Do you have unit tests that enforce that the resulting asm contains the correct happy path?

The most rustc could do is to generate llvm.expect calls, and it is entirely up to LLVM to make sure that fast path is fast. I don't see a way we could have an unit test for that.

@leonardo-m
Copy link

leonardo-m commented Jul 1, 2020

rustc is a compiler, and a compiler must have ways to verity what kind of asm it generates.

If you change something in the compiler with the purpose of changing the resulting asm happy path, and you can't be sure it produces the desired result, what's the point in changing the compiler? Probably I am missing something.

(One thing I'm missing: you're chanting the std lib, not the compiler)

@nbdd0121
Copy link
Contributor Author

nbdd0121 commented Jul 1, 2020

rustc is a compiler, and a compiler must have ways to verity what kind of asm it generates.

rustc lowers Rust code to LLVM IR and let LLVM generates the assembly. Rust is not pinned to any particular version of LLVM so the assembly it generates may and will change over time. The most we could do is to ensure that llvm.expects call is indeed generated and all assembly-level optimisation is taken care by LLVM. That check already exists in src/test/codegen/intrinsics/likely.rs.

If you change something in the compiler with the purpose of changing the resulting asm happy path, and you can't be sure it produces the desired result, what's the point in changing the compiler? Probably I am missing something.

The change made here is not in the compiler, but the standard library (libcore to be precise). Furthermore, the change made here hints LLVM to prefer the fast path, but there is no guarantee that LLVM will take advantage of that.

@nagisa
Copy link
Member

nagisa commented Jul 2, 2020

@bors r+

@bors
Copy link
Contributor

bors commented Jul 2, 2020

📌 Commit 86d8644 has been approved by nagisa

@bors bors added the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Jul 2, 2020
bors added a commit to rust-lang-ci/rust that referenced this pull request Jul 2, 2020
…arth

Rollup of 10 pull requests

Successful merges:

 - rust-lang#73414 (Implement `slice_strip` feature)
 - rust-lang#73564 (linker: Create GNU_EH_FRAME header by default when producing ELFs)
 - rust-lang#73622 (Deny unsafe ops in unsafe fns in libcore)
 - rust-lang#73684 (add spans to injected coverage counters, extract with CoverageData query)
 - rust-lang#73812 (ast_pretty: Pass some token streams and trees by reference)
 - rust-lang#73853 (Add newline to rustc MultiSpan docs)
 - rust-lang#73883 (Compile rustdoc less often.)
 - rust-lang#73885 (Fix wasm32 being broken due to a NodeJS version bump)
 - rust-lang#73903 (Changes required for rustc/cargo to build for iOS targets)
 - rust-lang#73938 (Optimise fast path of checked_ops with `unlikely`)

Failed merges:

r? @ghost
@@ -745,7 +760,7 @@ $EndFeature, "
#[inline]
pub const fn checked_add(self, rhs: Self) -> Option<Self> {
let (a, b) = self.overflowing_add(rhs);
if b {None} else {Some(a)}
if unlikely!(b) {None} else {Some(a)}
Copy link
Contributor

Choose a reason for hiding this comment

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

Will it have the same effect by flipping the case?

if !b { Some(a) } else { None }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Rearranging the code gives no hint to LLVM that one branch has more weight than another.

Copy link
Contributor

Choose a reason for hiding this comment

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

I tried it. The code is better for only this method alone, not at callsite. But at callsite, things are not improved.

@bors bors merged commit 4f536f2 into rust-lang:master Jul 2, 2020
@leonardo-m
Copy link

I tried it. The code is better for only this method alone, not at callsite. But at callsite, things are not improved.

Yes, that's the same thing you can infer from the asm I posted here:
#73731

That's why I have asked for some kind of unittests that this change actually does something useful...

@nbdd0121
Copy link
Contributor Author

nbdd0121 commented Jul 2, 2020

I tried it. The code is better for only this method alone, not at callsite. But at callsite, things are not improved.

Yes, that's the same thing you can infer from the asm I posted here:
#73731

That's why I have asked for some kind of unittests that this change actually does something useful...

I think @lzutao is talking about the rearranged code suggested by @pickfire rather than this PR. As I mentioned before, the most we could do is to pass the hint to LLVM, and we cannot guarantee that LLVM will take advantage of that.

@nbdd0121 nbdd0121 deleted the checked_opt branch September 4, 2021 02:55
@cuviper cuviper added this to the 1.46 milestone May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

checked_div happy path
8 participants