fix optimize problem

Gustavo's tests in de3fa9a855 illustrate the problem. The solution
is simply passing 1 for `optimized_rator` to optimize_for_inline().
Additional changes generalize optimize_for_inline() a little (although
that generality doesn't seem to be useful at the moment) and collapse
some variables that represent the same value.
This commit is contained in:
Matthew Flatt 2015-02-27 10:01:09 -07:00
parent de3fa9a855
commit 04ce921e8f

View File

@ -1704,12 +1704,12 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a
application with a single argument and if app3, we're inlining an application with a single argument and if app3, we're inlining an
application with two arguments. application with two arguments.
If not app, app2, or app3, just return a known procedure, if any, If not app, app2, or app3, just return a known procedure, if any,
and do not check arity. */ and do not check arity.
/* id_offset can be non 0 only when app, app2 and app3 are NULL */ The id_offset can be non 0 only when app, app2 and app3 are NULL and optimized_rator is 1. */
{ {
int offset = 0, single_use = 0, psize = 0; int offset = 0, single_use = 0, psize = 0;
Scheme_Object *bad_app = NULL, *prev = NULL, *orig_le = le; Scheme_Object *bad_app = NULL, *prev = NULL, *orig_le = le;
int nested_count = 0, outside_nested = 0, already_opt = optimized_rator, nonleaf, noapp; int outside_nested = 0, already_opt = optimized_rator, nonleaf, noapp;
noapp = !app && !app2 && !app3; noapp = !app && !app2 && !app3;
if (id_offset && !noapp) if (id_offset && !noapp)
@ -1719,18 +1719,30 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a
/* Move inside `let' bindings, so we can convert ((let (....) proc) arg ...) /* Move inside `let' bindings, so we can convert ((let (....) proc) arg ...)
to (let (....) (proc arg ...)) */ to (let (....) (proc arg ...)) */
if (optimized_rator) if (already_opt)
extract_tail_inside(&le, &prev, &nested_count); extract_tail_inside(&le, &prev, &id_offset);
if (SAME_TYPE(SCHEME_TYPE(le), scheme_compiled_unclosed_procedure_type)) { if (SAME_TYPE(SCHEME_TYPE(le), scheme_compiled_unclosed_procedure_type)) {
/* Found a `((lambda' */ /* Found a `((lambda' */
single_use = 1; single_use = 1;
} }
if (!optimized_rator && SAME_TYPE(SCHEME_TYPE(le), scheme_local_type)) { if (SAME_TYPE(SCHEME_TYPE(le), scheme_local_type)) {
/* Check for inlining: */ /* Check for inlining: */
int pos = SCHEME_LOCAL_POS(le); int pos = SCHEME_LOCAL_POS(le);
if (already_opt) {
if (pos >= id_offset)
le = optimize_reverse(info, pos - id_offset, 0, 0);
else
le = NULL;
if (!le)
return NULL;
already_opt = 0;
id_offset = 0;
pos = SCHEME_LOCAL_POS(le);
}
le = optimize_info_lookup(info, pos - id_offset, &offset, &single_use, 0, 0, &psize, NULL); le = optimize_info_lookup(info, pos - id_offset, &offset, &single_use, 0, 0, &psize, NULL);
outside_nested = 1; outside_nested = 1;
already_opt = 1; already_opt = 1;
@ -1827,8 +1839,7 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a
if ((data->num_params == argc) if ((data->num_params == argc)
|| ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REST) || ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REST)
&& (argc + 1 >= data->num_params)) && (argc + 1 >= data->num_params))) {
|| noapp) {
int threshold, is_leaf = 0; int threshold, is_leaf = 0;
if (!already_opt) { if (!already_opt) {
@ -1847,8 +1858,8 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a
/* Do we have enough fuel? */ /* Do we have enough fuel? */
if ((sz >= 0) && (single_use || (sz <= threshold))) { if ((sz >= 0) && (single_use || (sz <= threshold))) {
Optimize_Info *sub_info; Optimize_Info *sub_info;
if (nested_count) { if (id_offset) {
sub_info = optimize_info_add_frame(info, nested_count, nested_count, 0); sub_info = optimize_info_add_frame(info, id_offset, id_offset, 0);
/* We only go into `let` and `begin` only for an optimized rator, so /* We only go into `let` and `begin` only for an optimized rator, so
the virtual clock was already incremented as needed. */ the virtual clock was already incremented as needed. */
/* We could propagate bound values in sub_info, but relevant inlining /* We could propagate bound values in sub_info, but relevant inlining
@ -1859,7 +1870,7 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a
/* If optimize_clone succeeds, inlining succeeds. */ /* If optimize_clone succeeds, inlining succeeds. */
le = optimize_clone(single_use, data->code, sub_info, le = optimize_clone(single_use, data->code, sub_info,
offset + (outside_nested ? nested_count : 0), offset + (outside_nested ? id_offset : 0),
data->num_params); data->num_params);
if (le) { if (le) {
@ -1874,8 +1885,8 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a
threshold, threshold,
scheme_optimize_context_to_string(info->context)); scheme_optimize_context_to_string(info->context));
le = apply_inlined(le, data, sub_info, argc, app, app2, app3, context, le = apply_inlined(le, data, sub_info, argc, app, app2, app3, context,
nested_count, orig_le, prev); id_offset, orig_le, prev);
if (nested_count) if (id_offset)
optimize_info_done(sub_info, NULL); optimize_info_done(sub_info, NULL);
return le; return le;
} else { } else {
@ -3171,7 +3182,7 @@ static Scheme_Object *finish_optimize_application2(Scheme_App2_Rec *app, Optimiz
if (SAME_OBJ(scheme_procedure_p_proc, app->rator)) { if (SAME_OBJ(scheme_procedure_p_proc, app->rator)) {
int flags, sub_context = 0; int flags, sub_context = 0;
if (lookup_constant_proc(info, rand, id_offset) if (lookup_constant_proc(info, rand, id_offset)
|| optimize_for_inline(info, rand, 1, NULL, NULL, NULL, &flags, sub_context, 0, id_offset)) { || optimize_for_inline(info, rand, 1, NULL, NULL, NULL, &flags, sub_context, 1, id_offset)) {
info->preserves_marks = 1; info->preserves_marks = 1;
info->single_result = 1; info->single_result = 1;
return replace_tail_inside(scheme_true, inside, app->rand); return replace_tail_inside(scheme_true, inside, app->rand);