fix complexity of type merging in bytecode optimizer

Merge a smaller table into a larger one to avoid an overall
quadratic-time computation.
This commit is contained in:
Matthew Flatt 2017-06-08 06:33:58 -06:00
parent 5cfe5619de
commit ff26c2f29b
2 changed files with 23 additions and 3 deletions

View File

@ -5431,6 +5431,8 @@ static void add_type_no(Optimize_Info *info, Scheme_Object *var, Scheme_Object *
}
}
static void merge_types(Optimize_Info *src_info, Optimize_Info *info, Scheme_Hash_Tree *skip_vars)
{
Scheme_Hash_Tree *types = src_info->types;
@ -5439,12 +5441,30 @@ static void merge_types(Optimize_Info *src_info, Optimize_Info *info, Scheme_Has
if (!types)
return;
if (skip_vars) {
/* Remove variables from `types` that we're supposed to skip */
i = scheme_hash_tree_next(skip_vars, -1);
while (i != -1) {
scheme_hash_tree_index(types, i, &var, NULL);
scheme_hash_tree_set(types, var, NULL);
i = scheme_hash_tree_next(skip_vars, i);
}
}
if (!info->types || (types->count > info->types->count)) {
/* It will be faster to merge the old table into the new one: */
Scheme_Hash_Tree *old_types = info->types;
info->types = types;
if (!old_types)
return;
types = old_types;
}
i = scheme_hash_tree_next(types, -1);
while (i != -1) {
scheme_hash_tree_index(types, i, &var, &pred);
if (!skip_vars || !scheme_hash_tree_get(skip_vars, var))
add_type(info, var, pred);
add_type(info, var, pred);
i = scheme_hash_tree_next(types, i);
}
}

View File

@ -148,7 +148,7 @@ void (*scheme_push_break_enable)(Scheme_Cont_Frame_Data *cframe, int on, int pre
void (*scheme_pop_break_enable)(Scheme_Cont_Frame_Data *cframe, int post_check);
Scheme_Object *(*scheme_abort_continuation_no_dws)(Scheme_Object *pt, Scheme_Object *v);
Scheme_Object *(*scheme_call_with_composable_no_dws)(Scheme_Object *proc, Scheme_Object *pt);
Scheme_On_Atomic_Timeout_Proc (*scheme_set_on_atomic_timeout)(Scheme_On_Atomic_Timeout_Proc p);
Scheme_On_Atomic_Timeout_Proc (*scheme_set_on_atomic_timeout)(Scheme_On_Atomic_Timeout_Proc p, void *data);
/*========================================================================*/
/* error handling */
/*========================================================================*/