optimizer: allow duplication of toplevels

This commit is contained in:
Gustavo Massaccesi 2016-04-09 09:22:50 -03:00
parent 2d0f8f6c0f
commit b93d94bb67
2 changed files with 30 additions and 13 deletions

View File

@ -1945,6 +1945,19 @@
(if r #t (something-else)))) (if r #t (something-else))))
'(lambda (x) (if (something) #t (something-else)))) '(lambda (x) (if (something) #t (something-else))))
(let ([test-if-if-reduction
(lambda (dup)
(test-comp `(lambda (x y z) (if (if x y #f) z ,dup))
`(lambda (x y z) (if x (if y z ,dup) ,dup))))])
(test-if-if-reduction 1)
(test-if-if-reduction ''x)
(test-if-if-reduction "x")
(test-if-if-reduction #"x")
(test-if-if-reduction #t)
(test-if-if-reduction #f)
(test-if-if-reduction 'car)
(test-if-if-reduction 'map))
(let ([test-pred-implies-val (let ([test-pred-implies-val
(lambda (pred? val) (lambda (pred? val)
(test-comp `(lambda (x) (if (,pred? x) ,val 0)) (test-comp `(lambda (x) (if (,pred? x) ,val 0))

View File

@ -1639,21 +1639,22 @@ int scheme_ir_duplicate_ok(Scheme_Object *fb, int cross_module)
/* Is the constant a value that we can "copy" in the code? */ /* Is the constant a value that we can "copy" in the code? */
{ {
return (SCHEME_VOIDP(fb) return (SCHEME_VOIDP(fb)
|| SAME_OBJ(fb, scheme_true) || SAME_OBJ(fb, scheme_true)
|| SCHEME_FALSEP(fb) || SCHEME_FALSEP(fb)
|| (SCHEME_SYMBOLP(fb) || (SCHEME_SYMBOLP(fb)
&& (!cross_module || (!SCHEME_SYM_WEIRDP(fb) && (!cross_module || (!SCHEME_SYM_WEIRDP(fb)
&& (SCHEME_SYM_LEN(fb) < STR_INLINE_LIMIT)))) && (SCHEME_SYM_LEN(fb) < STR_INLINE_LIMIT))))
|| (SCHEME_KEYWORDP(fb) || (SCHEME_KEYWORDP(fb)
&& (!cross_module || (SCHEME_KEYWORD_LEN(fb) < STR_INLINE_LIMIT))) && (!cross_module || (SCHEME_KEYWORD_LEN(fb) < STR_INLINE_LIMIT)))
|| SCHEME_EOFP(fb) || SCHEME_EOFP(fb)
|| SCHEME_INTP(fb) || SCHEME_INTP(fb)
|| SCHEME_NULLP(fb) || SCHEME_NULLP(fb)
|| (!cross_module && SAME_TYPE(SCHEME_TYPE(fb), scheme_ir_local_type)) || (!cross_module && SAME_TYPE(SCHEME_TYPE(fb), scheme_ir_toplevel_type))
|| (!cross_module && SAME_TYPE(SCHEME_TYPE(fb), scheme_ir_local_type))
|| SCHEME_PRIMP(fb) || SCHEME_PRIMP(fb)
/* Values that are hashed by the printer and/or interned on /* Values that are hashed by the printer and/or interned on
read to avoid duplication: */ read to avoid duplication: */
|| SCHEME_CHARP(fb) || SCHEME_CHARP(fb)
|| (SCHEME_CHAR_STRINGP(fb) || (SCHEME_CHAR_STRINGP(fb)
&& (!cross_module || (SCHEME_CHAR_STRLEN_VAL(fb) < STR_INLINE_LIMIT))) && (!cross_module || (SCHEME_CHAR_STRLEN_VAL(fb) < STR_INLINE_LIMIT)))
|| (SCHEME_BYTE_STRINGP(fb) || (SCHEME_BYTE_STRINGP(fb)
@ -5773,9 +5774,6 @@ int scheme_is_liftable(Scheme_Object *o, Scheme_Hash_Tree *exclude_vars, int fue
int scheme_ir_propagate_ok(Scheme_Object *value, Optimize_Info *info) int scheme_ir_propagate_ok(Scheme_Object *value, Optimize_Info *info)
/* Can we constant-propagate the expression `value`? */ /* Can we constant-propagate the expression `value`? */
{ {
if (scheme_ir_duplicate_ok(value, 0))
return 1;
if (SAME_TYPE(SCHEME_TYPE(value), scheme_ir_lambda_type)) { if (SAME_TYPE(SCHEME_TYPE(value), scheme_ir_lambda_type)) {
int sz; int sz;
sz = lambda_body_size_plus_info((Scheme_Lambda *)value, 1, info, NULL); sz = lambda_body_size_plus_info((Scheme_Lambda *)value, 1, info, NULL);
@ -5831,8 +5829,14 @@ int scheme_ir_propagate_ok(Scheme_Object *value, Optimize_Info *info)
if (value) if (value)
return 1; return 1;
} }
return 0;
} }
/* Test this after the specific cases,
because it recognizes locals and toplevels. */
if (scheme_ir_duplicate_ok(value, 0))
return 1;
return 0; return 0;
} }
@ -8314,7 +8318,7 @@ Scheme_Object *scheme_optimize_expr(Scheme_Object *expr, Optimize_Info *info, in
/* We can't inline, but mark the top level as a constant, /* We can't inline, but mark the top level as a constant,
so we can direct-jump and avoid null checks in JITed code: */ so we can direct-jump and avoid null checks in JITed code: */
expr = scheme_toplevel_to_flagged_toplevel(expr, SCHEME_TOPLEVEL_CONST); expr = scheme_toplevel_to_flagged_toplevel(expr, SCHEME_TOPLEVEL_CONST);
} else { } else {
/* false is mapped to a table of non-constant ready values: */ /* false is mapped to a table of non-constant ready values: */
c = scheme_hash_get(info->top_level_consts, scheme_false); c = scheme_hash_get(info->top_level_consts, scheme_false);