diff --git a/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/optimizer/float.rkt b/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/optimizer/float.rkt index 2179fc836b..6eff36f035 100644 --- a/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/optimizer/float.rkt +++ b/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/optimizer/float.rkt @@ -202,6 +202,28 @@ fs:float-expr ...) #:do [(log-fl-opt "multi float comp")] #:with opt (n-ary-comp->binary #'op.unsafe #'f1.opt #'f2.opt #'(fs.opt ...))) + (pattern (#%plain-app op:binary-float-comp args:opt-expr ...) + ;; some args, but not all (otherwise above would have matched) are floats + ;; mixed-type comparisons are slow and block futures + #:when (let ([some-float? (for/first ([e (in-syntax #'(args ...))] + #:when (subtypeof? e -Flonum)) + e)]) + (when some-float? + (define non-floats ; irritants + (for/list ([e (in-syntax #'(args ...))] + #:unless (subtypeof? e -Flonum)) + e)) + (log-missed-optimization + "generic comparison" + (string-append + "This expression compares values of different exactnesses, " + "which prevents optimization. " + "To fix, explicitly convert the highlighted expressions to " + "be of type Float.") + this-syntax + non-floats)) + #f) ; keep trying other patterns + #:with opt #f) ; will never be reached (pattern (#%plain-app op:-^ f:float-expr) #:do [(log-fl-opt "unary float")] diff --git a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/missed-optimizations/mandelbrot.rkt b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/missed-optimizations/mandelbrot.rkt new file mode 100644 index 0000000000..a5e25c8b0b --- /dev/null +++ b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/missed-optimizations/mandelbrot.rkt @@ -0,0 +1,57 @@ +#;#; +#< (+ zrq ziq) 4) -- generic comparison -- caused by: 54:29 4 +TR missed opt: mandelbrot.rkt 54:14 (> (+ zrq ziq) 4) -- generic comparison -- caused by: 54:29 4 +TR missed opt: mandelbrot.rkt 57:25 (- (* 2 zr zi) ci) -- all args float-arg-expr, result not Float -- caused by: 57:28 (* 2 zr zi) +TR missed opt: mandelbrot.rkt 57:25 (- (* 2 zr zi) ci) -- all args float-arg-expr, result not Float -- caused by: 57:28 (* 2 zr zi) +TR missed opt: mandelbrot.rkt 57:28 (* 2 zr zi) -- all args float-arg-expr, result not Float -- caused by: 57:31 2 +TR missed opt: mandelbrot.rkt 57:28 (* 2 zr zi) -- all args float-arg-expr, result not Float -- caused by: 57:31 2 +TR opt: mandelbrot.rkt 51:21 (* zr zr) -- binary float +TR opt: mandelbrot.rkt 51:21 (* zr zr) -- binary float +TR opt: mandelbrot.rkt 52:21 (* zi zi) -- binary float +TR opt: mandelbrot.rkt 52:21 (* zi zi) -- binary float +TR opt: mandelbrot.rkt 54:17 (+ zrq ziq) -- binary float +TR opt: mandelbrot.rkt 54:17 (+ zrq ziq) -- binary float +TR opt: mandelbrot.rkt 56:25 (+ (- zrq ziq) cr) -- binary float +TR opt: mandelbrot.rkt 56:25 (+ (- zrq ziq) cr) -- binary float +TR opt: mandelbrot.rkt 56:28 (- zrq ziq) -- binary float +TR opt: mandelbrot.rkt 56:28 (- zrq ziq) -- binary float +END +"" + +#lang typed/racket + +;; from Matthew's talk at Mozilla +;; 2 things were blocking futures: +;; - (> (+ zrq ziq) 4) ; generic comparison +;; - (* 2 zr zi) ; generic multiplication +;; OC reports both + +(: mandelbrot : Integer Integer Integer Integer -> Integer) +(define (mandelbrot iterations x y n) + (let ([ci (- (/ (* 2.0 y) n) 1.0)] + [cr (- (/ (* 2.0 x) n) 1.5)]) + (let loop ([i 0] [zr 0.0] [zi 0.0]) + (if (> i iterations) + i + (let ([zrq (* zr zr)] + [ziq (* zi zi)]) + (cond + [(> (+ zrq ziq) 4) i] + [else (loop (add1 i) + (+ (- zrq ziq) cr) + (- (* 2 zr zi) ci))])))))) diff --git a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/dead-inf-comp.rkt b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/dead-inf-comp.rkt index 07368bdfca..de8d52f4fd 100644 --- a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/dead-inf-comp.rkt +++ b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/dead-inf-comp.rkt @@ -1,65 +1,83 @@ #;#; #< +inf.f rat) -- possible exact real arith -TR info: dead-inf-comp.rkt 175:4 (> rat +inf.f) -- possible exact real arith -TR info: dead-inf-comp.rkt 178:4 (> -inf.f rat) -- possible exact real arith -TR info: dead-inf-comp.rkt 181:4 (> rat -inf.f) -- possible exact real arith -TR info: dead-inf-comp.rkt 185:4 (<= rat +inf.f) -- possible exact real arith -TR info: dead-inf-comp.rkt 188:4 (<= +inf.f rat) -- possible exact real arith -TR info: dead-inf-comp.rkt 191:4 (<= rat -inf.f) -- possible exact real arith -TR info: dead-inf-comp.rkt 194:4 (<= -inf.f rat) -- possible exact real arith -TR info: dead-inf-comp.rkt 198:4 (>= +inf.f rat) -- possible exact real arith -TR info: dead-inf-comp.rkt 201:4 (>= rat +inf.f) -- possible exact real arith -TR info: dead-inf-comp.rkt 204:4 (>= -inf.f rat) -- possible exact real arith -TR info: dead-inf-comp.rkt 207:4 (>= rat -inf.f) -- possible exact real arith -TR info: dead-inf-comp.rkt 212:41 displayln -- hidden parameter -TR info: dead-inf-comp.rkt 212:41 displayln -- hidden parameter -TR opt: dead-inf-comp.rkt 108:4 (quote dead) -- dead else branch -TR opt: dead-inf-comp.rkt 110:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 113:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 117:4 (quote dead) -- dead else branch -TR opt: dead-inf-comp.rkt 121:4 (quote dead) -- dead else branch -TR opt: dead-inf-comp.rkt 123:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 126:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 130:4 (quote dead) -- dead else branch -TR opt: dead-inf-comp.rkt 134:4 (quote dead) -- dead else branch -TR opt: dead-inf-comp.rkt 136:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 139:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 143:4 (quote dead) -- dead else branch -TR opt: dead-inf-comp.rkt 147:4 (quote dead) -- dead else branch -TR opt: dead-inf-comp.rkt 149:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 152:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 156:4 (quote dead) -- dead else branch +TR info: dead-inf-comp.rkt 177:4 (< rat +inf.f) -- possible exact real arith +TR info: dead-inf-comp.rkt 180:4 (< +inf.f rat) -- possible exact real arith +TR info: dead-inf-comp.rkt 183:4 (< rat -inf.f) -- possible exact real arith +TR info: dead-inf-comp.rkt 186:4 (< -inf.f rat) -- possible exact real arith +TR info: dead-inf-comp.rkt 190:4 (> +inf.f rat) -- possible exact real arith +TR info: dead-inf-comp.rkt 193:4 (> rat +inf.f) -- possible exact real arith +TR info: dead-inf-comp.rkt 196:4 (> -inf.f rat) -- possible exact real arith +TR info: dead-inf-comp.rkt 199:4 (> rat -inf.f) -- possible exact real arith +TR info: dead-inf-comp.rkt 203:4 (<= rat +inf.f) -- possible exact real arith +TR info: dead-inf-comp.rkt 206:4 (<= +inf.f rat) -- possible exact real arith +TR info: dead-inf-comp.rkt 209:4 (<= rat -inf.f) -- possible exact real arith +TR info: dead-inf-comp.rkt 212:4 (<= -inf.f rat) -- possible exact real arith +TR info: dead-inf-comp.rkt 216:4 (>= +inf.f rat) -- possible exact real arith +TR info: dead-inf-comp.rkt 219:4 (>= rat +inf.f) -- possible exact real arith +TR info: dead-inf-comp.rkt 222:4 (>= -inf.f rat) -- possible exact real arith +TR info: dead-inf-comp.rkt 225:4 (>= rat -inf.f) -- possible exact real arith +TR info: dead-inf-comp.rkt 230:41 displayln -- hidden parameter +TR info: dead-inf-comp.rkt 230:41 displayln -- hidden parameter +TR missed opt: dead-inf-comp.rkt 124:4 (< rat +inf.0) -- generic comparison -- caused by: 124:7 rat +TR missed opt: dead-inf-comp.rkt 127:4 (< +inf.0 rat) -- generic comparison -- caused by: 127:14 rat +TR missed opt: dead-inf-comp.rkt 130:4 (< rat -inf.0) -- generic comparison -- caused by: 130:7 rat +TR missed opt: dead-inf-comp.rkt 133:4 (< -inf.0 rat) -- generic comparison -- caused by: 133:14 rat +TR missed opt: dead-inf-comp.rkt 137:4 (> +inf.0 rat) -- generic comparison -- caused by: 137:14 rat +TR missed opt: dead-inf-comp.rkt 140:4 (> rat +inf.0) -- generic comparison -- caused by: 140:7 rat +TR missed opt: dead-inf-comp.rkt 143:4 (> -inf.0 rat) -- generic comparison -- caused by: 143:14 rat +TR missed opt: dead-inf-comp.rkt 146:4 (> rat -inf.0) -- generic comparison -- caused by: 146:7 rat +TR missed opt: dead-inf-comp.rkt 150:4 (<= rat +inf.0) -- generic comparison -- caused by: 150:8 rat +TR missed opt: dead-inf-comp.rkt 153:4 (<= +inf.0 rat) -- generic comparison -- caused by: 153:15 rat +TR missed opt: dead-inf-comp.rkt 156:4 (<= rat -inf.0) -- generic comparison -- caused by: 156:8 rat +TR missed opt: dead-inf-comp.rkt 159:4 (<= -inf.0 rat) -- generic comparison -- caused by: 159:15 rat +TR missed opt: dead-inf-comp.rkt 163:4 (>= +inf.0 rat) -- generic comparison -- caused by: 163:15 rat +TR missed opt: dead-inf-comp.rkt 166:4 (>= rat +inf.0) -- generic comparison -- caused by: 166:8 rat +TR missed opt: dead-inf-comp.rkt 169:4 (>= -inf.0 rat) -- generic comparison -- caused by: 169:15 rat +TR missed opt: dead-inf-comp.rkt 172:4 (>= rat -inf.0) -- generic comparison -- caused by: 172:8 rat +TR missed opt: dead-inf-comp.rkt 230:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- generic comparison -- caused by: 230:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) +TR missed opt: dead-inf-comp.rkt 230:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- generic comparison -- caused by: 230:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) +TR opt: dead-inf-comp.rkt 126:4 (quote dead) -- dead else branch +TR opt: dead-inf-comp.rkt 128:4 (quote dead) -- dead then branch +TR opt: dead-inf-comp.rkt 131:4 (quote dead) -- dead then branch +TR opt: dead-inf-comp.rkt 135:4 (quote dead) -- dead else branch +TR opt: dead-inf-comp.rkt 139:4 (quote dead) -- dead else branch +TR opt: dead-inf-comp.rkt 141:4 (quote dead) -- dead then branch +TR opt: dead-inf-comp.rkt 144:4 (quote dead) -- dead then branch +TR opt: dead-inf-comp.rkt 148:4 (quote dead) -- dead else branch +TR opt: dead-inf-comp.rkt 152:4 (quote dead) -- dead else branch +TR opt: dead-inf-comp.rkt 154:4 (quote dead) -- dead then branch +TR opt: dead-inf-comp.rkt 157:4 (quote dead) -- dead then branch TR opt: dead-inf-comp.rkt 161:4 (quote dead) -- dead else branch -TR opt: dead-inf-comp.rkt 163:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 166:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 170:4 (quote dead) -- dead else branch +TR opt: dead-inf-comp.rkt 165:4 (quote dead) -- dead else branch +TR opt: dead-inf-comp.rkt 167:4 (quote dead) -- dead then branch +TR opt: dead-inf-comp.rkt 170:4 (quote dead) -- dead then branch TR opt: dead-inf-comp.rkt 174:4 (quote dead) -- dead else branch -TR opt: dead-inf-comp.rkt 176:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 179:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 183:4 (quote dead) -- dead else branch -TR opt: dead-inf-comp.rkt 187:4 (quote dead) -- dead else branch -TR opt: dead-inf-comp.rkt 189:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 192:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 196:4 (quote dead) -- dead else branch -TR opt: dead-inf-comp.rkt 200:4 (quote dead) -- dead else branch -TR opt: dead-inf-comp.rkt 202:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 205:4 (quote dead) -- dead then branch -TR opt: dead-inf-comp.rkt 209:4 (quote dead) -- dead else branch -TR opt: dead-inf-comp.rkt 212:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch -TR opt: dead-inf-comp.rkt 212:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch -TR opt: dead-inf-comp.rkt 212:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch -TR opt: dead-inf-comp.rkt 212:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch -TR opt: dead-inf-comp.rkt 212:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch -TR opt: dead-inf-comp.rkt 212:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch -TR opt: dead-inf-comp.rkt 212:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch -TR opt: dead-inf-comp.rkt 212:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch -TR opt: dead-inf-comp.rkt 212:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch -TR opt: dead-inf-comp.rkt 212:36 3 -- in-range +TR opt: dead-inf-comp.rkt 179:4 (quote dead) -- dead else branch +TR opt: dead-inf-comp.rkt 181:4 (quote dead) -- dead then branch +TR opt: dead-inf-comp.rkt 184:4 (quote dead) -- dead then branch +TR opt: dead-inf-comp.rkt 188:4 (quote dead) -- dead else branch +TR opt: dead-inf-comp.rkt 192:4 (quote dead) -- dead else branch +TR opt: dead-inf-comp.rkt 194:4 (quote dead) -- dead then branch +TR opt: dead-inf-comp.rkt 197:4 (quote dead) -- dead then branch +TR opt: dead-inf-comp.rkt 201:4 (quote dead) -- dead else branch +TR opt: dead-inf-comp.rkt 205:4 (quote dead) -- dead else branch +TR opt: dead-inf-comp.rkt 207:4 (quote dead) -- dead then branch +TR opt: dead-inf-comp.rkt 210:4 (quote dead) -- dead then branch +TR opt: dead-inf-comp.rkt 214:4 (quote dead) -- dead else branch +TR opt: dead-inf-comp.rkt 218:4 (quote dead) -- dead else branch +TR opt: dead-inf-comp.rkt 220:4 (quote dead) -- dead then branch +TR opt: dead-inf-comp.rkt 223:4 (quote dead) -- dead then branch +TR opt: dead-inf-comp.rkt 227:4 (quote dead) -- dead else branch +TR opt: dead-inf-comp.rkt 230:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch +TR opt: dead-inf-comp.rkt 230:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch +TR opt: dead-inf-comp.rkt 230:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch +TR opt: dead-inf-comp.rkt 230:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch +TR opt: dead-inf-comp.rkt 230:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch +TR opt: dead-inf-comp.rkt 230:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch +TR opt: dead-inf-comp.rkt 230:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch +TR opt: dead-inf-comp.rkt 230:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch +TR opt: dead-inf-comp.rkt 230:0 (for: ((i (in-range 5 +inf.0 2)) (j 3)) (displayln i)) -- dead else branch +TR opt: dead-inf-comp.rkt 230:36 3 -- in-range END #<