Coerce reals in float expressions when valid.

This commit is contained in:
Vincent St-Amour 2011-05-12 18:33:30 -04:00
parent e64ba228e8
commit 4cd0ad4b1a
3 changed files with 25 additions and 14 deletions

View File

@ -0,0 +1,15 @@
#;
(
float-real.rkt 13:1 + -- binary float
float-real.rkt 14:1 + -- binary float
5.3
8.7
14.26
)
#lang typed/racket
;; reals within float expressions should be coerced when it's safe to do so
(+ 2.3 (ann 3 Real)) ; safe
(+ 2.3 (* (ann 2 Integer) 3.2)) ; inner = unsafe, outer = safe
(* 2.3 (* (ann 2 Integer) 3.1)) ; all unsafe

View File

@ -241,7 +241,7 @@
;; special handling of reals inside complex operations ;; special handling of reals inside complex operations
;; must be after any cases that we are supposed to handle ;; must be after any cases that we are supposed to handle
(pattern e:float-coerce-expr (pattern e:float-arg-expr
#:with real-binding (unboxed-gensym 'unboxed-float-) #:with real-binding (unboxed-gensym 'unboxed-float-)
#:with imag-binding #f #:with imag-binding #f
#:when (log-optimization "float-coerce-expr in complex ops" #'e) #:when (log-optimization "float-coerce-expr in complex ops" #'e)
@ -252,7 +252,7 @@
;; we can eliminate boxing that was introduced by the user ;; we can eliminate boxing that was introduced by the user
(pattern (#%plain-app (~and op (~or (~literal make-rectangular) (pattern (#%plain-app (~and op (~or (~literal make-rectangular)
(~literal unsafe-make-flrectangular))) (~literal unsafe-make-flrectangular)))
real:float-coerce-expr imag:float-coerce-expr) real:float-arg-expr imag:float-arg-expr)
#:with real-binding (unboxed-gensym "unboxed-real-") #:with real-binding (unboxed-gensym "unboxed-real-")
#:with imag-binding (unboxed-gensym "unboxed-imag-") #:with imag-binding (unboxed-gensym "unboxed-imag-")
#:with (bindings ...) #:with (bindings ...)
@ -260,7 +260,7 @@
#'(((real-binding) real.opt) #'(((real-binding) real.opt)
((imag-binding) imag.opt)))) ((imag-binding) imag.opt))))
(pattern (#%plain-app (~and op (~literal make-polar)) (pattern (#%plain-app (~and op (~literal make-polar))
r:float-coerce-expr theta:float-coerce-expr) r:float-arg-expr theta:float-arg-expr)
#:with magnitude (unboxed-gensym) #:with magnitude (unboxed-gensym)
#:with angle (unboxed-gensym) #:with angle (unboxed-gensym)
#:with real-binding (unboxed-gensym "unboxed-real-") #:with real-binding (unboxed-gensym "unboxed-real-")

View File

@ -7,7 +7,7 @@
(types numeric-tower) (types numeric-tower)
(optimizer utils fixnum)) (optimizer utils fixnum))
(provide float-opt-expr float-coerce-expr) (provide float-opt-expr float-arg-expr)
(define (mk-float-tbl generic) (define (mk-float-tbl generic)
@ -50,15 +50,6 @@
#:with opt ((optimize) #'e))) #:with opt ((optimize) #'e)))
;; generates coercions to floats
(define-syntax-class float-coerce-expr
#:commit
(pattern e:float-arg-expr
#:with opt #'e.opt)
(pattern e:real-expr
#:with opt #'(exact->inexact e.opt)))
;; if the result of an operation is of type float, its non float arguments ;; if the result of an operation is of type float, its non float arguments
;; can be promoted, and we can use unsafe float operations ;; can be promoted, and we can use unsafe float operations
;; note: none of the unary operations have types where non-float arguments ;; note: none of the unary operations have types where non-float arguments
@ -76,7 +67,12 @@
(pattern e:int-expr (pattern e:int-expr
#:with opt #'(->fl e.opt)) #:with opt #'(->fl e.opt))
(pattern e:float-expr (pattern e:float-expr
#:with opt #'e.opt)) #:with opt #'e.opt)
;; reals within float expressions are not always valid to optimize because
;; of the exact 0 problem, but since float-opt-expr checks whether the
;; surrounding expressing is of type Float and not just Real, this is safe
(pattern e:real-expr
#:with opt #'(exact->inexact e)))
(define-syntax-class float-opt-expr (define-syntax-class float-opt-expr
#:commit #:commit