Skip to content

Commit bd9d843

Browse files
authored
Rollup merge of rust-lang#64801 - nnethercote:improve-find_constraint_paths_between_regions, r=estebank
Avoid `chain()` in `find_constraint_paths_between_regions()`. This iterator can be hot, and chained iterators are slow. The second half of the chain is almost always empty, so this commit specializes the code to avoid the chained iteration. This change reduces instruction counts for the `wg-grammar` benchmark by up to 1.5%.
2 parents 65a050f + 5ca99b7 commit bd9d843

File tree

2 files changed

+22
-18
lines changed
  • src/librustc_mir

2 files changed

+22
-18
lines changed

src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs

+21-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::borrow_check::nll::constraints::OutlivesConstraint;
2-
use crate::borrow_check::nll::region_infer::AppliedMemberConstraint;
32
use crate::borrow_check::nll::region_infer::RegionInferenceContext;
43
use crate::borrow_check::nll::type_check::Locations;
54
use crate::borrow_check::nll::universal_regions::DefiningTy;
@@ -253,29 +252,33 @@ impl<'tcx> RegionInferenceContext<'tcx> {
253252
let outgoing_edges_from_graph = self.constraint_graph
254253
.outgoing_edges(r, &self.constraints, fr_static);
255254

256-
257-
// But member constraints can also give rise to `'r: 'x`
258-
// edges that were not part of the graph initially, so
259-
// watch out for those.
260-
let outgoing_edges_from_picks = self.applied_member_constraints(r)
261-
.iter()
262-
.map(|&AppliedMemberConstraint { min_choice, member_constraint_index, .. }| {
263-
let p_c = &self.member_constraints[member_constraint_index];
264-
OutlivesConstraint {
265-
sup: r,
266-
sub: min_choice,
267-
locations: Locations::All(p_c.definition_span),
268-
category: ConstraintCategory::OpaqueType,
269-
}
270-
});
271-
272-
for constraint in outgoing_edges_from_graph.chain(outgoing_edges_from_picks) {
255+
// Always inline this closure because it can be hot.
256+
let mut handle_constraint = #[inline(always)] |constraint: OutlivesConstraint| {
273257
debug_assert_eq!(constraint.sup, r);
274258
let sub_region = constraint.sub;
275259
if let Trace::NotVisited = context[sub_region] {
276260
context[sub_region] = Trace::FromOutlivesConstraint(constraint);
277261
deque.push_back(sub_region);
278262
}
263+
};
264+
265+
// This loop can be hot.
266+
for constraint in outgoing_edges_from_graph {
267+
handle_constraint(constraint);
268+
}
269+
270+
// Member constraints can also give rise to `'r: 'x` edges that
271+
// were not part of the graph initially, so watch out for those.
272+
// (But they are extremely rare; this loop is very cold.)
273+
for constraint in self.applied_member_constraints(r) {
274+
let p_c = &self.member_constraints[constraint.member_constraint_index];
275+
let constraint = OutlivesConstraint {
276+
sup: r,
277+
sub: constraint.min_choice,
278+
locations: Locations::All(p_c.definition_span),
279+
category: ConstraintCategory::OpaqueType,
280+
};
281+
handle_constraint(constraint);
279282
}
280283
}
281284

src/librustc_mir/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
2525
#![feature(mem_take)]
2626
#![feature(associated_type_bounds)]
2727
#![feature(range_is_empty)]
28+
#![feature(stmt_expr_attributes)]
2829

2930
#![recursion_limit="256"]
3031

0 commit comments

Comments
 (0)