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:
parent
6c400adce0
commit
6ce5e3d34a
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user