diff --git a/collects/tests/racket/optimize.rktl b/collects/tests/racket/optimize.rktl index 74cd0ff1c3..5203a37013 100644 --- a/collects/tests/racket/optimize.rktl +++ b/collects/tests/racket/optimize.rktl @@ -1585,6 +1585,25 @@ f))) #f) +;; check move through an intermediate variable: +(test-comp '(lambda (n) + (let ([p (+ n n)]) + (if n + (let ([m (unsafe-fx- p 1)] + [t (- p p)]) + (let ([q (- p p)] + [s m]) + (+ p s q t))) + 'ok))) + '(lambda (n) + (let ([p (+ n n)]) + (if n + (let ([m (unsafe-fx- p 1)] + [t (- p p)]) + (+ p m (- p p) t)) + 'ok)))) + + ;; simple cross-module inlining (test-comp `(module m racket/base (require racket/bool) diff --git a/src/racket/src/optimize.c b/src/racket/src/optimize.c index 844f486edf..ae21a0016a 100644 --- a/src/racket/src/optimize.c +++ b/src/racket/src/optimize.c @@ -5603,8 +5603,6 @@ top_level_require_optimize(Scheme_Object *data, Optimize_Info *info, int context return data; } - - /*========================================================================*/ /* expressions */ /*========================================================================*/ @@ -6662,13 +6660,15 @@ static Scheme_Object *do_optimize_info_lookup(Optimize_Info *info, int pos, int o->cross_lambda = (j != orig_j); return (Scheme_Object *)o; } else if (SAME_TYPE(SCHEME_TYPE(n), scheme_local_type)) { - int pos, cross_lambda = (j != orig_j); + int pos, cross_lambda = (j != orig_j), extra_delta = 0; pos = SCHEME_LOCAL_POS(n); if (info->flags & SCHEME_LAMBDA_FRAME) j--; /* because it will get re-added on recur */ - else if (info->flags & SCHEME_POST_BIND_FRAME) + else if (info->flags & SCHEME_POST_BIND_FRAME) { + extra_delta = info->new_frame; info = info->next; /* bindings are relative to next frame */ + } /* Marks local as used; we don't expect to get back a value, because chaining would normally happen on the @@ -6694,7 +6694,7 @@ static Scheme_Object *do_optimize_info_lookup(Optimize_Info *info, int pos, int } else if (SAME_TYPE(SCHEME_TYPE(n), scheme_once_used_type)) { /* Need to adjust delta: */ delta = optimize_info_get_shift(info, pos); - ((Scheme_Once_Used *)n)->delta += delta; + ((Scheme_Once_Used *)n)->delta += delta + extra_delta; if (cross_lambda) ((Scheme_Once_Used *)n)->cross_lambda = 1; } }