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

Normalize late-bound projections with inference variables in fulfillment #94070

Conversation

compiler-errors
Copy link
Member

@compiler-errors compiler-errors commented Feb 17, 2022

I modified the PR #90887 "Try to normalize associated types before processing obligations" to only attempt normalization when these two conditions are both true:

  1. the projection type has escaping late-bound variables, and
  2. the projection has remaining inference variables.

The only projections that we expect to see inside of a predicate during fulfillment (and which we have any hope of normalizing further) are those that have remaining inference variables that need to be resolved, and which have late-bound vars which opted them out of being replaced with a fresh inference variable in the first place. We rely on existing normalization that is speckled through typeck and confirmation (e.g. here) to uphold this invariant, which means we can skip a large portion of the normalization calls that we saw in #90887.

As seen in the (really messy) initial PR I put up for a perf run, it seems to have improved performance.


Reasoning about why these two conditions together are sufficient:

  1. If we see a projection during the fulfillment loop that has inference but no late-bound variables, we probably are missing a normalization call somewhere else, since that projection should've been replaced with an inference variable when we got the type from HIR. This means we should track down that missing normalization call to somewhere in typeck or confirmation.
  2. If we see a projection with escaping late-bound variables (but no inference variables), then we probably don't have a solution to that projection variable in the first place, since we should have been able to normalize it (since we have all the information we can have about the type).

This probably needs more discussion, but I'm putting this up for initial review, and we can perhaps discuss it in the GATs meeting.

r? @nikomatsakis
cc @jackh726

Fixes #90729
Fixes #93341
Fixes #93342
Fixes #94160

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Feb 17, 2022
@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Feb 17, 2022
@compiler-errors compiler-errors changed the title Normalize assocs in fulfillment Normalize late-bound projections with inference variables in fulfillment Feb 17, 2022
@jackh726
Copy link
Member

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion.

@rustbot label: +S-waiting-on-perf

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Feb 17, 2022
@bors
Copy link
Contributor

bors commented Feb 17, 2022

⌛ Trying commit df8d9f530e6a6c825f92b21145861dbbabeb083e with merge f20c37cb312b7df326fa1d05e51af9149c90e9fd...

@jackh726
Copy link
Member

Things to think about:

  • I liked removing the extra normalizations in confirmations; it really highlights that this actually simplifies things (this also in theory could have been the reason for better perf, we'll see)
  • Was moving the normalization in fulfill up a bit enough to fix perf? In other words, do we really need to only normalize if there are late-bound vars?

@bors
Copy link
Contributor

bors commented Feb 17, 2022

☀️ Try build successful - checks-actions
Build commit: f20c37cb312b7df326fa1d05e51af9149c90e9fd (f20c37cb312b7df326fa1d05e51af9149c90e9fd)

@rust-timer
Copy link
Collaborator

Queued f20c37cb312b7df326fa1d05e51af9149c90e9fd with parent 930fc4f, future comparison URL.

@compiler-errors
Copy link
Member Author

compiler-errors commented Feb 17, 2022

Yeah, regard the first part, I actually discovered that all that extra normalizing of those Fn trait refs wasn't needed when I stopped first shallow resolving and then normalizing during fulfillment... hence this PR is a lot shorter.

The second question is a good point, I can put up a quick PR tomorrow so we can run an experiment unless you want to modify #90887 yourself.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (f20c37cb312b7df326fa1d05e51af9149c90e9fd): comparison url.

Summary: This benchmark run shows 13 relevant regressions 😿 to instruction counts.

  • Average relevant regression: 1.3%
  • Largest regression in instruction counts: 3.1% on full builds of inflate check

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR led to changes in compiler perf.

Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @rustbot label: +perf-regression-triaged along with sufficient written justification. If you cannot justify the regressions please fix the regressions and do another perf run. If the next run shows neutral or positive results, the label will be automatically removed.

@bors rollup=never
@rustbot label: +S-waiting-on-review -S-waiting-on-perf +perf-regression

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Feb 17, 2022
@compiler-errors
Copy link
Member Author

Haha! That's lovely. Let me rebase that normalization commit when I get up in a few hours.

@jackh726
Copy link
Member

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion.

@rustbot label: +S-waiting-on-perf

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Feb 17, 2022
@bors
Copy link
Contributor

bors commented Feb 17, 2022

⌛ Trying commit a2ce369ecd32bb4b319c1495a0991f1260ddd5c8 with merge 0ab1cb526af76f0c1d83259e21fd9cb9497c1e80...

@bors
Copy link
Contributor

bors commented Feb 17, 2022

☀️ Try build successful - checks-actions
Build commit: 0ab1cb526af76f0c1d83259e21fd9cb9497c1e80 (0ab1cb526af76f0c1d83259e21fd9cb9497c1e80)

@rust-timer
Copy link
Collaborator

Queued 0ab1cb526af76f0c1d83259e21fd9cb9497c1e80 with parent 30b3f35, future comparison URL.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (0ab1cb526af76f0c1d83259e21fd9cb9497c1e80): comparison url.

Summary: This benchmark run did not return any relevant results. 14 results were found to be statistically significant but too small to be relevant.

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR led to changes in compiler perf.

@bors rollup=never
@rustbot label: +S-waiting-on-review -S-waiting-on-perf -perf-regression

@rustbot rustbot removed S-waiting-on-perf Status: Waiting on a perf run to be completed. perf-regression Performance regression. labels Feb 17, 2022
@compiler-errors
Copy link
Member Author

Interesting to see that the perf improvement is a combination of the normalization in selection and (probably?) the type flag addition.

Per discussion with @jackh726, let's test this hypothesis further. I reverted the type flag diff (and added a small change so we don't resolve variables and normalize in fulfillment, since that's kinda doing duplicated work).

@jackh726
Copy link
Member

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Queued b133e1a0ceb78dbf55643a6deab904d3911208b6 with parent 30b3f35, future comparison URL.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (b133e1a0ceb78dbf55643a6deab904d3911208b6): comparison url.

Summary: This benchmark run did not return any relevant results. 29 results were found to be statistically significant but too small to be relevant.

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR led to changes in compiler perf.

@bors rollup=never
@rustbot label: +S-waiting-on-review -S-waiting-on-perf -perf-regression

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Feb 17, 2022
bors added a commit to rust-lang-ci/rust that referenced this pull request Feb 21, 2022
…malization, r=jackh726

Normalize obligation and expected trait_refs in confirm_poly_trait_refs

Consolidate normalization the obligation and expected trait refs in `confirm_poly_trait_refs`. Also, _always_ normalize these trait refs -- we were already normalizing the obligation trait ref when confirming closure and generator candidates, but this does it for fn pointer confirmation as well.

This presumably does more work in the case that the obligation's trait ref is already normalized, but we can see from the perf runs in rust-lang#94070, it actually (paradoxically, perhaps) improves performance when paired with logic that normalizes projections in fulfillment loop.
@compiler-errors compiler-errors force-pushed the normalize-assocs-in-fulfillment branch 2 times, most recently from 9550ae8 to fd193d2 Compare March 7, 2022 17:14
@jackh726
Copy link
Member

jackh726 commented Mar 7, 2022

Let's land #90887 first, and see if this stands on its on?

@bors
Copy link
Contributor

bors commented Mar 8, 2022

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

@compiler-errors compiler-errors force-pushed the normalize-assocs-in-fulfillment branch from fd193d2 to 0a096a0 Compare March 8, 2022 04:38
@nnethercote
Copy link
Contributor

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion.

@rustbot label: +S-waiting-on-perf

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Mar 8, 2022
@bors
Copy link
Contributor

bors commented Mar 8, 2022

⌛ Trying commit 0a096a0 with merge dd0319c25a100e481bc99429d2a54fe68330aa26...

@bors
Copy link
Contributor

bors commented Mar 8, 2022

☀️ Try build successful - checks-actions
Build commit: dd0319c25a100e481bc99429d2a54fe68330aa26 (dd0319c25a100e481bc99429d2a54fe68330aa26)

@rust-timer
Copy link
Collaborator

Queued dd0319c25a100e481bc99429d2a54fe68330aa26 with parent 67b3e81, future comparison URL.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (dd0319c25a100e481bc99429d2a54fe68330aa26): comparison url.

Summary: This benchmark run shows 15 relevant improvements 🎉 to instruction counts.

  • Arithmetic mean of relevant improvements: -0.4%
  • Largest improvement in instruction counts: -0.8% on full builds of futures check

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR led to changes in compiler perf.

@bors rollup=never
@rustbot label: +S-waiting-on-review -S-waiting-on-perf -perf-regression

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Mar 8, 2022
@nikomatsakis
Copy link
Contributor

@compiler-errors do you plan to rebase atop #90887 ?

@compiler-errors
Copy link
Member Author

@nikomatsakis I did! 😄

@jackh726
Copy link
Member

jackh726 commented Mar 8, 2022

Not sure the slight perf improvement here is worth the added complexity.

@compiler-errors
Copy link
Member Author

Yeah, in that case, I'll close this out.

@compiler-errors compiler-errors deleted the normalize-assocs-in-fulfillment branch April 7, 2022 04:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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.
Projects
None yet
9 participants