From 55768330a9046d240c5e542419d808626106a0aa Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 18 Jan 2019 09:51:24 +1100 Subject: [PATCH 1/2] Remove unneeded `origin` arg from `iterate_until_fixed_point`'s closure. --- src/librustc/infer/lexical_region_resolve/mod.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 39ce8cc621b49..f45ed395c414f 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -186,8 +186,8 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { } fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) { - self.iterate_until_fixed_point("Expansion", |constraint, origin| { - debug!("expansion: constraint={:?} origin={:?}", constraint, origin); + self.iterate_until_fixed_point("Expansion", |constraint| { + debug!("expansion: constraint={:?}", constraint); match *constraint { Constraint::RegSubVar(a_region, b_vid) => { let b_data = var_values.value_mut(b_vid); @@ -722,18 +722,17 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { } fn iterate_until_fixed_point(&self, tag: &str, mut body: F) - where - F: FnMut(&Constraint<'tcx>, &SubregionOrigin<'tcx>) -> (bool, bool), + where F: FnMut(&Constraint<'tcx>) -> (bool, bool), { - let mut constraints: SmallVec<[_; 16]> = self.data.constraints.iter().collect(); + let mut constraints: SmallVec<[_; 16]> = self.data.constraints.keys().collect(); let mut iteration = 0; let mut changed = true; while changed { changed = false; iteration += 1; debug!("---- {} Iteration {}{}", "#", tag, iteration); - constraints.retain(|(constraint, origin)| { - let (edge_changed, retain) = body(constraint, origin); + constraints.retain(|constraint| { + let (edge_changed, retain) = body(constraint); if edge_changed { debug!("Updated due to constraint {:?}", constraint); changed = true; From 92fd6f9d30d0b6b4ecbcf01534809fb66393f139 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 18 Jan 2019 10:00:51 +1100 Subject: [PATCH 2/2] Inline `expand_node`. This requires restructuring things a little so that there is only one callsite, ensuring that inlinining doesn't cause unnecessary code bloat. This reduces instruction counts for the `unicode_normalization` benchmark by up to 4%. --- .../infer/lexical_region_resolve/mod.rs | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index f45ed395c414f..545192a1f2113 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -188,32 +188,37 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) { self.iterate_until_fixed_point("Expansion", |constraint| { debug!("expansion: constraint={:?}", constraint); - match *constraint { + let (a_region, b_vid, b_data, retain) = match *constraint { Constraint::RegSubVar(a_region, b_vid) => { let b_data = var_values.value_mut(b_vid); - (self.expand_node(a_region, b_vid, b_data), false) + (a_region, b_vid, b_data, false) } Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) { - VarValue::ErrorValue => (false, false), + VarValue::ErrorValue => return (false, false), VarValue::Value(a_region) => { - let b_node = var_values.value_mut(b_vid); - let changed = self.expand_node(a_region, b_vid, b_node); - let retain = match *b_node { + let b_data = var_values.value_mut(b_vid); + let retain = match *b_data { VarValue::Value(ReStatic) | VarValue::ErrorValue => false, _ => true }; - (changed, retain) + (a_region, b_vid, b_data, retain) } }, Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => { // These constraints are checked after expansion // is done, in `collect_errors`. - (false, false) + return (false, false) } - } + }; + + let changed = self.expand_node(a_region, b_vid, b_data); + (changed, retain) }) } + // This function is very hot in some workloads. There's a single callsite + // so always inlining is ok even though it's large. + #[inline(always)] fn expand_node( &self, a_region: Region<'tcx>,