Skip to content

Commit 960c730

Browse files
committed
Auto merge of #57494 - dotdash:expand, r=<try>
Speed up item_bodies for large match statements involving regions These changes don't change anything about the complexity of the algorithms, but use some easy shortcuts or modifications to cut down some overhead. The first change, which incrementally removes the constraints from the set we're iterating over probably introduces some overhead for small to medium sized constraint sets, but it's not big enough for me to observe it in any project I tested against (not that many though). Though most other crates probably won't improve much at all, because huge matches aren't that common, the changes seemed simple enough for me to make them. Ref #55528 cc unicode-rs/unicode-normalization#29 r? @nikomatsakis
2 parents 6ecad33 + 5f402b8 commit 960c730

File tree

1 file changed

+23
-8
lines changed
  • src/librustc/infer/lexical_region_resolve

1 file changed

+23
-8
lines changed

src/librustc/infer/lexical_region_resolve/mod.rs

+23-8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_data_structures::graph::implementation::{
1313
Direction, Graph, NodeIndex, INCOMING, OUTGOING,
1414
};
1515
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
16+
use smallvec::SmallVec;
1617
use std::fmt;
1718
use std::u32;
1819
use ty::fold::TypeFoldable;
@@ -190,19 +191,24 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
190191
match *constraint {
191192
Constraint::RegSubVar(a_region, b_vid) => {
192193
let b_data = var_values.value_mut(b_vid);
193-
self.expand_node(a_region, b_vid, b_data)
194+
(self.expand_node(a_region, b_vid, b_data), false)
194195
}
195196
Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) {
196-
VarValue::ErrorValue => false,
197+
VarValue::ErrorValue => (false, false),
197198
VarValue::Value(a_region) => {
198199
let b_node = var_values.value_mut(b_vid);
199-
self.expand_node(a_region, b_vid, b_node)
200+
let changed = self.expand_node(a_region, b_vid, b_node);
201+
let retain = match *b_node {
202+
VarValue::Value(ReStatic) | VarValue::ErrorValue => false,
203+
_ => true
204+
};
205+
(changed, retain)
200206
}
201207
},
202208
Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => {
203209
// These constraints are checked after expansion
204210
// is done, in `collect_errors`.
205-
false
211+
(false, false)
206212
}
207213
}
208214
})
@@ -268,6 +274,13 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
268274

269275
fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> {
270276
let tcx = self.tcx();
277+
278+
// Equal scopes can show up quite often, if the fixed point
279+
// iteration converges slowly, skip them
280+
if a == b {
281+
return a;
282+
}
283+
271284
match (a, b) {
272285
(&ty::ReClosureBound(..), _)
273286
| (_, &ty::ReClosureBound(..))
@@ -710,21 +723,23 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
710723

711724
fn iterate_until_fixed_point<F>(&self, tag: &str, mut body: F)
712725
where
713-
F: FnMut(&Constraint<'tcx>, &SubregionOrigin<'tcx>) -> bool,
726+
F: FnMut(&Constraint<'tcx>, &SubregionOrigin<'tcx>) -> (bool, bool),
714727
{
728+
let mut constraints: SmallVec<[_; 16]> = self.data.constraints.iter().collect();
715729
let mut iteration = 0;
716730
let mut changed = true;
717731
while changed {
718732
changed = false;
719733
iteration += 1;
720734
debug!("---- {} Iteration {}{}", "#", tag, iteration);
721-
for (constraint, origin) in &self.data.constraints {
722-
let edge_changed = body(constraint, origin);
735+
constraints.retain(|(constraint, origin)| {
736+
let (edge_changed, retain) = body(constraint, origin);
723737
if edge_changed {
724738
debug!("Updated due to constraint {:?}", constraint);
725739
changed = true;
726740
}
727-
}
741+
retain
742+
});
728743
}
729744
debug!("---- {} Complete after {} iteration(s)", tag, iteration);
730745
}

0 commit comments

Comments
 (0)