Skip to content

Commit 917eb18

Browse files
MarwesMarkus Westerlind
authored and
Markus Westerlind
committed
perf: Only search the potentially changed constraints in lexical_region_resolve
1 parent 343eee6 commit 917eb18

File tree

1 file changed

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

1 file changed

+29
-50
lines changed

src/librustc/infer/lexical_region_resolve/mod.rs

+29-50
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;
@@ -295,23 +294,19 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
295294
}
296295

297296
fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) {
298-
let mut changed = false;
299-
let mut constraints = Vec::new();
297+
let mut constraints = IndexVec::from_elem_n(Vec::new(), var_values.values.len());
298+
let mut changes = Vec::new();
300299
for constraint in self.data.constraints.keys() {
301-
let (a_region, b_vid, b_data) = match *constraint {
300+
let (a_vid, a_region, b_vid, b_data) = match *constraint {
302301
Constraint::RegSubVar(a_region, b_vid) => {
303302
let b_data = var_values.value_mut(b_vid);
304-
(a_region, b_vid, b_data)
303+
(None, a_region, b_vid, b_data)
305304
}
306305
Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) {
307306
VarValue::ErrorValue => continue,
308307
VarValue::Value(a_region) => {
309308
let b_data = var_values.value_mut(b_vid);
310-
match *b_data {
311-
VarValue::Value(ReStatic) | VarValue::ErrorValue => (),
312-
_ => constraints.push((a_vid, b_vid)),
313-
}
314-
(a_region, b_vid, b_data)
309+
(Some(a_vid), a_region, b_vid, b_data)
315310
}
316311
},
317312
Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => {
@@ -320,54 +315,38 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
320315
continue;
321316
}
322317
};
323-
let edge_changed = self.expand_node(a_region, b_vid, b_data);
324-
if edge_changed {
325-
changed = true
318+
if self.expand_node(a_region, b_vid, b_data) {
319+
changes.push(b_vid);
320+
}
321+
if let Some(a_vid) = a_vid {
322+
match *b_data {
323+
VarValue::Value(ReStatic) | VarValue::ErrorValue => (),
324+
_ => {
325+
constraints[a_vid].push((a_vid, b_vid));
326+
constraints[b_vid].push((a_vid, b_vid));
327+
}
328+
}
326329
}
327330
}
328331

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

368-
// This function is very hot in some workloads. There's a single callsite
369-
// so always inlining is ok even though it's large.
370-
#[inline(always)]
371350
fn expand_node(
372351
&self,
373352
a_region: Region<'tcx>,

0 commit comments

Comments
 (0)