intern common tag names

This commit is contained in:
Folkert 2022-03-20 15:30:47 +01:00
parent 00ef997be3
commit 38c2710fc5
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
2 changed files with 62 additions and 21 deletions

View file

@ -1850,6 +1850,29 @@ fn find_tag_name_run<T>(slice: &[(TagName, T)], subs: &mut Subs) -> Option<SubsS
result result
} }
#[inline(always)]
fn register_tag_arguments<'a>(
subs: &mut Subs,
rank: Rank,
pools: &mut Pools,
arena: &'_ bumpalo::Bump,
stack: &mut bumpalo::collections::Vec<'_, TypeToVar<'a>>,
arguments: &'a [Type],
) -> VariableSubsSlice {
if arguments.is_empty() {
VariableSubsSlice::default()
} else {
let new_variables = VariableSubsSlice::reserve_into_subs(subs, arguments.len());
let it = (new_variables.indices()).zip(arguments);
for (target_index, argument) in it {
let var = RegisterVariable::with_stack(subs, rank, pools, arena, argument, stack);
subs.variables[target_index] = var;
}
new_variables
}
}
/// Assumes that the tags are sorted and there are no duplicates! /// Assumes that the tags are sorted and there are no duplicates!
fn insert_tags_fast_path<'a>( fn insert_tags_fast_path<'a>(
subs: &mut Subs, subs: &mut Subs,
@ -1859,23 +1882,35 @@ fn insert_tags_fast_path<'a>(
tags: &'a [(TagName, Vec<Type>)], tags: &'a [(TagName, Vec<Type>)],
stack: &mut bumpalo::collections::Vec<'_, TypeToVar<'a>>, stack: &mut bumpalo::collections::Vec<'_, TypeToVar<'a>>,
) -> UnionTags { ) -> UnionTags {
let new_variable_slices = SubsSlice::reserve_variable_slices(subs, tags.len()); if let [(TagName::Global(tag_name), arguments)] = tags {
let variable_slice = register_tag_arguments(subs, rank, pools, arena, stack, arguments);
let new_variable_slices =
SubsSlice::extend_new(&mut subs.variable_slices, [variable_slice]);
macro_rules! subs_tag_name {
($tag_name_slice:expr) => {
return UnionTags::from_slices($tag_name_slice, new_variable_slices)
};
}
match tag_name.as_str() {
"Ok" => subs_tag_name!(Subs::TAG_NAME_OK.as_slice()),
"Err" => subs_tag_name!(Subs::TAG_NAME_ERR.as_slice()),
"InvalidNumStr" => subs_tag_name!(Subs::TAG_NAME_INVALID_NUM_STR.as_slice()),
"BadUtf8" => subs_tag_name!(Subs::TAG_NAME_BAD_UTF_8.as_slice()),
"OutOfBounds" => subs_tag_name!(Subs::TAG_NAME_OUT_OF_BOUNDS.as_slice()),
_other => {}
}
}
let new_variable_slices = SubsSlice::reserve_variable_slices(subs, tags.len());
match find_tag_name_run(tags, subs) { match find_tag_name_run(tags, subs) {
Some(new_tag_names) => { Some(new_tag_names) => {
let it = (new_variable_slices.indices()).zip(tags); let it = (new_variable_slices.indices()).zip(tags);
for (variable_slice_index, (_, arguments)) in it { for (variable_slice_index, (_, arguments)) in it {
// turn the arguments into variables subs.variable_slices[variable_slice_index] =
let new_variables = VariableSubsSlice::reserve_into_subs(subs, arguments.len()); register_tag_arguments(subs, rank, pools, arena, stack, arguments);
let it = (new_variables.indices()).zip(arguments);
for (target_index, argument) in it {
let var =
RegisterVariable::with_stack(subs, rank, pools, arena, argument, stack);
subs.variables[target_index] = var;
}
subs.variable_slices[variable_slice_index] = new_variables;
} }
UnionTags::from_slices(new_tag_names, new_variable_slices) UnionTags::from_slices(new_tag_names, new_variable_slices)
@ -1888,16 +1923,9 @@ fn insert_tags_fast_path<'a>(
.zip(tags); .zip(tags);
for ((variable_slice_index, tag_name_index), (tag_name, arguments)) in it { for ((variable_slice_index, tag_name_index), (tag_name, arguments)) in it {
// turn the arguments into variables subs.variable_slices[variable_slice_index] =
let new_variables = VariableSubsSlice::reserve_into_subs(subs, arguments.len()); register_tag_arguments(subs, rank, pools, arena, stack, arguments);
let it = (new_variables.indices()).zip(arguments);
for (target_index, argument) in it {
let var =
RegisterVariable::with_stack(subs, rank, pools, arena, argument, stack);
subs.variables[target_index] = var;
}
subs.variable_slices[variable_slice_index] = new_variables;
subs.tag_names[tag_name_index] = tag_name.clone(); subs.tag_names[tag_name_index] = tag_name.clone();
} }

View file

@ -331,7 +331,7 @@ impl SubsSlice<TagName> {
} }
impl<T> SubsIndex<T> { impl<T> SubsIndex<T> {
pub fn new(start: u32) -> Self { pub const fn new(start: u32) -> Self {
Self { Self {
index: start, index: start,
_marker: std::marker::PhantomData, _marker: std::marker::PhantomData,
@ -345,6 +345,10 @@ impl<T> SubsIndex<T> {
index index
} }
pub const fn as_slice(self) -> SubsSlice<T> {
SubsSlice::new(self.index, 1)
}
} }
impl<T> IntoIterator for SubsSlice<T> { impl<T> IntoIterator for SubsSlice<T> {
@ -1291,9 +1295,14 @@ fn define_float_types(subs: &mut Subs) {
impl Subs { impl Subs {
pub const RESULT_TAG_NAMES: SubsSlice<TagName> = SubsSlice::new(0, 2); pub const RESULT_TAG_NAMES: SubsSlice<TagName> = SubsSlice::new(0, 2);
pub const TAG_NAME_ERR: SubsIndex<TagName> = SubsIndex::new(0);
pub const TAG_NAME_OK: SubsIndex<TagName> = SubsIndex::new(1);
pub const NUM_AT_NUM: SubsSlice<TagName> = SubsSlice::new(2, 1); pub const NUM_AT_NUM: SubsSlice<TagName> = SubsSlice::new(2, 1);
pub const NUM_AT_INTEGER: SubsSlice<TagName> = SubsSlice::new(3, 1); pub const NUM_AT_INTEGER: SubsSlice<TagName> = SubsSlice::new(3, 1);
pub const NUM_AT_FLOATINGPOINT: SubsSlice<TagName> = SubsSlice::new(4, 1); pub const NUM_AT_FLOATINGPOINT: SubsSlice<TagName> = SubsSlice::new(4, 1);
pub const TAG_NAME_INVALID_NUM_STR: SubsIndex<TagName> = SubsIndex::new(5);
pub const TAG_NAME_BAD_UTF_8: SubsIndex<TagName> = SubsIndex::new(6);
pub const TAG_NAME_OUT_OF_BOUNDS: SubsIndex<TagName> = SubsIndex::new(7);
pub fn new() -> Self { pub fn new() -> Self {
Self::with_capacity(0) Self::with_capacity(0)
@ -1311,6 +1320,10 @@ impl Subs {
tag_names.push(TagName::Private(Symbol::NUM_AT_INTEGER)); tag_names.push(TagName::Private(Symbol::NUM_AT_INTEGER));
tag_names.push(TagName::Private(Symbol::NUM_AT_FLOATINGPOINT)); tag_names.push(TagName::Private(Symbol::NUM_AT_FLOATINGPOINT));
tag_names.push(TagName::Global("InvalidNumStr".into()));
tag_names.push(TagName::Global("BadUtf8".into()));
tag_names.push(TagName::Global("OutOfBounds".into()));
let mut subs = Subs { let mut subs = Subs {
utable: UnificationTable::default(), utable: UnificationTable::default(),
variables: Vec::new(), variables: Vec::new(),