fix mismatch between optimizer snd run-time on "constant" detection
Cross-module inlining that pulls a variable reference across a module boundary imposes a more struct requirement that run-time "constant" detection is consistent with the optimizer's view of "constant" within a module. So, make sure they're the same.
This commit is contained in:
parent
747185184b
commit
26d28a28fe
|
@ -3345,6 +3345,35 @@
|
||||||
(require (submod ".." a))
|
(require (submod ".." a))
|
||||||
(list b c (c)))))
|
(list b c (c)))))
|
||||||
|
|
||||||
|
(test-comp `(module m racket/base
|
||||||
|
(module a racket/base
|
||||||
|
(provide b c)
|
||||||
|
(define c
|
||||||
|
(let ([x 0])
|
||||||
|
(lambda (y)
|
||||||
|
(begin0
|
||||||
|
x
|
||||||
|
(set! x y)))))
|
||||||
|
(define (b z)
|
||||||
|
(c z)))
|
||||||
|
(module d racket/base
|
||||||
|
(require (submod ".." a))
|
||||||
|
(list b c (b 1))))
|
||||||
|
`(module m racket/base
|
||||||
|
(module a racket/base
|
||||||
|
(provide b c)
|
||||||
|
(define c
|
||||||
|
(let ([x 0])
|
||||||
|
(lambda (y)
|
||||||
|
(begin0
|
||||||
|
x
|
||||||
|
(set! x y)))))
|
||||||
|
(define (b z)
|
||||||
|
(c z)))
|
||||||
|
(module d racket/base
|
||||||
|
(require (submod ".." a))
|
||||||
|
(list b c (c 1)))))
|
||||||
|
|
||||||
(module check-inline-request racket/base
|
(module check-inline-request racket/base
|
||||||
(require racket/performance-hint)
|
(require racket/performance-hint)
|
||||||
(provide loop)
|
(provide loop)
|
||||||
|
|
|
@ -2093,10 +2093,7 @@ define_execute_with_dynamic_state(Scheme_Object *vec, int delta, int defmacro,
|
||||||
|
|
||||||
if (SCHEME_TOPLEVEL_FLAGS(var) & SCHEME_TOPLEVEL_SEAL) {
|
if (SCHEME_TOPLEVEL_FLAGS(var) & SCHEME_TOPLEVEL_SEAL) {
|
||||||
int flags = GLOB_IS_IMMUTATED;
|
int flags = GLOB_IS_IMMUTATED;
|
||||||
if (SCHEME_PROCP(vals_expr)
|
if (scheme_is_statically_proc(vals_expr, NULL, OMITTABLE_RESOLVED))
|
||||||
|| SAME_TYPE(SCHEME_TYPE(vals_expr), scheme_lambda_type)
|
|
||||||
|| SAME_TYPE(SCHEME_TYPE(vals_expr), scheme_case_lambda_sequence_type)
|
|
||||||
|| SAME_TYPE(SCHEME_TYPE(vals_expr), scheme_inline_variant_type))
|
|
||||||
flags |= GLOB_IS_CONSISTENT;
|
flags |= GLOB_IS_CONSISTENT;
|
||||||
((Scheme_Bucket_With_Flags *)b)->flags |= flags;
|
((Scheme_Bucket_With_Flags *)b)->flags |= flags;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5736,24 +5736,53 @@ int scheme_ir_propagate_ok(Scheme_Object *value, Optimize_Info *info)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int scheme_is_statically_proc(Scheme_Object *value, Optimize_Info *info)
|
int scheme_is_statically_proc(Scheme_Object *value, Optimize_Info *info, int flags)
|
||||||
/* Does `value` definitely produce a procedure of a specific shape? */
|
/* Does `value` definitely produce a procedure of a specific shape?
|
||||||
|
This function can be used on resolved (and SFS) forms, too, and it
|
||||||
|
must be consistent with (i.e., as least as accepting as)
|
||||||
|
optimization-time decisions. The `flags` argument is for
|
||||||
|
scheme_omittable_expr(). */
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
if (SCHEME_LAMBDAP(value)) {
|
if (SCHEME_LAMBDAP(value)
|
||||||
|
|| SCHEME_PROCP(value)
|
||||||
|
|| SAME_TYPE(SCHEME_TYPE(value), scheme_lambda_type)
|
||||||
|
|| SAME_TYPE(SCHEME_TYPE(value), scheme_case_lambda_sequence_type)
|
||||||
|
|| SAME_TYPE(SCHEME_TYPE(value), scheme_inline_variant_type))
|
||||||
return 1;
|
return 1;
|
||||||
} else if (SAME_TYPE(SCHEME_TYPE(value), scheme_ir_let_header_type)) {
|
else if (SAME_TYPE(SCHEME_TYPE(value), scheme_ir_let_header_type)) {
|
||||||
/* Look for (let ([x <omittable>]) <proc>), which is generated for optional arguments. */
|
/* Look for (let ([x <omittable>]) <proc>), which is generated for optional arguments. */
|
||||||
Scheme_IR_Let_Header *lh = (Scheme_IR_Let_Header *)value;
|
Scheme_IR_Let_Header *lh = (Scheme_IR_Let_Header *)value;
|
||||||
if (lh->num_clauses == 1) {
|
if (lh->num_clauses == 1) {
|
||||||
Scheme_IR_Let_Value *lv = (Scheme_IR_Let_Value *)lh->body;
|
Scheme_IR_Let_Value *lv = (Scheme_IR_Let_Value *)lh->body;
|
||||||
if (scheme_omittable_expr(lv->value, lv->count, 20, 0, info, NULL)) {
|
if (scheme_omittable_expr(lv->value, lv->count, 20, flags, info, NULL)) {
|
||||||
value = lv->body;
|
value = lv->body;
|
||||||
info = NULL;
|
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
|
} else if (SAME_TYPE(SCHEME_TYPE(value), scheme_let_one_type)) {
|
||||||
|
Scheme_Let_One *lo = (Scheme_Let_One *)value;
|
||||||
|
if (scheme_omittable_expr(lo->value, 1, 20, flags, info, NULL)) {
|
||||||
|
value = lo->body;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
} else if (SAME_TYPE(SCHEME_TYPE(value), scheme_boxenv_type)) {
|
||||||
|
value = SCHEME_PTR2_VAL(value);
|
||||||
|
} else if (SAME_TYPE(SCHEME_TYPE(value), scheme_sequence_type)
|
||||||
|
/* Handle a sequence for resolved mode, because it might
|
||||||
|
be for safe-for-space clears around a procedure */
|
||||||
|
&& (flags & OMITTABLE_RESOLVED)) {
|
||||||
|
Scheme_Sequence *seq = (Scheme_Sequence *)value;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < seq->count-1; i++) {
|
||||||
|
if (!scheme_omittable_expr(seq->array[i], 1, 5, flags, info, NULL))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == seq->count-1) {
|
||||||
|
value = seq->array[i];
|
||||||
|
} else
|
||||||
|
break;
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -7709,7 +7738,7 @@ module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
|
||||||
if (n == 1) {
|
if (n == 1) {
|
||||||
if (scheme_ir_propagate_ok(e, info))
|
if (scheme_ir_propagate_ok(e, info))
|
||||||
cnst = 1;
|
cnst = 1;
|
||||||
else if (scheme_is_statically_proc(e, info)) {
|
else if (scheme_is_statically_proc(e, info, 0)) {
|
||||||
cnst = 1;
|
cnst = 1;
|
||||||
sproc = 1;
|
sproc = 1;
|
||||||
}
|
}
|
||||||
|
@ -7864,7 +7893,7 @@ module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!scheme_ir_propagate_ok(e, info)
|
if (!scheme_ir_propagate_ok(e, info)
|
||||||
&& scheme_is_statically_proc(e, info)) {
|
&& scheme_is_statically_proc(e, info, 0)) {
|
||||||
/* If we previously installed a procedure for inlining,
|
/* If we previously installed a procedure for inlining,
|
||||||
don't replace that with a worse approximation. */
|
don't replace that with a worse approximation. */
|
||||||
if (SCHEME_LAMBDAP(old_e))
|
if (SCHEME_LAMBDAP(old_e))
|
||||||
|
|
|
@ -3267,7 +3267,7 @@ Scheme_Object *scheme_optimize_apply_values(Scheme_Object *f, Scheme_Object *e,
|
||||||
|
|
||||||
int scheme_ir_duplicate_ok(Scheme_Object *o, int cross_mod);
|
int scheme_ir_duplicate_ok(Scheme_Object *o, int cross_mod);
|
||||||
int scheme_ir_propagate_ok(Scheme_Object *o, Optimize_Info *info);
|
int scheme_ir_propagate_ok(Scheme_Object *o, Optimize_Info *info);
|
||||||
int scheme_is_statically_proc(Scheme_Object *value, Optimize_Info *info);
|
int scheme_is_statically_proc(Scheme_Object *value, Optimize_Info *info, int flags);
|
||||||
XFORM_NONGCING int scheme_predicate_to_local_type(Scheme_Object *pred);
|
XFORM_NONGCING int scheme_predicate_to_local_type(Scheme_Object *pred);
|
||||||
Scheme_Object *scheme_make_noninline_proc(Scheme_Object *e);
|
Scheme_Object *scheme_make_noninline_proc(Scheme_Object *e);
|
||||||
Scheme_Object *scheme_optimize_extract_tail_inside(Scheme_Object *t2);
|
Scheme_Object *scheme_optimize_extract_tail_inside(Scheme_Object *t2);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user