mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
Subs efficiency
This commit is contained in:
parent
7bb367713c
commit
41e61ba38a
3 changed files with 50 additions and 44 deletions
|
@ -880,7 +880,7 @@ fn check_for_infinite_type(
|
||||||
let var = loc_var.value;
|
let var = loc_var.value;
|
||||||
|
|
||||||
let is_uniq_infer = matches!(
|
let is_uniq_infer = matches!(
|
||||||
subs.get(var).content,
|
subs.get_ref(var).content,
|
||||||
Content::Alias(Symbol::ATTR_ATTR, _, _)
|
Content::Alias(Symbol::ATTR_ATTR, _, _)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1088,7 +1088,7 @@ fn generalize(
|
||||||
for vars in all_but_last_pool {
|
for vars in all_but_last_pool {
|
||||||
for &var in vars {
|
for &var in vars {
|
||||||
if !subs.redundant(var) {
|
if !subs.redundant(var) {
|
||||||
let rank = subs.get(var).rank;
|
let rank = subs.get_rank(var);
|
||||||
|
|
||||||
pools.get_mut(rank).push(var);
|
pools.get_mut(rank).push(var);
|
||||||
}
|
}
|
||||||
|
@ -1099,13 +1099,12 @@ fn generalize(
|
||||||
// otherwise generalize
|
// otherwise generalize
|
||||||
for &var in last_pool {
|
for &var in last_pool {
|
||||||
if !subs.redundant(var) {
|
if !subs.redundant(var) {
|
||||||
let mut desc = subs.get(var);
|
let desc_rank = subs.get_rank(var);
|
||||||
|
|
||||||
if desc.rank < young_rank {
|
if desc_rank < young_rank {
|
||||||
pools.get_mut(desc.rank).push(var);
|
pools.get_mut(desc_rank).push(var);
|
||||||
} else {
|
} else {
|
||||||
desc.rank = Rank::NONE;
|
subs.set_rank(var, Rank::NONE);
|
||||||
subs.set(var, desc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1121,18 +1120,8 @@ fn pool_to_rank_table(
|
||||||
|
|
||||||
// Sort the variables into buckets by rank.
|
// Sort the variables into buckets by rank.
|
||||||
for &var in young_vars.iter() {
|
for &var in young_vars.iter() {
|
||||||
let desc = subs.get(var);
|
let rank = subs.get_rank(var);
|
||||||
let rank = desc.rank;
|
subs.set_mark(var, young_mark);
|
||||||
|
|
||||||
subs.set(
|
|
||||||
var,
|
|
||||||
Descriptor {
|
|
||||||
rank,
|
|
||||||
mark: young_mark,
|
|
||||||
content: desc.content,
|
|
||||||
copy: desc.copy,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
debug_assert!(rank.into_usize() < young_rank.into_usize() + 1);
|
debug_assert!(rank.into_usize() < young_rank.into_usize() + 1);
|
||||||
pools.get_mut(rank).push(var);
|
pools.get_mut(rank).push(var);
|
||||||
|
@ -1155,24 +1144,15 @@ fn adjust_rank(
|
||||||
if desc.mark == young_mark {
|
if desc.mark == young_mark {
|
||||||
let Descriptor {
|
let Descriptor {
|
||||||
content,
|
content,
|
||||||
rank,
|
rank: _,
|
||||||
mark: _,
|
mark: _,
|
||||||
copy,
|
copy,
|
||||||
} = desc;
|
} = desc;
|
||||||
|
|
||||||
// Mark the variable as visited before adjusting content, as it may be cyclic.
|
// Mark the variable as visited before adjusting content, as it may be cyclic.
|
||||||
subs.set(
|
subs.set_mark(var, visit_mark);
|
||||||
var,
|
|
||||||
Descriptor {
|
|
||||||
content: content.clone(),
|
|
||||||
rank,
|
|
||||||
mark: visit_mark,
|
|
||||||
copy,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let max_rank =
|
let max_rank = adjust_rank_content(subs, young_mark, visit_mark, group_rank, &content);
|
||||||
adjust_rank_content(subs, young_mark, visit_mark, group_rank, content.clone());
|
|
||||||
|
|
||||||
subs.set(
|
subs.set(
|
||||||
var,
|
var,
|
||||||
|
@ -1208,7 +1188,7 @@ fn adjust_rank_content(
|
||||||
young_mark: Mark,
|
young_mark: Mark,
|
||||||
visit_mark: Mark,
|
visit_mark: Mark,
|
||||||
group_rank: Rank,
|
group_rank: Rank,
|
||||||
content: Content,
|
content: &Content,
|
||||||
) -> Rank {
|
) -> Rank {
|
||||||
use roc_types::subs::Content::*;
|
use roc_types::subs::Content::*;
|
||||||
use roc_types::subs::FlatType::*;
|
use roc_types::subs::FlatType::*;
|
||||||
|
@ -1224,14 +1204,15 @@ fn adjust_rank_content(
|
||||||
let mut rank = Rank::toplevel();
|
let mut rank = Rank::toplevel();
|
||||||
|
|
||||||
for var in args {
|
for var in args {
|
||||||
rank = rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, var));
|
rank =
|
||||||
|
rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, *var));
|
||||||
}
|
}
|
||||||
|
|
||||||
rank
|
rank
|
||||||
}
|
}
|
||||||
|
|
||||||
Func(arg_vars, closure_var, ret_var) => {
|
Func(arg_vars, closure_var, ret_var) => {
|
||||||
let mut rank = adjust_rank(subs, young_mark, visit_mark, group_rank, ret_var);
|
let mut rank = adjust_rank(subs, young_mark, visit_mark, group_rank, *ret_var);
|
||||||
|
|
||||||
// TODO investigate further.
|
// TODO investigate further.
|
||||||
//
|
//
|
||||||
|
@ -1244,12 +1225,13 @@ fn adjust_rank_content(
|
||||||
young_mark,
|
young_mark,
|
||||||
visit_mark,
|
visit_mark,
|
||||||
group_rank,
|
group_rank,
|
||||||
closure_var,
|
*closure_var,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
for var in arg_vars {
|
for var in arg_vars {
|
||||||
rank = rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, var));
|
rank =
|
||||||
|
rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, *var));
|
||||||
}
|
}
|
||||||
|
|
||||||
rank
|
rank
|
||||||
|
@ -1263,7 +1245,7 @@ fn adjust_rank_content(
|
||||||
EmptyTagUnion => Rank::toplevel(),
|
EmptyTagUnion => Rank::toplevel(),
|
||||||
|
|
||||||
Record(fields, ext_var) => {
|
Record(fields, ext_var) => {
|
||||||
let mut rank = adjust_rank(subs, young_mark, visit_mark, group_rank, ext_var);
|
let mut rank = adjust_rank(subs, young_mark, visit_mark, group_rank, *ext_var);
|
||||||
|
|
||||||
for (_, var) in fields {
|
for (_, var) in fields {
|
||||||
rank = rank.max(adjust_rank(
|
rank = rank.max(adjust_rank(
|
||||||
|
@ -1279,7 +1261,7 @@ fn adjust_rank_content(
|
||||||
}
|
}
|
||||||
|
|
||||||
TagUnion(tags, ext_var) => {
|
TagUnion(tags, ext_var) => {
|
||||||
let mut rank = adjust_rank(subs, young_mark, visit_mark, group_rank, ext_var);
|
let mut rank = adjust_rank(subs, young_mark, visit_mark, group_rank, *ext_var);
|
||||||
|
|
||||||
for var in tags.values().flatten() {
|
for var in tags.values().flatten() {
|
||||||
rank =
|
rank =
|
||||||
|
@ -1290,9 +1272,9 @@ fn adjust_rank_content(
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveTagUnion(rec_var, tags, ext_var) => {
|
RecursiveTagUnion(rec_var, tags, ext_var) => {
|
||||||
let mut rank = adjust_rank(subs, young_mark, visit_mark, group_rank, rec_var);
|
let mut rank = adjust_rank(subs, young_mark, visit_mark, group_rank, *rec_var);
|
||||||
rank = rank.max(adjust_rank(
|
rank = rank.max(adjust_rank(
|
||||||
subs, young_mark, visit_mark, group_rank, ext_var,
|
subs, young_mark, visit_mark, group_rank, *ext_var,
|
||||||
));
|
));
|
||||||
|
|
||||||
for var in tags.values().flatten() {
|
for var in tags.values().flatten() {
|
||||||
|
@ -1305,10 +1287,11 @@ fn adjust_rank_content(
|
||||||
|
|
||||||
Boolean(Bool::Shared) => Rank::toplevel(),
|
Boolean(Bool::Shared) => Rank::toplevel(),
|
||||||
Boolean(Bool::Container(cvar, mvars)) => {
|
Boolean(Bool::Container(cvar, mvars)) => {
|
||||||
let mut rank = adjust_rank(subs, young_mark, visit_mark, group_rank, cvar);
|
let mut rank = adjust_rank(subs, young_mark, visit_mark, group_rank, *cvar);
|
||||||
|
|
||||||
for var in mvars {
|
for var in mvars {
|
||||||
rank = rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, var));
|
rank =
|
||||||
|
rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, *var));
|
||||||
}
|
}
|
||||||
|
|
||||||
rank
|
rank
|
||||||
|
@ -1322,13 +1305,13 @@ fn adjust_rank_content(
|
||||||
let mut rank = Rank::toplevel();
|
let mut rank = Rank::toplevel();
|
||||||
|
|
||||||
for (_, var) in args {
|
for (_, var) in args {
|
||||||
rank = rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, var));
|
rank = rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, *var));
|
||||||
}
|
}
|
||||||
|
|
||||||
// from elm-compiler: THEORY: anything in the real_var would be Rank::toplevel()
|
// from elm-compiler: THEORY: anything in the real_var would be Rank::toplevel()
|
||||||
// this theory is not true in Roc! aliases of function types capture the closure var
|
// this theory is not true in Roc! aliases of function types capture the closure var
|
||||||
rank = rank.max(adjust_rank(
|
rank = rank.max(adjust_rank(
|
||||||
subs, young_mark, visit_mark, group_rank, real_var,
|
subs, young_mark, visit_mark, group_rank, *real_var,
|
||||||
));
|
));
|
||||||
|
|
||||||
rank
|
rank
|
||||||
|
|
|
@ -306,6 +306,18 @@ impl Subs {
|
||||||
self.utable.probe_value(key)
|
self.utable.probe_value(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_ref(&self, key: Variable) -> &Descriptor {
|
||||||
|
&self.utable.probe_value_ref(key).value
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_rank(&mut self, key: Variable) -> Rank {
|
||||||
|
self.utable.probe_value_ref(key).value.rank
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_mark(&mut self, key: Variable) -> Mark {
|
||||||
|
self.utable.probe_value_ref(key).value.mark
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_without_compacting(&self, key: Variable) -> Descriptor {
|
pub fn get_without_compacting(&self, key: Variable) -> Descriptor {
|
||||||
self.utable.probe_value_without_compacting(key)
|
self.utable.probe_value_without_compacting(key)
|
||||||
}
|
}
|
||||||
|
|
11
vendor/ena/src/unify/mod.rs
vendored
11
vendor/ena/src/unify/mod.rs
vendored
|
@ -433,6 +433,17 @@ where
|
||||||
self.value(id).value.clone()
|
self.value(id).value.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the current value for the given key. If the key has
|
||||||
|
/// been union'd, this will give the value from the current root.
|
||||||
|
pub fn probe_value_ref<K1>(&self, id: K1) -> &VarValue<K>
|
||||||
|
where
|
||||||
|
K1: Into<K>,
|
||||||
|
{
|
||||||
|
let id = id.into();
|
||||||
|
let id = self.get_root_key_without_compacting(id);
|
||||||
|
self.value(id)
|
||||||
|
}
|
||||||
|
|
||||||
/// This is for a debug_assert! in solve() only. Do not use it elsewhere!
|
/// This is for a debug_assert! in solve() only. Do not use it elsewhere!
|
||||||
pub fn probe_value_without_compacting<K1>(&self, id: K1) -> V
|
pub fn probe_value_without_compacting<K1>(&self, id: K1) -> V
|
||||||
where
|
where
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue