Skip to content

Commit d9f3888

Browse files
committed
perf: Only search the potentially changed constraints in lexical_region_resolve
1 parent 6f8409f commit d9f3888

File tree

1 file changed

+29
-52
lines changed
  • src/librustc/infer/lexical_region_resolve

1 file changed

+29
-52
lines changed

src/librustc/infer/lexical_region_resolve/mod.rs

+29-52
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use rustc_data_structures::graph::implementation::{
1919
Direction, Graph, NodeIndex, INCOMING, OUTGOING,
2020
};
2121
use rustc_hir::def_id::DefId;
22-
use rustc_index::bit_set::BitSet;
2322
use rustc_index::vec::{Idx, IndexVec};
2423
use rustc_span::Span;
2524
use std::fmt;
@@ -297,23 +296,19 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
297296
}
298297

299298
fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) {
300-
let mut changed = false;
301-
let mut constraints = Vec::new();
299+
let mut constraints = IndexVec::from_elem_n(Vec::new(), var_values.values.len());
300+
let mut changes = Vec::new();
302301
for constraint in self.data.constraints.keys() {
303-
let (a_region, b_vid, b_data) = match *constraint {
302+
let (a_vid, a_region, b_vid, b_data) = match *constraint {
304303
Constraint::RegSubVar(a_region, b_vid) => {
305304
let b_data = var_values.value_mut(b_vid);
306-
(a_region, b_vid, b_data)
305+
(None, a_region, b_vid, b_data)
307306
}
308307
Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) {
309308
VarValue::ErrorValue => continue,
310309
VarValue::Value(a_region) => {
311310
let b_data = var_values.value_mut(b_vid);
312-
match *b_data {
313-
VarValue::Value(ReStatic) | VarValue::ErrorValue => (),
314-
_ => constraints.push((a_vid, b_vid)),
315-
}
316-
(a_region, b_vid, b_data)
311+
(Some(a_vid), a_region, b_vid, b_data)
317312
}
318313
},
319314
Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => {
@@ -322,56 +317,38 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
322317
continue;
323318
}
324319
};
325-
let edge_changed = self.expand_node(a_region, b_vid, b_data);
326-
if edge_changed {
327-
changed = true
320+
if self.expand_node(a_region, b_vid, b_data) {
321+
changes.push(b_vid);
328322
}
329-
}
330-
331-
let mut process_constraint = |a_vid, b_vid| {
332-
let (a_region, b_data, retain) = match *var_values.value(a_vid) {
333-
VarValue::ErrorValue => return (false, false),
334-
VarValue::Value(a_region) => {
335-
let b_data = var_values.value_mut(b_vid);
336-
let retain = match *b_data {
337-
VarValue::Value(ReStatic) | VarValue::ErrorValue => false,
338-
_ => true,
339-
};
340-
(a_region, b_data, retain)
323+
if let Some(a_vid) = a_vid {
324+
match *b_data {
325+
VarValue::Value(ReStatic) | VarValue::ErrorValue => (),
326+
_ => {
327+
constraints[a_vid].push((a_vid, b_vid));
328+
constraints[b_vid].push((a_vid, b_vid));
329+
}
341330
}
342-
};
343-
let changed = self.expand_node(a_region, b_vid, b_data);
344-
(changed, retain)
345-
};
331+
}
332+
}
346333

347-
// Using bitsets to track the remaining elements is faster than using a
348-
// `Vec` by itself (which requires removing elements, which requires
349-
// element shuffling, which is slow).
350-
let mut live_indices: BitSet<usize> = BitSet::new_filled(constraints.len());
351-
let mut killed_indices: BitSet<usize> = BitSet::new_empty(constraints.len());
352-
while changed {
353-
changed = false;
354-
for index in live_indices.iter() {
355-
let (a_vid, b_vid) = constraints[index];
356-
let (edge_changed, retain) = process_constraint(a_vid, b_vid);
357-
if edge_changed {
358-
changed = true
334+
while let Some(vid) = changes.pop() {
335+
constraints[vid].retain(|&(a_vid, b_vid)| {
336+
let a_region = match *var_values.value(a_vid) {
337+
VarValue::ErrorValue => return false,
338+
VarValue::Value(a_region) => a_region,
339+
};
340+
let b_data = var_values.value_mut(b_vid);
341+
if self.expand_node(a_region, b_vid, b_data) {
342+
changes.push(b_vid);
359343
}
360-
if !retain {
361-
let changed = killed_indices.insert(index);
362-
debug_assert!(changed);
344+
match *b_data {
345+
VarValue::Value(ReStatic) | VarValue::ErrorValue => false,
346+
_ => true,
363347
}
364-
}
365-
live_indices.subtract(&killed_indices);
366-
367-
// We could clear `killed_indices` here, but we don't need to and
368-
// it's cheaper not to.
348+
});
369349
}
370350
}
371351

372-
// This function is very hot in some workloads. There's a single callsite
373-
// so always inlining is ok even though it's large.
374-
#[inline(always)]
375352
fn expand_node(
376353
&self,
377354
a_region: Region<'tcx>,

0 commit comments

Comments
 (0)