diff --git a/collects/tests/typed-scheme/optimizer/generic/unboxed-let3.rkt b/collects/tests/typed-scheme/optimizer/generic/unboxed-let3.rkt new file mode 100644 index 00000000..b52e893c --- /dev/null +++ b/collects/tests/typed-scheme/optimizer/generic/unboxed-let3.rkt @@ -0,0 +1,15 @@ +#lang typed/scheme #:optimize + +(require racket/unsafe/ops) + +;; both boxed and unboxed uses, we unbox anyway +;; causes unnecessary boxing/unboxing if we take a boxed path when +;; unboxing a complex literal or variable, but I expect this case +;; to be uncommon +;; by comparison, cases where we leave a result unboxed and box it +;; if needed (like here) or cases where this would unbox loop variables +;; are likely to be more common, and more interesting +(let ((x (+ 1.0+2.0i 2.0+4.0i))) + (if (even? 2) + x + (+ x 2.0+4.0i))) diff --git a/collects/typed-scheme/optimizer/inexact-complex.rkt b/collects/typed-scheme/optimizer/inexact-complex.rkt index def4dde9..95be4637 100644 --- a/collects/typed-scheme/optimizer/inexact-complex.rkt +++ b/collects/typed-scheme/optimizer/inexact-complex.rkt @@ -332,6 +332,16 @@ e.imag-binding ... #,@(map (lambda (i) ((optimize) (get-arg i))) boxed)))]))) ; boxed params + + ;; unboxed variable used in a boxed fashion, we have to box + (pattern v:id + #:with unboxed-info (dict-ref unboxed-vars-table #'v #f) + #:when (syntax->datum #'unboxed-info) + #:with real-binding (car (syntax->list #'unboxed-info)) + #:with imag-binding (cadr (syntax->list #'unboxed-info)) + #:with opt + (begin (log-optimization "boxing of an unboxed variable" #'v) + #'(unsafe-make-flrectangular real-binding imag-binding))) (pattern e:inexact-complex-arith-opt-expr #:with opt diff --git a/collects/typed-scheme/optimizer/unboxed-let.rkt b/collects/typed-scheme/optimizer/unboxed-let.rkt index f4f7948d..a5a0369b 100644 --- a/collects/typed-scheme/optimizer/unboxed-let.rkt +++ b/collects/typed-scheme/optimizer/unboxed-let.rkt @@ -109,16 +109,15 @@ (ormap (lambda (x) (and (identifier? x) (free-identifier=? x v))) (syntax->list exp))) -;; if a variable is only used in complex arithmetic operations, it's safe -;; to unbox it +;; if a variable is used at least once in complex arithmetic operations, +;; it's worth unboxing (define (could-be-unboxed-in? v exp) ;; if v is a direct child of exp, that means it's used in a boxed ;; fashion, and is not safe to unboxed ;; if not, recur on the subforms (define (look-at exp) - (and (not (direct-child-of? v exp)) - (andmap rec (syntax->list exp)))) + (ormap rec (syntax->list exp))) (define (rec exp) (syntax-parse exp @@ -126,7 +125,8 @@ ;; can be used in a complex arithmetic expr, can be a direct child [exp:inexact-complex-arith-opt-expr - (andmap rec (syntax->list #'exp))] + (or (direct-child-of? v #'exp) + (ormap rec (syntax->list #'exp)))] ;; recur down [((~and op (~or (~literal #%plain-lambda) (~literal define-values)))