Skip to content

Use LazyBTreeMap for region constraints. #50491

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/librustc/infer/lexical_region_resolve/graphviz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ use middle::region;
use super::Constraint;
use infer::SubregionOrigin;
use infer::region_constraints::RegionConstraintData;
use rustc_data_structures::lazy_btree_map::LazyBTreeMap;
use util::nodemap::{FxHashMap, FxHashSet};

use std::borrow::Cow;
use std::collections::hash_map::Entry::Vacant;
use std::collections::btree_map::BTreeMap;
use std::env;
use std::fs::File;
use std::io;
Expand Down Expand Up @@ -124,7 +124,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
struct ConstraintGraph<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
graph_name: String,
region_rels: &'a RegionRelations<'a, 'gcx, 'tcx>,
map: &'a BTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
map: &'a LazyBTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this even be an FxHashMap?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If ConstraintGraph::map is changed to an FxHashMap, then all the other LazyBTreeMap instances in this patch have to change to an FxHashMap as well. Maybe that's what you're suggesting? The various BTreeMaps are iterated over in multiple places. I don't know if the iteration order is important, but I'm inclined to be conservative.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, Constraint just seems to have a derived Ord implementation, so the order might not be important. I don't know this code though.

node_ids: FxHashMap<Node, usize>,
}

Expand Down Expand Up @@ -264,7 +264,7 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
}
}

pub type ConstraintMap<'tcx> = BTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>;
pub type ConstraintMap<'tcx> = LazyBTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>;

fn dump_region_data_to<'a, 'gcx, 'tcx>(region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
map: &ConstraintMap<'tcx>,
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/infer/region_constraints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ use self::CombineMapType::*;
use super::{MiscVariable, RegionVariableOrigin, SubregionOrigin};
use super::unify_key;

use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use rustc_data_structures::lazy_btree_map::LazyBTreeMap;
use rustc_data_structures::unify as ut;
use ty::{self, Ty, TyCtxt};
use ty::{Region, RegionVid};
use ty::ReStatic;
use ty::{BrFresh, ReLateBound, ReVar};

use std::collections::BTreeMap;
use std::{cmp, fmt, mem, u32};

mod taint;
Expand Down Expand Up @@ -81,7 +81,7 @@ pub type VarInfos = IndexVec<RegionVid, RegionVariableInfo>;
pub struct RegionConstraintData<'tcx> {
/// Constraints of the form `A <= B`, where either `A` or `B` can
/// be a region variable (or neither, as it happens).
pub constraints: BTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
pub constraints: LazyBTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,

/// A "verify" is something that we need to verify after inference
/// is done, but which does not directly affect inference in any
Expand Down
43 changes: 43 additions & 0 deletions src/librustc_data_structures/lazy_btree_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::borrow::Borrow;
use std::collections::btree_map;
use std::collections::BTreeMap;

Expand Down Expand Up @@ -37,6 +38,10 @@ impl<K, V> LazyBTreeMap<K, V> {
pub fn is_empty(&self) -> bool {
self.0.as_ref().map_or(true, |btm| btm.is_empty())
}

pub fn len(&self) -> usize {
self.0.as_ref().map_or(0, |btm| btm.len())
}
}

impl<K: Ord, V> LazyBTreeMap<K, V> {
Expand All @@ -50,19 +55,43 @@ impl<K: Ord, V> LazyBTreeMap<K, V> {
}
}

pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V>
where K: Borrow<Q>,
Q: Ord
{
self.0.as_ref().and_then(|btm| btm.get(key))
}

pub fn insert(&mut self, key: K, value: V) -> Option<V> {
self.instantiate().insert(key, value)
}

pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
where K: Borrow<Q>,
Q: Ord
{
self.0.as_mut().and_then(|btm| btm.remove(key))
}

pub fn entry(&mut self, key: K) -> btree_map::Entry<K, V> {
self.instantiate().entry(key)
}

pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
Keys(self.0.as_ref().map(|btm| btm.keys()))
}

pub fn values<'a>(&'a self) -> Values<'a, K, V> {
Values(self.0.as_ref().map(|btm| btm.values()))
}
}

impl<K: Clone, V: Clone> Clone for LazyBTreeMap<K, V> {
fn clone(&self) -> Self {
LazyBTreeMap(self.0.as_ref().map(|map| map.clone()))
}
}

impl<K: Ord, V> Default for LazyBTreeMap<K, V> {
fn default() -> LazyBTreeMap<K, V> {
LazyBTreeMap::new()
Expand Down Expand Up @@ -92,6 +121,20 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> {
}
}

pub struct Keys<'a, K: 'a, V: 'a>(Option<btree_map::Keys<'a, K, V>>);

impl<'a, K, V> Iterator for Keys<'a, K, V> {
type Item = &'a K;

fn next(&mut self) -> Option<&'a K> {
self.0.as_mut().and_then(|keys| keys.next())
}

fn size_hint(&self) -> (usize, Option<usize>) {
self.0.as_ref().map_or_else(|| (0, Some(0)), |keys| keys.size_hint())
}
}

pub struct Values<'a, K: 'a, V: 'a>(Option<btree_map::Values<'a, K, V>>);

impl<'a, K, V> Iterator for Values<'a, K, V> {
Expand Down