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

Optimize slice.{r}position result bounds check #47333

Merged
merged 1 commit into from
Jan 17, 2018

Conversation

arthurprs
Copy link
Contributor

@arthurprs arthurprs commented Jan 10, 2018

Second attempt of #45501
Fixes #45964

Demo: https://godbolt.org/g/N4mBHp

@arthurprs arthurprs changed the title Optimize slice.{r}position result bounds check [WIP] Optimize slice.{r}position result bounds check Jan 10, 2018
{
// The addition might panic on overflow
self.try_fold(0, move |i, x| {
if predicate(x) { LoopState::Break(i) }
Copy link
Member

Choose a reason for hiding this comment

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

failed to resolve. Use of undeclared type or module LoopState

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm changing it to use Result<,>'s instead.

@kennytm
Copy link
Member

kennytm commented Jan 10, 2018

r? @dtolnay

@kennytm kennytm added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 10, 2018
Copy link
Member

@dtolnay dtolnay left a comment

Choose a reason for hiding this comment

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

Thanks for sticking with this!

@dtolnay
Copy link
Member

dtolnay commented Jan 10, 2018

@bors r+

@bors
Copy link
Contributor

bors commented Jan 10, 2018

📋 Looks like this PR is still in progress, ignoring approval

@kennytm
Copy link
Member

kennytm commented Jan 10, 2018

Borrowck error. We haven't enabled NLL yet 😄.

[00:03:08] error[E0502]: cannot borrow `self` as immutable because `*self` is also borrowed as mutable
[00:03:08]     --> libcore/slice/mod.rs:1242:32
[00:03:08]      |
[00:03:08] 1242 |                 self.try_rfold(self.len(), move |i, x| {
[00:03:08]      |                 ----           ^^^^ immutable borrow occurs here
[00:03:08]      |                 |
[00:03:08]      |                 mutable borrow occurs here
[00:03:08] ...
[00:03:08] 1246 |                 }).err()
[00:03:08]      |                  - mutable borrow ends here
[00:03:08] ...
[00:03:08] 1422 | iterator!{struct Iter -> *const T, &'a T, make_ref}
[00:03:08]      | --------------------------------------------------- in this macro invocation

@arthurprs
Copy link
Contributor Author

I see 😢 going for the 5th try now.

@arthurprs arthurprs force-pushed the iter-position-bounds-check branch 4 times, most recently from 806b403 to 1699dc4 Compare January 10, 2018 21:00
@kennytm kennytm 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 10, 2018
@arthurprs arthurprs changed the title [WIP] Optimize slice.{r}position result bounds check Optimize slice.{r}position result bounds check Jan 10, 2018
@kennytm
Copy link
Member

kennytm commented Jan 11, 2018

@bors r=dtolnay

@bors
Copy link
Contributor

bors commented Jan 11, 2018

📌 Commit 1699dc4 has been approved by dtolnay

@kennytm kennytm 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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 11, 2018
Self: Sized,
P: FnMut(Self::Item) -> bool,
{
// The addition might panic on overflow
Copy link
Member

Choose a reason for hiding this comment

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

I think this needs either Add::add instead of + or #[rustc_inherit_overflow_checks].

Also, it's a shame there's no way to "call base" here. Would it be worth making a pub(crate) helper here to avoid duplicating the logic? Or using specialization to do the assume for all Self: TrustedLen?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think the duplication is a concern as these are really small. Having a helper would probably end up adding more lines than saving.

Good points about the overflow and specialization though. I have to test if the assume survives the abstraction/inlining.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I couldn't make it work with TrustedLen 😞 https://godbolt.org/g/bFA3tk

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for giving it a try! Good to see this get in 🙂

@arthurprs
Copy link
Contributor Author

I added a #[rustc_inherit_overflow_checks] as per @scottmcm review

@kennytm
Copy link
Member

kennytm commented Jan 17, 2018

@bors r=dtolnay

@bors
Copy link
Contributor

bors commented Jan 17, 2018

📌 Commit 0b56ab0 has been approved by dtolnay

kennytm added a commit to kennytm/rust that referenced this pull request Jan 17, 2018
…k, r=dtolnay

Optimize slice.{r}position result bounds check

Second attempt of rust-lang#45501
Fixes rust-lang#45964

Demo: https://godbolt.org/g/N4mBHp
bors added a commit that referenced this pull request Jan 17, 2018
@bors bors merged commit 0b56ab0 into rust-lang:master Jan 17, 2018
@arthurprs
Copy link
Contributor Author

arthurprs commented Jan 25, 2018

Apparently this didn't work 😢 Demo: https://godbolt.org/g/MXg2ae

It has to do with self.len() in this PR calling the iterator len instead of the slice len.

Using self.as_slice().len() does the trick. Demo: https://godbolt.org/g/P8q5aZ I'll make the fix PR later.

bors added a commit that referenced this pull request Jan 28, 2018
Use the slice length to hint the optimizer about iter.position result

Using the len of the iterator doesn't give the same result.
That's also why we can't generalize it to all TrustedLen iterators.

Problem demo: https://godbolt.org/g/MXg2ae
Fix demo: https://godbolt.org/g/P8q5aZ

Second attempt of #47333
Third attempt of #45501
Fixes #45964
kennytm added a commit to kennytm/rust that referenced this pull request Feb 14, 2018
Removed the `assume()` which we assumed is the cause of misoptimization in
issue rust-lang#48116.
bors added a commit that referenced this pull request Feb 14, 2018
Try to fix 48116 and 48192

The bug #48116 happens because of a misoptimization of the `import_path_to_string` function, where a `names` slice is empty but the `!names.is_empty()` branch is executed.

https://github.com/rust-lang/rust/blob/4d2d3fc5dadf894a8ad709a5860a549f2c0b1032/src/librustc_resolve/resolve_imports.rs#L1015-L1042

Yesterday, @eddyb had locally reproduced the bug, and [came across the `position` function](https://mozilla.logbot.info/rust-infra/20180214#c14296834) where the `assume()` call is found to be suspicious. We have *not* concluded that this `assume()` causes #48116, but given [the reputation of `assume()`](#45501 (comment)), this seems higher relevant. Here we try to see if commenting it out can fix the errors.

Later @alexcrichton has bisected and found a potential bug [in the LLVM side](#48116 (comment)). We are currently testing if reverting that LLVM commit is enough to stop the bug. If true, this PR can be reverted (keep the `assume()`) and we could backport the LLVM patch instead.

(This PR also includes an earlier commit from #48127 for help debugging ICE happening in compile-fail/parse-fail tests.)

The PR also reverts #48059, which seems to cause #48192.

r? @alexcrichton
cc @eddyb, @arthurprs (#47333)
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.

5 participants