diff options
| author | bors <bors@rust-lang.org> | 2024-07-04 21:17:19 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-07-04 21:17:19 +0000 |
| commit | cc8da78a036dc3c15c35a97651b02af9a6d30c1e (patch) | |
| tree | 7fed19378e80e1b3d189f66557a85c15cb8cf971 | |
| parent | c4225812973cee4bba952cbf7a421f69871fed0d (diff) | |
| parent | 529a3f4ce609f4bc98215185838351d9815fbdc1 (diff) | |
Auto merge of #127288 - lqd:typelen-cache, r=compiler-errors
cache type sizes in type-size limit visitor
This is basically https://github.com/rust-lang/rust/pull/125507#issuecomment-2206813779 as lcnr can't open the PR now.
Locally it reduces the `itertools` regression by quite a bit, to "only +50%" compared to nightly (that includes overhead from the local lack of artifact post-processing, and is just a data point to compare to the 10-20x timings without the cache).
```console
Benchmark 1: cargo +stage1 build --release
Time (mean ± σ): 2.721 s ± 0.009 s [User: 2.446 s, System: 0.325 s]
Range (min … max): 2.710 s … 2.738 s 10 runs
Benchmark 2: cargo +nightly build --release
Time (mean ± σ): 1.784 s ± 0.005 s [User: 1.540 s, System: 0.279 s]
Range (min … max): 1.778 s … 1.792 s 10 runs
Summary
cargo +nightly build --release ran
1.52 ± 0.01 times faster than cargo +stage1 build --release
```
On master, it's from 34s to the 2.7s above.
r? compiler-errors
| -rw-r--r-- | compiler/rustc_middle/src/ty/instance.rs | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index ae54411d788..c50a98e88fd 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -5,6 +5,7 @@ use crate::ty::{ self, EarlyBinder, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::Namespace; @@ -388,13 +389,25 @@ impl<'tcx> InstanceKind<'tcx> { } fn type_length<'tcx>(item: impl TypeVisitable<TyCtxt<'tcx>>) -> usize { - struct Visitor { + struct Visitor<'tcx> { type_length: usize, + cache: FxHashMap<Ty<'tcx>, usize>, } - impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Visitor { + impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Visitor<'tcx> { fn visit_ty(&mut self, t: Ty<'tcx>) { + if let Some(&value) = self.cache.get(&t) { + self.type_length += value; + return; + } + + let prev = self.type_length; self.type_length += 1; t.super_visit_with(self); + + // We don't try to use the cache if the type is fairly small. + if self.type_length > 16 { + self.cache.insert(t, self.type_length - prev); + } } fn visit_const(&mut self, ct: ty::Const<'tcx>) { @@ -402,7 +415,7 @@ fn type_length<'tcx>(item: impl TypeVisitable<TyCtxt<'tcx>>) -> usize { ct.super_visit_with(self); } } - let mut visitor = Visitor { type_length: 0 }; + let mut visitor = Visitor { type_length: 0, cache: Default::default() }; item.visit_with(&mut visitor); visitor.type_length |
