Use a sub_info to optimize branches
Create a new sub_info for each branch to hold the type information of the local variables, instead of handling the types manually.
This commit is contained in:
parent
5031897c51
commit
3f246dd857
|
@ -4218,19 +4218,21 @@ static void merge_types(Optimize_Info *src_info, Optimize_Info *info, int delta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scheme_Hash_Tree *intersect_and_merge_types(Scheme_Hash_Tree *t_types, Scheme_Hash_Tree *f_types,
|
static void intersect_and_merge_types(Optimize_Info *t_info, Optimize_Info *f_info,
|
||||||
Scheme_Hash_Tree *base_types)
|
Optimize_Info *base_info)
|
||||||
/* return (union (intersetion t_type f_types) base_types)
|
/* return (union (intersetion t_type f_types) base_types)
|
||||||
in case a key is already in base_type, the value is not modified*/
|
in case a key is already in base_type, the value is not modified*/
|
||||||
{
|
{
|
||||||
|
Scheme_Hash_Tree *t_types = t_info->types, *f_types = f_info->types,
|
||||||
|
*base_types = base_info->types;
|
||||||
Scheme_Object *pos, *t_pred, *f_pred, *base_pred;
|
Scheme_Object *pos, *t_pred, *f_pred, *base_pred;
|
||||||
intptr_t i;
|
intptr_t i;
|
||||||
|
|
||||||
if (!t_types || !f_types)
|
if (!t_types || !f_types)
|
||||||
return base_types;
|
return;
|
||||||
|
|
||||||
if (base_types && (SAME_OBJ(f_types, base_types) || SAME_OBJ(t_types, base_types)))
|
if (base_types && (SAME_OBJ(f_types, base_types) || SAME_OBJ(t_types, base_types)))
|
||||||
return base_types;
|
return;
|
||||||
|
|
||||||
if (f_types->count > t_types->count) {
|
if (f_types->count > t_types->count) {
|
||||||
Scheme_Hash_Tree *swap = f_types;
|
Scheme_Hash_Tree *swap = f_types;
|
||||||
|
@ -4256,7 +4258,7 @@ Scheme_Hash_Tree *intersect_and_merge_types(Scheme_Hash_Tree *t_types, Scheme_Ha
|
||||||
}
|
}
|
||||||
i = scheme_hash_tree_next(f_types, i);
|
i = scheme_hash_tree_next(f_types, i);
|
||||||
}
|
}
|
||||||
return base_types;
|
base_info->types = base_types;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int relevant_predicate(Scheme_Object *pred)
|
static int relevant_predicate(Scheme_Object *pred)
|
||||||
|
@ -4373,10 +4375,8 @@ static Scheme_Object *optimize_branch(Scheme_Object *o, Optimize_Info *info, int
|
||||||
{
|
{
|
||||||
Scheme_Branch_Rec *b;
|
Scheme_Branch_Rec *b;
|
||||||
Scheme_Object *t, *tb, *fb;
|
Scheme_Object *t, *tb, *fb;
|
||||||
Scheme_Hash_Tree *init_types, *then_types;
|
|
||||||
int init_vclock, init_aclock, init_kclock, init_sclock;
|
int init_vclock, init_aclock, init_kclock, init_sclock;
|
||||||
int then_escapes, then_preserves_marks, then_single_result;
|
Optimize_Info *then_info, *else_info;
|
||||||
int then_vclock, then_aclock, then_kclock, then_sclock;
|
|
||||||
Optimize_Info_Sequence info_seq;
|
Optimize_Info_Sequence info_seq;
|
||||||
Scheme_Object *pred;
|
Scheme_Object *pred;
|
||||||
|
|
||||||
|
@ -4492,22 +4492,13 @@ static Scheme_Object *optimize_branch(Scheme_Object *o, Optimize_Info *info, int
|
||||||
init_aclock = info->aclock;
|
init_aclock = info->aclock;
|
||||||
init_kclock = info->kclock;
|
init_kclock = info->kclock;
|
||||||
init_sclock = info->sclock;
|
init_sclock = info->sclock;
|
||||||
init_types = info->types;
|
|
||||||
|
|
||||||
add_types_for_t_branch(t, info, 5);
|
then_info = optimize_info_add_frame(info, 0, 0, 0);
|
||||||
|
add_types_for_t_branch(t, then_info, 5);
|
||||||
|
tb = scheme_optimize_expr(tb, then_info, scheme_optimize_tail_context(context));
|
||||||
|
optimize_info_done(then_info, NULL);
|
||||||
|
|
||||||
tb = scheme_optimize_expr(tb, info, scheme_optimize_tail_context(context));
|
info->escapes = 0;
|
||||||
|
|
||||||
then_types = info->types;
|
|
||||||
then_preserves_marks = info->preserves_marks;
|
|
||||||
then_single_result = info->single_result;
|
|
||||||
then_escapes = info->escapes;
|
|
||||||
then_vclock = info->vclock;
|
|
||||||
then_aclock = info->aclock;
|
|
||||||
then_kclock = info->kclock;
|
|
||||||
then_sclock = info->sclock;
|
|
||||||
|
|
||||||
info->types = init_types;
|
|
||||||
info->vclock = init_vclock;
|
info->vclock = init_vclock;
|
||||||
info->aclock = init_aclock;
|
info->aclock = init_aclock;
|
||||||
info->kclock = init_kclock;
|
info->kclock = init_kclock;
|
||||||
|
@ -4515,44 +4506,48 @@ static Scheme_Object *optimize_branch(Scheme_Object *o, Optimize_Info *info, int
|
||||||
|
|
||||||
optimize_info_seq_step(info, &info_seq);
|
optimize_info_seq_step(info, &info_seq);
|
||||||
|
|
||||||
add_types_for_f_branch(t, info, 5);
|
else_info = optimize_info_add_frame(info, 0, 0, 0);
|
||||||
|
add_types_for_f_branch(t, else_info, 5);
|
||||||
|
fb = scheme_optimize_expr(fb, else_info, scheme_optimize_tail_context(context));
|
||||||
|
optimize_info_done(else_info, NULL);
|
||||||
|
|
||||||
fb = scheme_optimize_expr(fb, info, scheme_optimize_tail_context(context));
|
if (then_info->escapes && else_info->escapes) {
|
||||||
|
|
||||||
if (info->escapes && then_escapes) {
|
|
||||||
/* both branches escaped */
|
/* both branches escaped */
|
||||||
info->preserves_marks = 1;
|
info->preserves_marks = 1;
|
||||||
info->single_result = 1;
|
info->single_result = 1;
|
||||||
info->kclock = init_kclock;
|
info->kclock = init_kclock;
|
||||||
info->types = init_types; /* not sure if this is necesary */
|
|
||||||
|
|
||||||
} else if (info->escapes) {
|
} else if (info->escapes) {
|
||||||
info->preserves_marks = then_preserves_marks;
|
info->preserves_marks = then_info->preserves_marks;
|
||||||
info->single_result = then_single_result;
|
info->single_result = then_info->single_result;
|
||||||
info->kclock = then_kclock;
|
info->kclock = then_info->kclock;
|
||||||
info->types = then_types;
|
merge_types(then_info, info, 0);
|
||||||
info->escapes = 0;
|
info->escapes = 0;
|
||||||
|
|
||||||
} else if (then_escapes) {
|
} else if (then_info->escapes) {
|
||||||
info->escapes = 0;
|
info->preserves_marks = else_info->preserves_marks;
|
||||||
|
info->single_result = else_info->single_result;
|
||||||
|
merge_types(else_info, info, 0);
|
||||||
|
info->escapes = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
then_preserves_marks = or_tentative(then_preserves_marks, info->preserves_marks);
|
int new_preserves_marks, new_single_result;
|
||||||
info->preserves_marks = then_preserves_marks;
|
|
||||||
then_single_result = or_tentative(then_single_result, info->single_result);
|
new_preserves_marks = or_tentative(then_info->preserves_marks, else_info->preserves_marks);
|
||||||
info->single_result = then_single_result;
|
info->preserves_marks = new_preserves_marks;
|
||||||
if (then_kclock > info->kclock)
|
new_single_result = or_tentative(then_info->single_result, else_info->single_result);
|
||||||
info->kclock = then_kclock;
|
info->single_result = new_single_result;
|
||||||
init_types = intersect_and_merge_types(then_types, info->types, init_types);
|
if (then_info->kclock > info->kclock)
|
||||||
info->types = init_types;
|
info->kclock = then_info->kclock;
|
||||||
|
intersect_and_merge_types(then_info, else_info, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (then_sclock > info->sclock)
|
if (then_info->sclock > info->sclock)
|
||||||
info->sclock = then_sclock;
|
info->sclock = then_info->sclock;
|
||||||
if (then_aclock > info->aclock)
|
if (then_info->aclock > info->aclock)
|
||||||
info->aclock = then_aclock;
|
info->aclock = then_info->aclock;
|
||||||
|
|
||||||
if ((init_vclock == then_vclock) && (init_vclock == info->vclock)) {
|
if ((init_vclock == then_info->vclock) && (init_vclock == info->vclock)) {
|
||||||
/* we can rewind the vclock to just after the test, because the
|
/* we can rewind the vclock to just after the test, because the
|
||||||
`if` as a whole has no effect */
|
`if` as a whole has no effect */
|
||||||
info->vclock--;
|
info->vclock--;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user