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)
```
This commit is contained in:
bors 2023-08-12 04:38:32 +00:00
commit 39ebc378c2

View File

@ -143,6 +143,9 @@ pub(crate) struct InferenceTable<'a> {
var_unification_table: ChalkInferenceTable, var_unification_table: ChalkInferenceTable,
type_variable_table: Vec<TypeVariableFlags>, type_variable_table: Vec<TypeVariableFlags>,
pending_obligations: Vec<Canonicalized<InEnvironment<Goal>>>, 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 { pub(crate) struct InferenceTableSnapshot {
@ -159,6 +162,7 @@ pub(crate) fn new(db: &'a dyn HirDatabase, trait_env: Arc<TraitEnvironment>) ->
var_unification_table: ChalkInferenceTable::new(), var_unification_table: ChalkInferenceTable::new(),
type_variable_table: Vec::new(), type_variable_table: Vec::new(),
pending_obligations: Vec::new(), pending_obligations: Vec::new(),
resolve_obligations_buffer: Vec::new(),
} }
} }
@ -510,10 +514,10 @@ pub(crate) fn register_infer_ok<T>(&mut self, infer_ok: InferOk<T>) {
pub(crate) fn resolve_obligations_as_possible(&mut self) { pub(crate) fn resolve_obligations_as_possible(&mut self) {
let _span = profile::span("resolve_obligations_as_possible"); let _span = profile::span("resolve_obligations_as_possible");
let mut changed = true; let mut changed = true;
let mut obligations = Vec::new(); let mut obligations = mem::take(&mut self.resolve_obligations_buffer);
while changed { while mem::take(&mut changed) {
changed = false;
mem::swap(&mut self.pending_obligations, &mut obligations); mem::swap(&mut self.pending_obligations, &mut obligations);
for canonicalized in obligations.drain(..) { for canonicalized in obligations.drain(..) {
if !self.check_changed(&canonicalized) { if !self.check_changed(&canonicalized) {
self.pending_obligations.push(canonicalized); self.pending_obligations.push(canonicalized);
@ -528,6 +532,8 @@ pub(crate) fn resolve_obligations_as_possible(&mut self) {
self.register_obligation_in_env(uncanonical); self.register_obligation_in_env(uncanonical);
} }
} }
self.resolve_obligations_buffer = obligations;
self.resolve_obligations_buffer.clear();
} }
pub(crate) fn fudge_inference<T: TypeFoldable<Interner>>( pub(crate) fn fudge_inference<T: TypeFoldable<Interner>>(