Skip to content

Commit e499e7a

Browse files
committed
Auto merge of #118824 - aliemjay:perf-region-cons, r=<try>
use Vec for region constraints instead of BTreeMap ~1% perf gain Diagnostic regressions need more investigation. r? `@ghost`
2 parents d253bf6 + f388f23 commit e499e7a

File tree

11 files changed

+87
-120
lines changed

11 files changed

+87
-120
lines changed

compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
137137
) -> LexicalRegionResolutions<'tcx> {
138138
let mut var_data = self.construct_var_data();
139139

140+
self.data.constraints.sort_by_key(|(constraint, _)| *constraint);
141+
self.data.constraints.dedup_by_key(|(constraint, _)| *constraint);
142+
140143
if cfg!(debug_assertions) {
141144
self.dump_constraints();
142145
}
@@ -183,7 +186,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
183186
let mut constraints = IndexVec::from_elem(Vec::new(), &var_values.values);
184187
// Tracks the changed region vids.
185188
let mut changes = Vec::new();
186-
for constraint in self.data.constraints.keys() {
189+
for (constraint, _) in &self.data.constraints {
187190
match *constraint {
188191
Constraint::RegSubVar(a_region, b_vid) => {
189192
let b_data = var_values.value_mut(b_vid);
@@ -678,7 +681,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
678681
let dummy_source = graph.add_node(());
679682
let dummy_sink = graph.add_node(());
680683

681-
for constraint in self.data.constraints.keys() {
684+
for (constraint, _) in &self.data.constraints {
682685
match *constraint {
683686
Constraint::VarSubVar(a_id, b_id) => {
684687
graph.add_edge(NodeIndex(a_id.index()), NodeIndex(b_id.index()), *constraint);
@@ -885,9 +888,11 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
885888
}
886889

887890
Constraint::RegSubVar(region, _) | Constraint::VarSubReg(_, region) => {
891+
let constraint_idx =
892+
this.constraints.binary_search_by_key(&edge.data, |(c, _)| *c).unwrap();
888893
state.result.push(RegionAndOrigin {
889894
region,
890-
origin: this.constraints.get(&edge.data).unwrap().clone(),
895+
origin: this.constraints[constraint_idx].1.clone(),
891896
});
892897
}
893898

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine, Tr
1818
use rustc_data_structures::fx::FxIndexMap;
1919
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
2020
use rustc_data_structures::sync::Lrc;
21-
use rustc_data_structures::undo_log::Rollback;
2221
use rustc_data_structures::unify as ut;
2322
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
2423
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -919,7 +918,7 @@ impl<'tcx> InferCtxt<'tcx> {
919918
self.inner
920919
.borrow_mut()
921920
.unwrap_region_constraints()
922-
.region_constraints_added_in_snapshot(&snapshot.undo_snapshot)
921+
.region_constraints_added_in_snapshot(&snapshot.region_constraints_snapshot)
923922
}
924923

925924
pub fn opaque_types_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'tcx>) -> bool {

compiler/rustc_infer/src/infer/region_constraints/leak_check.rs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -412,26 +412,15 @@ impl<'tcx> MiniGraph<'tcx> {
412412
};
413413

414414
if let Some(snapshot) = only_consider_snapshot {
415-
for undo_entry in
416-
region_constraints.undo_log.region_constraints_in_snapshot(&snapshot.undo_snapshot)
417-
{
418-
match undo_entry {
419-
AddConstraint(constraint) => {
420-
each_constraint(constraint);
421-
}
422-
&AddVerify(i) => span_bug!(
423-
region_constraints.data().verifys[i].origin.span(),
424-
"we never add verifications while doing higher-ranked things",
425-
),
426-
&AddCombination(..) | &AddVar(..) => {}
427-
}
428-
}
415+
region_constraints
416+
.region_constraints_in_snapshot(&snapshot.region_constraints_snapshot)
417+
.for_each(each_constraint);
429418
} else {
430419
region_constraints
431420
.data()
432421
.constraints
433-
.keys()
434-
.for_each(|constraint| each_constraint(constraint));
422+
.iter()
423+
.for_each(|(constraint, _)| each_constraint(constraint));
435424
}
436425
}
437426

compiler/rustc_infer/src/infer/region_constraints/mod.rs

Lines changed: 43 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
//! See `README.md`.
22
33
use self::CombineMapType::*;
4-
use self::UndoLog::*;
54

6-
use super::{
7-
InferCtxtUndoLogs, MiscVariable, RegionVariableOrigin, Rollback, Snapshot, SubregionOrigin,
8-
};
5+
use super::{InferCtxtUndoLogs, MiscVariable, RegionVariableOrigin, SubregionOrigin};
96

10-
use rustc_data_structures::fx::FxHashMap;
7+
use rustc_data_structures::fx::FxIndexMap;
118
use rustc_data_structures::intern::Interned;
129
use rustc_data_structures::sync::Lrc;
1310
use rustc_data_structures::undo_log::UndoLogs;
@@ -20,7 +17,6 @@ use rustc_middle::ty::{ReBound, ReVar};
2017
use rustc_middle::ty::{Region, RegionVid};
2118
use rustc_span::Span;
2219

23-
use std::collections::BTreeMap;
2420
use std::ops::Range;
2521
use std::{cmp, fmt, mem};
2622

@@ -90,7 +86,7 @@ pub type VarInfos = IndexVec<RegionVid, RegionVariableInfo>;
9086
pub struct RegionConstraintData<'tcx> {
9187
/// Constraints of the form `A <= B`, where either `A` or `B` can
9288
/// be a region variable (or neither, as it happens).
93-
pub constraints: BTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
89+
pub constraints: Vec<(Constraint<'tcx>, SubregionOrigin<'tcx>)>,
9490

9591
/// Constraints of the form `R0 member of [R1, ..., Rn]`, meaning that
9692
/// `R0` must be equal to one of the regions `R1..Rn`. These occur
@@ -267,28 +263,13 @@ pub(crate) struct TwoRegions<'tcx> {
267263
b: Region<'tcx>,
268264
}
269265

270-
#[derive(Copy, Clone, PartialEq)]
271-
pub(crate) enum UndoLog<'tcx> {
272-
/// We added `RegionVid`.
273-
AddVar(RegionVid),
274-
275-
/// We added the given `constraint`.
276-
AddConstraint(Constraint<'tcx>),
277-
278-
/// We added the given `verify`.
279-
AddVerify(usize),
280-
281-
/// We added a GLB/LUB "combination variable".
282-
AddCombination(CombineMapType, TwoRegions<'tcx>),
283-
}
284-
285266
#[derive(Copy, Clone, PartialEq)]
286267
pub(crate) enum CombineMapType {
287268
Lub,
288269
Glb,
289270
}
290271

291-
type CombineMap<'tcx> = FxHashMap<TwoRegions<'tcx>, RegionVid>;
272+
type CombineMap<'tcx> = FxIndexMap<TwoRegions<'tcx>, RegionVid>;
292273

293274
#[derive(Debug, Clone, Copy)]
294275
pub struct RegionVariableInfo {
@@ -298,6 +279,11 @@ pub struct RegionVariableInfo {
298279

299280
pub struct RegionSnapshot {
300281
any_unifications: bool,
282+
vars_len: usize,
283+
constraints_len: usize,
284+
verifys_len: usize,
285+
glbs_len: usize,
286+
lubs_len: usize,
301287
}
302288

303289
impl<'tcx> RegionConstraintStorage<'tcx> {
@@ -312,28 +298,6 @@ impl<'tcx> RegionConstraintStorage<'tcx> {
312298
) -> RegionConstraintCollector<'a, 'tcx> {
313299
RegionConstraintCollector { storage: self, undo_log }
314300
}
315-
316-
fn rollback_undo_entry(&mut self, undo_entry: UndoLog<'tcx>) {
317-
match undo_entry {
318-
AddVar(vid) => {
319-
self.var_infos.pop().unwrap();
320-
assert_eq!(self.var_infos.len(), vid.index());
321-
}
322-
AddConstraint(ref constraint) => {
323-
self.data.constraints.remove(constraint);
324-
}
325-
AddVerify(index) => {
326-
self.data.verifys.pop();
327-
assert_eq!(self.data.verifys.len(), index);
328-
}
329-
AddCombination(Glb, ref regions) => {
330-
self.glbs.remove(regions);
331-
}
332-
AddCombination(Lub, ref regions) => {
333-
self.lubs.remove(regions);
334-
}
335-
}
336-
}
337301
}
338302

339303
impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
@@ -407,12 +371,32 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
407371

408372
pub(super) fn start_snapshot(&mut self) -> RegionSnapshot {
409373
debug!("RegionConstraintCollector: start_snapshot");
410-
RegionSnapshot { any_unifications: self.any_unifications }
374+
RegionSnapshot {
375+
any_unifications: self.any_unifications,
376+
vars_len: self.var_infos.len(),
377+
constraints_len: self.data.constraints.len(),
378+
verifys_len: self.data.verifys.len(),
379+
glbs_len: self.glbs.len(),
380+
lubs_len: self.lubs.len(),
381+
}
411382
}
412383

413384
pub(super) fn rollback_to(&mut self, snapshot: RegionSnapshot) {
414385
debug!("RegionConstraintCollector: rollback_to({:?})", snapshot);
415-
self.any_unifications = snapshot.any_unifications;
386+
let RegionSnapshot {
387+
any_unifications,
388+
vars_len,
389+
constraints_len,
390+
verifys_len,
391+
glbs_len,
392+
lubs_len,
393+
} = snapshot;
394+
self.any_unifications = any_unifications;
395+
self.var_infos.truncate(vars_len);
396+
self.data.constraints.truncate(constraints_len);
397+
self.data.verifys.truncate(verifys_len);
398+
self.glbs.truncate(glbs_len);
399+
self.lubs.truncate(lubs_len);
416400
}
417401

418402
pub(super) fn new_region_var(
@@ -424,7 +408,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
424408

425409
let u_vid = self.unification_table_mut().new_key(UnifiedRegion::new(None));
426410
assert_eq!(vid, u_vid.vid);
427-
self.undo_log.push(AddVar(vid));
428411
debug!("created new region variable {:?} in {:?} with origin {:?}", vid, universe, origin);
429412
vid
430413
}
@@ -442,15 +425,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
442425
fn add_constraint(&mut self, constraint: Constraint<'tcx>, origin: SubregionOrigin<'tcx>) {
443426
// cannot add constraints once regions are resolved
444427
debug!("RegionConstraintCollector: add_constraint({:?})", constraint);
445-
446-
// never overwrite an existing (constraint, origin) - only insert one if it isn't
447-
// present in the map yet. This prevents origins from outside the snapshot being
448-
// replaced with "less informative" origins e.g., during calls to `can_eq`
449-
let undo_log = &mut self.undo_log;
450-
self.storage.data.constraints.entry(constraint).or_insert_with(|| {
451-
undo_log.push(AddConstraint(constraint));
452-
origin
453-
});
428+
self.storage.data.constraints.push((constraint, origin));
454429
}
455430

456431
fn add_verify(&mut self, verify: Verify<'tcx>) {
@@ -464,9 +439,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
464439
return;
465440
}
466441

467-
let index = self.data.verifys.len();
468442
self.data.verifys.push(verify);
469-
self.undo_log.push(AddVerify(index));
470443
}
471444

472445
pub(super) fn make_eqregion(
@@ -638,6 +611,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
638611
b: Region<'tcx>,
639612
origin: SubregionOrigin<'tcx>,
640613
) -> Region<'tcx> {
614+
//assert!(!UndoLogs::<super::UndoLog<'_>>::in_snapshot(&self.undo_log));
641615
let vars = TwoRegions { a, b };
642616
if let Some(&c) = self.combine_map(t).get(&vars) {
643617
return ty::Region::new_var(tcx, c);
@@ -647,7 +621,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
647621
let c_universe = cmp::max(a_universe, b_universe);
648622
let c = self.new_region_var(c_universe, MiscVariable(origin.span()));
649623
self.combine_map(t).insert(vars, c);
650-
self.undo_log.push(AddCombination(t, vars));
651624
let new_r = ty::Region::new_var(tcx, c);
652625
for old_r in [a, b] {
653626
match t {
@@ -686,10 +659,16 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
686659
}
687660

688661
/// See `InferCtxt::region_constraints_added_in_snapshot`.
689-
pub fn region_constraints_added_in_snapshot(&self, mark: &Snapshot<'tcx>) -> bool {
690-
self.undo_log
691-
.region_constraints_in_snapshot(mark)
692-
.any(|&elt| matches!(elt, AddConstraint(_)))
662+
pub fn region_constraints_added_in_snapshot(&self, snapshot: &RegionSnapshot) -> bool {
663+
self.data.constraints.len() != snapshot.constraints_len
664+
}
665+
666+
fn region_constraints_in_snapshot(
667+
&self,
668+
snapshot: &RegionSnapshot,
669+
) -> impl Iterator<Item = &Constraint<'tcx>> {
670+
assert_eq!(snapshot.verifys_len, self.data.verifys.len());
671+
self.data.constraints[snapshot.constraints_len..].iter().map(|(constraint, _)| constraint)
693672
}
694673

695674
#[inline]
@@ -774,9 +753,3 @@ impl<'tcx> RegionConstraintData<'tcx> {
774753
constraints.is_empty() && member_constraints.is_empty() && verifys.is_empty()
775754
}
776755
}
777-
778-
impl<'tcx> Rollback<UndoLog<'tcx>> for RegionConstraintStorage<'tcx> {
779-
fn reverse(&mut self, undo: UndoLog<'tcx>) {
780-
self.rollback_undo_entry(undo)
781-
}
782-
}

compiler/rustc_infer/src/infer/undo_log.rs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey, RegionVidKey};
77
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey};
88

99
use crate::{
10-
infer::{region_constraints, type_variable, InferCtxtInner},
10+
infer::{type_variable, InferCtxtInner},
1111
traits,
1212
};
1313

@@ -25,7 +25,6 @@ pub(crate) enum UndoLog<'tcx> {
2525
IntUnificationTable(sv::UndoLog<ut::Delegate<ty::IntVid>>),
2626
FloatUnificationTable(sv::UndoLog<ut::Delegate<ty::FloatVid>>),
2727
EffectUnificationTable(sv::UndoLog<ut::Delegate<EffectVidKey<'tcx>>>),
28-
RegionConstraintCollector(region_constraints::UndoLog<'tcx>),
2928
RegionUnificationTable(sv::UndoLog<ut::Delegate<RegionVidKey<'tcx>>>),
3029
ProjectionCache(traits::UndoLog<'tcx>),
3130
PushRegionObligation,
@@ -45,7 +44,6 @@ macro_rules! impl_from {
4544

4645
// Upcast from a single kind of "undoable action" to the general enum
4746
impl_from! {
48-
RegionConstraintCollector(region_constraints::UndoLog<'tcx>),
4947
TypeVariables(type_variable::UndoLog<'tcx>),
5048

5149
TypeVariables(sv::UndoLog<ut::Delegate<type_variable::TyVidEqKey<'tcx>>>),
@@ -72,9 +70,6 @@ impl<'tcx> Rollback<UndoLog<'tcx>> for InferCtxtInner<'tcx> {
7270
UndoLog::IntUnificationTable(undo) => self.int_unification_storage.reverse(undo),
7371
UndoLog::FloatUnificationTable(undo) => self.float_unification_storage.reverse(undo),
7472
UndoLog::EffectUnificationTable(undo) => self.effect_unification_storage.reverse(undo),
75-
UndoLog::RegionConstraintCollector(undo) => {
76-
self.region_constraint_storage.as_mut().unwrap().reverse(undo)
77-
}
7873
UndoLog::RegionUnificationTable(undo) => {
7974
self.region_constraint_storage.as_mut().unwrap().unification_table.reverse(undo)
8075
}
@@ -170,16 +165,6 @@ impl<'tcx> InferCtxtUndoLogs<'tcx> {
170165
Snapshot { undo_len: self.logs.len(), _marker: PhantomData }
171166
}
172167

173-
pub(crate) fn region_constraints_in_snapshot(
174-
&self,
175-
s: &Snapshot<'tcx>,
176-
) -> impl Iterator<Item = &'_ region_constraints::UndoLog<'tcx>> + Clone {
177-
self.logs[s.undo_len..].iter().filter_map(|log| match log {
178-
UndoLog::RegionConstraintCollector(log) => Some(log),
179-
_ => None,
180-
})
181-
}
182-
183168
pub(crate) fn opaque_types_in_snapshot(&self, s: &Snapshot<'tcx>) -> bool {
184169
self.logs[s.undo_len..].iter().any(|log| matches!(log, UndoLog::OpaqueTypes(..)))
185170
}

compiler/rustc_trait_selection/src/traits/auto_trait.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
477477
let mut vid_map: FxHashMap<RegionTarget<'cx>, RegionDeps<'cx>> = FxHashMap::default();
478478
let mut finished_map = FxHashMap::default();
479479

480-
for constraint in regions.constraints.keys() {
480+
for (constraint, _) in &regions.constraints {
481481
match constraint {
482482
&Constraint::VarSubVar(r1, r2) => {
483483
{

src/librustdoc/clean/auto_trait.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ where
195195
// into a map. Each RegionTarget (either a RegionVid or a Region) maps
196196
// to its smaller and larger regions. Note that 'larger' regions correspond
197197
// to sub-regions in Rust code (e.g., in 'a: 'b, 'a is the larger region).
198-
for constraint in regions.constraints.keys() {
198+
for (constraint, _) in &regions.constraints {
199199
match *constraint {
200200
Constraint::VarSubVar(r1, r2) => {
201201
{

tests/ui/higher-ranked/higher-ranked-lifetime-error.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
44
LL | assert_all::<_, &String>(id);
55
| ^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
66
|
7-
= note: expected reference `&String`
8-
found reference `&String`
7+
= note: expected trait `for<'a> <for<'a> fn(&'a String) -> &'a String {id} as FnMut<(&'a String,)>>`
8+
found trait `for<'a> <for<'a> fn(&'a String) -> &'a String {id} as FnMut<(&'a String,)>>`
99

1010
error: aborting due to 1 previous error
1111

0 commit comments

Comments
 (0)