Skip to content

Optimize try_expand_impl_trait_type #65293

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 2 commits into from
Oct 16, 2019
Merged

Conversation

tmandry
Copy link
Member

@tmandry tmandry commented Oct 11, 2019

A lot of time was being spent expanding some large impl Future types in fuchsia. This PR takes the number of types being visited in one expansion from >3 billion to about a thousand, and eliminates the compile time regression in #65147 (in fact, compile times are better than they were before).

Thanks to @Mark-Simulacrum for helping identify the issue and to @matthewjasper for suggesting this change.

Fixes #65147.
r? @matthewjasper,@nikomatsakis

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 11, 2019
@tmandry
Copy link
Member Author

tmandry commented Oct 11, 2019

@bors try

@bors
Copy link
Collaborator

bors commented Oct 11, 2019

⌛ Trying commit 6493e6b with merge 0d2ff89f766a2f16a09c41ee7c65453980e81908...

@bors
Copy link
Collaborator

bors commented Oct 11, 2019

☀️ Try build successful - checks-azure
Build commit: 0d2ff89f766a2f16a09c41ee7c65453980e81908 (0d2ff89f766a2f16a09c41ee7c65453980e81908)

@tmandry
Copy link
Member Author

tmandry commented Oct 11, 2019

@rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion

@tmandry
Copy link
Member Author

tmandry commented Oct 11, 2019

@rust-timer build 0d2ff89f766a2f16a09c41ee7c65453980e81908

@rust-timer
Copy link
Collaborator

Queued 0d2ff89f766a2f16a09c41ee7c65453980e81908 with parent 898f36c, future comparison URL.

@@ -697,6 +697,9 @@ impl<'tcx> TyCtxt<'tcx> {
// that type, and when we finish expanding that type we remove the
// its DefId.
seen_opaque_tys: FxHashSet<DefId>,
// Cache of all expansions we've seen so far. This is a critical
// optimization for some large types produced by async fn trees.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// optimization for some large types produced by async fn trees.
// optimization for some large types produced by `async fn` trees.

let concrete_ty = generic_ty.subst(self.tcx, substs);
let expanded_ty = self.fold_ty(concrete_ty);
self.seen_opaque_tys.remove(&def_id);
let expanded_ty = match self.expanded_cache.get(&def_id) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not use the .entry API?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah! Entry! Entry! I ❤️ Entry!

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, I think I see why not -- the self.fold_ty call would error out with entry, wouldn't it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, the fact that the closure would need &mut self prevents me from using entry here :/

@nikomatsakis
Copy link
Contributor

@tmandry I'm not sure if we have a suitable test already, but if not, can you add something to perf that reflects this compile time gap?

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

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

Presuming this helps, and if we add a perf regression test, seems good to me! Nice detective work y'all.

@rust-timer
Copy link
Collaborator

Finished benchmarking try commit 0d2ff89f766a2f16a09c41ee7c65453980e81908, comparison URL.

@tmandry
Copy link
Member Author

tmandry commented Oct 11, 2019

@tmandry I'm not sure if we have a suitable test already, but if not, can you add something to perf that reflects this compile time gap?

Will do. I was hoping something would turn up in the existing test suite, but it doesn't look that way :)

Copy link
Contributor

@matthewjasper matthewjasper left a comment

Choose a reason for hiding this comment

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

I think the following test case shows the problem here:

#![type_length_limit="10000000"]
#![allow(unused)]

macro_rules! mk_async_fn {
    ($f:ident $g:ident) => {
        async fn $g() -> i32 {
            $f().await;
            $f().await;
            $f().await
        }
    }
}

async fn a() -> i32 { 1 }

mk_async_fn!(a b);
mk_async_fn!(b c);
mk_async_fn!(c d);
mk_async_fn!(d e);
mk_async_fn!(e f);
mk_async_fn!(f g);
mk_async_fn!(g h);
mk_async_fn!(h i);
mk_async_fn!(i j);

@matthewjasper matthewjasper 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 Oct 12, 2019
@tmandry
Copy link
Member Author

tmandry commented Oct 14, 2019

@bors try

@bors
Copy link
Collaborator

bors commented Oct 14, 2019

⌛ Trying commit 6493e6b with merge 0c36cd3...

bors added a commit that referenced this pull request Oct 14, 2019
Optimize `try_expand_impl_trait_type`

A lot of time was being spent expanding some large `impl Future` types in fuchsia. This PR takes the number of types being visited in one expansion from >3 billion to about a thousand, and eliminates the compile time regression in #65147 (in fact, compile times are better than they were before).

Thanks to @matthewjasper for suggesting this change.

Fixes #65147.
r? @matthewjasper,@nikomatsakis
@tmandry tmandry 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 Oct 14, 2019
@tmandry
Copy link
Member Author

tmandry commented Oct 15, 2019

@matthewjasper thanks for supplying the benchmark!

This should be ready, pending another timer run once rust-lang/rustc-perf#508 is merged.

@bors
Copy link
Collaborator

bors commented Oct 15, 2019

☀️ Try build successful - checks-azure
Build commit: 0c36cd3 (0c36cd32207594f45af4c9c92294f769113808b6)

@tmandry
Copy link
Member Author

tmandry commented Oct 15, 2019

@bors r=matthewjasper

@bors
Copy link
Collaborator

bors commented Oct 15, 2019

📌 Commit 802554f has been approved by matthewjasper

@bors bors 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-review Status: Awaiting review from the assignee but also interested parties. labels Oct 15, 2019
@tmandry tmandry added beta-nominated Nominated for backporting to the compiler in the beta channel. I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 15, 2019
tmandry added a commit to tmandry/rust that referenced this pull request Oct 15, 2019
…sper

Optimize `try_expand_impl_trait_type`

A lot of time was being spent expanding some large `impl Future` types in fuchsia. This PR takes the number of types being visited in one expansion from >3 billion to about a thousand, and eliminates the compile time regression in rust-lang#65147 (in fact, compile times are better than they were before).

Thanks to @Mark-Simulacrum for helping identify the issue and to @matthewjasper for suggesting this change.

Fixes rust-lang#65147.
r? @matthewjasper,@nikomatsakis
bors added a commit that referenced this pull request Oct 15, 2019
Rollup of 14 pull requests

Successful merges:

 - #64603 (Reducing spurious unused lifetime warnings.)
 - #64623 (Remove last uses of gensyms)
 - #65235 (don't assume we can *always* find a return type hint in async fn)
 - #65242 (Fix suggestion to constrain trait for method to be found)
 - #65265 (Cleanup librustc mir err codes)
 - #65293 (Optimize `try_expand_impl_trait_type`)
 - #65307 (Try fix incorrect "explicit lifetime name needed")
 - #65308 (Add long error explanation for E0574)
 - #65353 (save-analysis: Don't ICE when resolving qualified type paths in struct members)
 - #65389 (Return `false` from `needs_drop` for all zero-sized arrays.)
 - #65402 (Add troubleshooting section to PGO chapter in rustc book.)
 - #65425 (Optimize `BitIter`)
 - #65438 (Organize `never_type`  tests)
 - #65444 (Implement AsRef<[T]> for List<T>)

Failed merges:

 - #65390 (Add long error explanation for E0576)

r? @ghost
@bors bors merged commit 802554f into rust-lang:master Oct 16, 2019
@pnkfelix
Copy link
Member

discussed at T-compiler meeting. Accepted for beta-backport.

@pnkfelix pnkfelix added the beta-accepted Accepted for backporting to the compiler in the beta channel. label Oct 17, 2019
@Mark-Simulacrum Mark-Simulacrum removed beta-nominated Nominated for backporting to the compiler in the beta channel. I-nominated labels Oct 22, 2019
bors added a commit that referenced this pull request Oct 24, 2019
[beta] backport rollup

This includes a bunch of PRs:
 *  Fix redundant semicolon lint interaction with proc macro attributes #64387
 *  Upgrade async/await to "used" keywords. #64875
 *  syntax: fix dropping of attribute on first param of non-method assocated fn #64894
 *  async/await: improve not-send errors #64895
 *  Silence unreachable code lint from await desugaring #64930
 *  Always mark rust and rust-call abi's as unwind #65020
 *  Account for macro invocation in `let mut $pat` diagnostic. #65123
 *  Ensure that associated `async fn`s have unique fresh param names #65142
 *  Add troubleshooting section to PGO chapter in rustc book. #65402
 *  Upgrade GCC to 8.3.0, glibc to 1.17.0 and crosstool-ng to 1.24.0 for dist-armv7-linux #65302
 *  Optimize `try_expand_impl_trait_type` #65293
 *  use precalculated dominators in explain_borrow #65172
 *  Fix ICE #64964 #64989
bors added a commit that referenced this pull request Oct 26, 2019
[beta] backport rollup

This includes a bunch of PRs:
 *  Fix redundant semicolon lint interaction with proc macro attributes #64387
 *  Upgrade async/await to "used" keywords. #64875
 *  syntax: fix dropping of attribute on first param of non-method assocated fn #64894
 *  async/await: improve not-send errors #64895
 *  Silence unreachable code lint from await desugaring #64930
 *  Always mark rust and rust-call abi's as unwind #65020
 *  Account for macro invocation in `let mut $pat` diagnostic. #65123
 *  Ensure that associated `async fn`s have unique fresh param names #65142
 *  Add troubleshooting section to PGO chapter in rustc book. #65402
 *  Upgrade GCC to 8.3.0, glibc to 1.17.0 and crosstool-ng to 1.24.0 for dist-armv7-linux #65302
 *  Optimize `try_expand_impl_trait_type` #65293
 *  use precalculated dominators in explain_borrow #65172
 *  Fix ICE #64964 #64989
 *  [beta] Revert "Auto merge of #62948 - matklad:failable-file-loading, r=petro… #65273
 *  save-analysis: Don't ICE when resolving qualified type paths in struct members #65353
 *  save-analysis: Nest tables when processing impl block definitions #65511
 *  Avoid ICE when checking `Destination` of `break` inside a closure #65518
 *  Avoid ICE when adjusting bad self ty #65755
 *  workaround msys2 bug #65762
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
beta-accepted Accepted for backporting to the compiler in the beta channel. 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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

check_mod_item_types query times regressed bigly
9 participants