Skip to content

Commit 343eee6

Browse files
MarwesMarkus Westerlind
authored and
Markus Westerlind
committed
perf: Filter out and process fixed constraints first in region expansion
Should reduce the number of elements as well as branches in the extremely hot loop and process_constraint in benchmarks such as unicode_normalization
1 parent 9fe05e9 commit 343eee6

File tree

1 file changed

+33
-16
lines changed
  • src/librustc/infer/lexical_region_resolve

1 file changed

+33
-16
lines changed

src/librustc/infer/lexical_region_resolve/mod.rs

+33-16
Original file line numberDiff line numberDiff line change
@@ -295,46 +295,63 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
295295
}
296296

297297
fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) {
298-
let mut process_constraint = |constraint: &Constraint<'tcx>| {
299-
let (a_region, b_vid, b_data, retain) = match *constraint {
298+
let mut changed = false;
299+
let mut constraints = Vec::new();
300+
for constraint in self.data.constraints.keys() {
301+
let (a_region, b_vid, b_data) = match *constraint {
300302
Constraint::RegSubVar(a_region, b_vid) => {
301303
let b_data = var_values.value_mut(b_vid);
302-
(a_region, b_vid, b_data, false)
304+
(a_region, b_vid, b_data)
303305
}
304306
Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) {
305-
VarValue::ErrorValue => return (false, false),
307+
VarValue::ErrorValue => continue,
306308
VarValue::Value(a_region) => {
307309
let b_data = var_values.value_mut(b_vid);
308-
let retain = match *b_data {
309-
VarValue::Value(ReStatic) | VarValue::ErrorValue => false,
310-
_ => true,
311-
};
312-
(a_region, b_vid, b_data, retain)
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)
313315
}
314316
},
315317
Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => {
316318
// These constraints are checked after expansion
317319
// is done, in `collect_errors`.
318-
return (false, false);
320+
continue;
319321
}
320322
};
323+
let edge_changed = self.expand_node(a_region, b_vid, b_data);
324+
if edge_changed {
325+
changed = true
326+
}
327+
}
321328

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)
339+
}
340+
};
322341
let changed = self.expand_node(a_region, b_vid, b_data);
323342
(changed, retain)
324343
};
325344

326345
// Using bitsets to track the remaining elements is faster than using a
327346
// `Vec` by itself (which requires removing elements, which requires
328347
// element shuffling, which is slow).
329-
let constraints: Vec<_> = self.data.constraints.keys().collect();
330348
let mut live_indices: BitSet<usize> = BitSet::new_filled(constraints.len());
331349
let mut killed_indices: BitSet<usize> = BitSet::new_empty(constraints.len());
332-
let mut changed = true;
333350
while changed {
334351
changed = false;
335352
for index in live_indices.iter() {
336-
let constraint = constraints[index];
337-
let (edge_changed, retain) = process_constraint(constraint);
353+
let (a_vid, b_vid) = constraints[index];
354+
let (edge_changed, retain) = process_constraint(a_vid, b_vid);
338355
changed |= edge_changed;
339356
if !retain {
340357
let changed = killed_indices.insert(index);
@@ -790,8 +807,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
790807
self.var_infos[node_idx].origin.span(),
791808
&format!(
792809
"collect_error_for_expanding_node() could not find \
793-
error for var {:?} in universe {:?}, lower_bounds={:#?}, \
794-
upper_bounds={:#?}",
810+
error for var {:?} in universe {:?}, lower_bounds={:#?}, \
811+
upper_bounds={:#?}",
795812
node_idx, node_universe, lower_bounds, upper_bounds
796813
),
797814
);

0 commit comments

Comments
 (0)