optimizer repair related to use-before-defined

Don't optimize away a use-before-definition in an early compiler
pass. (More specifically, adjust the meaning of a flag within an
optimization helper function so that it works for decisions before the
letrec-fixing pass.)
This commit is contained in:
Matthew Flatt 2014-04-16 06:26:01 -06:00
parent 6c400adce0
commit 6ce5e3d34a
2 changed files with 23 additions and 10 deletions

View File

@ -3415,6 +3415,17 @@
(eval (parameterize ([read-accept-compiled #t])
(read (open-input-bytes (get-output-bytes o))))))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Check that an unsufe opertion's argument is
;; not "optimized" away if it's a use of
;; a variable before definition:
(err/rt-test (let ()
(unsafe-fx+ x 1)
(define x 3)
x)
exn:fail:contract:variable?)
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(report-errs)

View File

@ -249,8 +249,10 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved,
for "functional" bodies.
If warn_info is supplied, complain when a mismatch is detected.
If no_id is 1, then an identifier doesn't count as omittable,
unless the identifier is a consistent top-level; currently, this
is used to imply the absence of a continuation-mark impersonator. */
unless the identifier is a consistent top-level; the no_id mode
is used by the "compile" phase before letrec checks are inserted
(where referencing a variable might raise an exception) and to
imply the absence of a continuation-mark impersonator. */
{
Scheme_Type vtype;
@ -315,7 +317,7 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved,
if (vtype == scheme_branch_type) {
Scheme_Branch_Rec *b;
b = (Scheme_Branch_Rec *)o;
return (scheme_omittable_expr(b->test, 1, fuel - 1, resolved, opt_info, warn_info, deeper_than, 0)
return (scheme_omittable_expr(b->test, 1, fuel - 1, resolved, opt_info, warn_info, deeper_than, no_id)
&& scheme_omittable_expr(b->tbranch, vals, fuel - 1, resolved, opt_info, warn_info, deeper_than, no_id)
&& scheme_omittable_expr(b->fbranch, vals, fuel - 1, resolved, opt_info, warn_info, deeper_than, no_id));
}
@ -345,7 +347,7 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved,
&& (lv2->position == 0)
&& scheme_omittable_expr(lv2->value, 1, fuel - 1, resolved, opt_info, warn_info,
deeper_than + 1 + lv->count,
0)) {
no_id)) {
o = lv2->body;
deeper_than += 1;
} else
@ -362,7 +364,7 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved,
if ((lh->count == 1) && (lh->num_clauses == 1)) {
if (SAME_TYPE(SCHEME_TYPE(lh->body), scheme_compiled_let_value_type)) {
Scheme_Compiled_Let_Value *lv = (Scheme_Compiled_Let_Value *)lh->body;
if (scheme_omittable_expr(lv->value, 1, fuel - 1, resolved, opt_info, warn_info, deeper_than + 1, 0)) {
if (scheme_omittable_expr(lv->value, 1, fuel - 1, resolved, opt_info, warn_info, deeper_than + 1, no_id)) {
o = lv->body;
deeper_than++;
goto try_again;
@ -389,7 +391,7 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved,
int i;
for (i = app->num_args; i--; ) {
if (!scheme_omittable_expr(app->args[i + 1], 1, fuel - 1, resolved, opt_info, warn_info,
deeper_than + (resolved ? app->num_args : 0), 0))
deeper_than + (resolved ? app->num_args : 0), no_id))
return 0;
}
return 1;
@ -409,7 +411,7 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved,
if (scheme_is_functional_primitive(app->rator, 1, vals)
|| scheme_is_struct_functional(app->rator, 1, opt_info, vals)) {
if (scheme_omittable_expr(app->rand, 1, fuel - 1, resolved, opt_info, warn_info,
deeper_than + (resolved ? 1 : 0), 0))
deeper_than + (resolved ? 1 : 0), no_id))
return 1;
} else if (SCHEME_PRIMP(app->rator)) {
if (!(SCHEME_PRIM_PROC_FLAGS(app->rator) & SCHEME_PRIM_IS_MULTI_RESULT)
@ -425,9 +427,9 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved,
if (scheme_is_functional_primitive(app->rator, 2, vals)
|| scheme_is_struct_functional(app->rator, 2, opt_info, vals)) {
if (scheme_omittable_expr(app->rand1, 1, fuel - 1, resolved, opt_info, warn_info,
deeper_than + (resolved ? 2 : 0), 0)
deeper_than + (resolved ? 2 : 0), no_id)
&& scheme_omittable_expr(app->rand2, 1, fuel - 1, resolved, opt_info, warn_info,
deeper_than + (resolved ? 2 : 0), 0))
deeper_than + (resolved ? 2 : 0), no_id))
return 1;
} else if (SCHEME_PRIMP(app->rator)) {
if (!(SCHEME_PRIM_PROC_FLAGS(app->rator) & SCHEME_PRIM_IS_MULTI_RESULT)) {
@ -459,7 +461,7 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved,
5);
if (auto_e) {
if (scheme_omittable_expr(auto_e, 1, fuel - 1, resolved, opt_info, warn_info,
deeper_than + auto_e_depth, 0))
deeper_than + auto_e_depth, no_id))
return 1;
}
}