Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #15436 - Veykril:temp-alloc, r=Veykril
Preserve `resolve_obligations_as_possible` temporary allocation across calls
This saves ~20ms in the highlihting bench on my machine
```
284ms - highlight
150ms - infer:wait @ per_query_memory_usage
150ms - infer_query
0 - PerNs::filter_visibility (436 calls)
0 - crate_def_map:wait (336 calls)
2ms - deref_by_trait (909 calls)
0 - generic_params_query (1 calls)
0 - inherent_impls_in_block_query (1 calls)
107ms - resolve_obligations_as_possible (17013 calls)
0 - trait_solve::wait (1017 calls)
0 - PerNs::filter_visibility (13 calls)
17ms - Semantics::analyze_impl (19 calls)
0 - SourceBinder::to_module_def (30 calls)
0 - attrs_query (6 calls)
0 - classify_lifetime (1 calls)
0 - classify_lifetime_ref (4 calls)
35ms - classify_name (28 calls)
54ms - classify_name_ref (452 calls)
0 - crate_def_map:wait (375 calls)
7ms - descend_into_macros (776 calls)
0 - generic_params_query (5 calls)
0 - impl_data_with_diagnostics_query (1 calls)
17ms - infer:wait (32 calls)
0 - resolve_obligations_as_possible (1 calls)
0 - source_file_to_def (1 calls)
0 - trait_solve::wait (1 calls)
```
to
```
256ms - highlight
121ms - infer:wait @ per_query_memory_usage
121ms - infer_query
0 - PerNs::filter_visibility (436 calls)
0 - crate_def_map:wait (336 calls)
2ms - deref_by_trait (909 calls)
0 - generic_params_query (1 calls)
0 - inherent_impls_in_block_query (1 calls)
81ms - resolve_obligations_as_possible (17013 calls)
0 - trait_solve::wait (1017 calls)
0 - PerNs::filter_visibility (13 calls)
17ms - Semantics::analyze_impl (19 calls)
0 - SourceBinder::to_module_def (30 calls)
0 - attrs_query (6 calls)
0 - classify_lifetime (1 calls)
0 - classify_lifetime_ref (4 calls)
35ms - classify_name (28 calls)
56ms - classify_name_ref (452 calls)
0 - crate_def_map:wait (375 calls)
7ms - descend_into_macros (776 calls)
0 - generic_params_query (5 calls)
0 - impl_data_with_diagnostics_query (1 calls)
16ms - infer:wait (32 calls)
0 - resolve_obligations_as_possible (1 calls)
0 - source_file_to_def (1 calls)
0 - trait_solve::wait (1 calls)
```
| -rw-r--r-- | crates/hir-ty/src/infer/unify.rs | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs index 169679b463..0a68a9f3b5 100644 --- a/crates/hir-ty/src/infer/unify.rs +++ b/crates/hir-ty/src/infer/unify.rs @@ -143,6 +143,9 @@ pub(crate) struct InferenceTable<'a> { var_unification_table: ChalkInferenceTable, type_variable_table: Vec<TypeVariableFlags>, pending_obligations: Vec<Canonicalized<InEnvironment<Goal>>>, + /// Double buffer used in [`Self::resolve_obligations_as_possible`] to cut down on + /// temporary allocations. + resolve_obligations_buffer: Vec<Canonicalized<InEnvironment<Goal>>>, } pub(crate) struct InferenceTableSnapshot { @@ -159,6 +162,7 @@ impl<'a> InferenceTable<'a> { var_unification_table: ChalkInferenceTable::new(), type_variable_table: Vec::new(), pending_obligations: Vec::new(), + resolve_obligations_buffer: Vec::new(), } } @@ -510,10 +514,10 @@ impl<'a> InferenceTable<'a> { pub(crate) fn resolve_obligations_as_possible(&mut self) { let _span = profile::span("resolve_obligations_as_possible"); let mut changed = true; - let mut obligations = Vec::new(); - while changed { - changed = false; + let mut obligations = mem::take(&mut self.resolve_obligations_buffer); + while mem::take(&mut changed) { mem::swap(&mut self.pending_obligations, &mut obligations); + for canonicalized in obligations.drain(..) { if !self.check_changed(&canonicalized) { self.pending_obligations.push(canonicalized); @@ -528,6 +532,8 @@ impl<'a> InferenceTable<'a> { self.register_obligation_in_env(uncanonical); } } + self.resolve_obligations_buffer = obligations; + self.resolve_obligations_buffer.clear(); } pub(crate) fn fudge_inference<T: TypeFoldable<Interner>>( |