Skip to content

Commit a06638a

Browse files
committed
add reductions for + in cptypes
Reduce + with some combintations of values that are known at compile time to be real (+ <fx> <fx> ...) => ($fxx+ <fx> <fx> ...) (+ <fl> <fx> ...) => (fl+ <fl> (fixnum->flonum <fx>) ...) (+ <fl> <real> ...) => (fl+ <fl> (real->flonum <real>) ...) (+ <fl> <fl> ...) => (fl+ <fl> <fl>) with some special cases for 0, in particular (+ <fl> 1 ...) => (fl+ <fl> 1.0 ...) (+ <fl> 0 ...) => (fl+ <fl> -0.0 ...) (+ 1.0 0 ...) => (fl+ 1.0 0.0 ...)
1 parent 7db61e9 commit a06638a

File tree

8 files changed

+254
-11
lines changed

8 files changed

+254
-11
lines changed

mats/cptypes.ms

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,23 @@
5959
#;[optimize-level (max (optimize-level) 2)])
6060
(expand/optimize y)))]))
6161
62+
(define-syntax cptypes/first-equivalent-expansion?
63+
; When run-cp0 is call, use first #3%$cptypes and
64+
; then twice the cp0 function provided.
65+
; This checks that cptypes.ss doesn't mess up unusual combinations
66+
; that are reduced by cp0.
67+
(syntax-rules ()
68+
[(_ x y)
69+
(equivalent-expansion?
70+
(parameterize ([run-cp0 (lambda (cp0 c) (cp0 (cp0 (#3%$cptypes c))))]
71+
[#%$suppress-primitive-inlining #f]
72+
#;[optimize-level (max (optimize-level) 2)])
73+
(expand/optimize x))
74+
(parameterize ([run-cp0 (lambda (cp0 c) (cp0 (cp0 (#3%$cptypes c))))]
75+
[#%$suppress-primitive-inlining #f]
76+
#;[optimize-level (max (optimize-level) 2)])
77+
(expand/optimize y)))]))
78+
6279
(mat cptypes-handcoded
6380
(cptypes-equivalent-expansion?
6481
'(vector? (vector)) ;actually reduced by folding, not cptypes
@@ -658,6 +675,7 @@
658675
(test-chain* '(fixnum? integer? real?))
659676
(test-chain* '(fixnum? exact? number?)) ; exact? may raise an error
660677
(test-chain* '(bignum? exact? number?)) ; exact? may raise an error
678+
(test-chain '(fixnum? (lambda (x) (and (integer? x) (exact? x))) (lambda (x) (and (number? x) (exact? x))) number?))
661679
(test-chain '((lambda (x) (eqv? x (expt 256 100))) bignum? integer? real? number?))
662680
(test-chain '((lambda (x) (eqv? 0.0 x)) flonum? real? number?))
663681
(test-chain '((lambda (x) (eqv? 0.0 x)) flonum? cflonum? number?))
@@ -1006,6 +1024,100 @@
10061024
'(flonum? real? (lambda (x) (and (integer? x) (exact? x)))))
10071025
)
10081026
1027+
(mat cptypes-plus
1028+
(test-closed1 '(+ (lambda (x) (+ x 1)) (lambda (x) (+ x x)))
1029+
'(flonum? real? (lambda (x) (and (integer? x) (exact? x))) (lambda (x) (and (number? x) (exact? x)))))
1030+
(cptypes-equivalent-expansion?
1031+
'(lambda (x y) (when (and (fixnum? x) (fixnum? y))
1032+
(+ x y)))
1033+
'(lambda (x y) (when (and (fixnum? x) (fixnum? y))
1034+
(#3%$fxx+ x y))))
1035+
(cptypes-equivalent-expansion?
1036+
'(lambda (x y) (when (and (flonum? x) (flonum? y))
1037+
(+ x y)))
1038+
'(lambda (x y) (when (and (flonum? x) (flonum? y))
1039+
(#3%fl+ x y))))
1040+
(cptypes-equivalent-expansion?
1041+
'(lambda (x y) (when (and (number? x) (number? y))
1042+
(+ x y)))
1043+
'(lambda (x y) (when (and (number? x) (number? y))
1044+
(#3%+ x y))))
1045+
; in cp0, partial-folder reverses (+ x 1) to (+ 1 x)
1046+
(cptypes-equivalent-expansion?
1047+
'(lambda (x) (when (fixnum? x)
1048+
(+ 1 x)))
1049+
'(lambda (x) (when (fixnum? x)
1050+
(#3%$fxx+ 1 x))))
1051+
(cptypes-equivalent-expansion?
1052+
'(lambda (x) (when (flonum? x)
1053+
(+ 1 x)))
1054+
'(lambda (x) (when (flonum? x)
1055+
(#3%fl+ 1.0 x))))
1056+
(cptypes-equivalent-expansion?
1057+
'(lambda (x) (when (number? x)
1058+
(+ 1 x)))
1059+
'(lambda (x) (when (number? x)
1060+
(#3%+ 1 x))))
1061+
(cptypes-equivalent-expansion?
1062+
'(lambda (x) (when (fixnum? x)
1063+
(+ 1.0 x)))
1064+
'(lambda (x) (when (fixnum? x)
1065+
(#3%fl+ 1.0 (fixnum->flonum x)))))
1066+
(cptypes-equivalent-expansion?
1067+
'(lambda (x) (when (fixnum? x)
1068+
(+ -0.0 x)))
1069+
'(lambda (x) (when (fixnum? x)
1070+
(#3%fl+ -0.0 (if (#3%eq? x 0) -0.0 (fixnum->flonum x))))))
1071+
(cptypes-equivalent-expansion?
1072+
'(lambda (x) (when (bignum? x)
1073+
(+ -0.0 x)))
1074+
'(lambda (x) (when (bignum? x)
1075+
(#3%fl+ -0.0 (real->flonum x)))))
1076+
(cptypes-equivalent-expansion?
1077+
'(lambda (x) (when (flonum? x)
1078+
(+ 1.0 x)))
1079+
'(lambda (x) (when (flonum? x)
1080+
(#3%fl+ 1.0 x))))
1081+
(cptypes-equivalent-expansion?
1082+
'(lambda (x) (when (number? x)
1083+
(+ 1.0 x)))
1084+
'(lambda (x) (when (number? x)
1085+
(#3%+ 1.0 x))))
1086+
(cptypes-equivalent-expansion?
1087+
'(lambda (x) (when (fixnum? x)
1088+
(+ 1 x x)))
1089+
'(lambda (x) (when (fixnum? x)
1090+
(#3%$fxx+ 1 x x))))
1091+
(cptypes-equivalent-expansion?
1092+
'(lambda (x) (when (flonum? x)
1093+
(+ 1 x x)))
1094+
'(lambda (x) (when (flonum? x)
1095+
(#3%fl+ 1.0 x x))))
1096+
(cptypes-equivalent-expansion?
1097+
'(lambda (x) (when (number? x)
1098+
(+ 1 x x)))
1099+
'(lambda (x) (when (number? x)
1100+
(#3%+ 1 x x))))
1101+
(cptypes/first-equivalent-expansion?
1102+
'(lambda (x) (+))
1103+
'(lambda (x) 0))
1104+
(cptypes/first-equivalent-expansion?
1105+
'(lambda (x) (+ 0))
1106+
'(lambda (x) 0))
1107+
(cptypes/first-equivalent-expansion?
1108+
'(lambda (x) (+ 0 0))
1109+
'(lambda (x) 0))
1110+
(cptypes/first-equivalent-expansion?
1111+
'(lambda (x) (+ 0 0.0))
1112+
'(lambda (x) 0.0))
1113+
(cptypes/first-equivalent-expansion?
1114+
'(lambda (x) (+ 0 -0.0))
1115+
'(lambda (x) -0.0))
1116+
(cptypes/first-equivalent-expansion?
1117+
'(lambda (x) (+ 0.0 -0.0))
1118+
'(lambda (x) 0.0))
1119+
)
1120+
10091121
(mat cptypes-rest-argument
10101122
(cptypes/nocp0-equivalent-expansion?
10111123
'((lambda (x . r) (pair? r)) 1)

s/cp0.ss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3077,6 +3077,7 @@
30773077
; the multiply case. maybe shouldn't bother with nans anyway.
30783078
(partial-folder plus + + 0 generic-nan?)
30793079
(partial-folder plus fx+ + 0 (lambda (x) #f) 3)
3080+
(partial-folder plus $fxx+ + 0 (lambda (x) #f))
30803081
(r6rs-fixnum-partial-folder plus r6rs:fx+ fx+ + 0 (lambda (x) #f) 3)
30813082
(r6rs-fixnum-partial-folder plus fx+/wraparound fx+/wraparound + 0 (lambda (x) #f) 3)
30823083
(partial-folder plus fl+ fl+ -0.0 fl-nan? #f obviously-fl?)

s/cpprim.ss

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1750,12 +1750,16 @@
17501750
,t))
17511751
(goto ,Lfalse))))])
17521752
(define-inline 3 $fxx+
1753+
[() `(immediate ,(fix 0))]
1754+
[(e) (ensure-single-valued e)]
17531755
[(e1 e2)
17541756
(bind #t (e1 e2)
17551757
(bind #f ([t (%inline +/ovfl ,e1 ,e2)])
17561758
`(if (inline ,(make-info-condition-code 'overflow #f #t) ,%condition-code)
17571759
,(build-libcall #t src sexpr + e1 e2)
1758-
,t)))])
1760+
,t)))]
1761+
[e* #f])
1762+
17591763
(let ()
17601764
(define (go src sexpr e1 e2)
17611765
(let ([Llib (make-local-label 'Llib)])

s/cptypes-lattice.ss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@
6666
real-pred
6767
number-pred
6868
flzero-pred
69+
flinteger-pred
70+
exact-real-pred
71+
exact-pred
72+
inexact-pred
73+
integer-pred
6974
$fixmediate-pred
7075
$list-pred ; immutable lists
7176
list-pair-pred

s/cptypes.ss

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,49 @@ Notes:
355355
[(ref ,maybe-src ,x) (and (not (prelex-assigned x)) x)]
356356
[else #f])))
357357

358+
(define (real-expr->flonum-expr x r)
359+
; Transform 0 into 0.0 as usual
360+
; Assume (predicate-implies r real-pred)
361+
(cond
362+
[(and (Lsrc? r)
363+
(nanopass-case (Lsrc Expr) r
364+
[(quote ,d) d]
365+
[else #f])) =>
366+
(lambda (d) (make-1seq 'value x `(quote ,(real->flonum d))))]
367+
[(predicate-implies? r flonum-pred)
368+
x]
369+
[else
370+
(let ([->flonum-name (if (predicate-implies? r 'fixnum)
371+
'fixnum->flonum
372+
'real->flonum)])
373+
`(call ,(make-preinfo-call) ,(lookup-primref 3 ->flonum-name) ,x))]))
374+
375+
(define (real-expr->flonum-expr/- x r)
376+
; Transform 0 into -0.0 instead of 0.0
377+
; Assume (predicate-implies r real-pred)
378+
(cond
379+
[(and (Lsrc? r)
380+
(nanopass-case (Lsrc Expr) r
381+
[(quote ,d) d]
382+
[else #f])) =>
383+
(lambda (d) (make-1seq 'value x `(quote ,(if (eqv? d 0) -0.0 (real->flonum d)))))]
384+
[(predicate-implies? r flonum-pred)
385+
x]
386+
[else
387+
(let ([->flonum-name (if (predicate-implies? r 'fixnum)
388+
'fixnum->flonum
389+
'real->flonum)])
390+
(cond
391+
[(predicate-disjoint? r `(quote 0))
392+
`(call ,(make-preinfo-call) ,(lookup-primref 3 ->flonum-name) ,x)]
393+
[else
394+
(build-let 'value (list x) (list r)
395+
(lambda (x*)
396+
(let ([x (car x*)])
397+
`(if (call ,(make-preinfo-call) ,(lookup-primref 3 'eq?) ,x (quote 0))
398+
(quote -0.0)
399+
(call ,(make-preinfo-call) ,(lookup-primref 3 ->flonum-name) ,x)))))]))]))
400+
358401
(define (filter/head+rest pred? l)
359402
; (filter/head+rest odd? '(1 3 2 5 4 6))
360403
; ==> (values '(1 3) '(2 5 4 6))
@@ -1141,6 +1184,71 @@ Notes:
11411184
(and (eq? ctxt 'test)
11421185
(pred-env-add/ref ntypes val (rtd->record-predicate rtd #t) plxc))
11431186
#f)]))])
1187+
1188+
(let ()
1189+
(define (predicate-implies-real? r) (predicate-implies? r real-pred))
1190+
(define (predicate-implies-fixnum? r) (predicate-implies? r 'fixnum))
1191+
(define (predicate-implies-integer? r) (predicate-implies? r integer-pred))
1192+
(define (predicate-implies-flonum? r) (predicate-implies? r flonum-pred))
1193+
(define (predicate-implies-exact? r) (predicate-implies? r exact-pred))
1194+
(define (predicate-implies-inexact? r) (predicate-implies? r inexact-pred))
1195+
1196+
(define (predicate-close/plus r*)
1197+
(cond
1198+
[(andmap predicate-implies-exact? r*)
1199+
(if (andmap predicate-implies-real? r*)
1200+
(if (andmap predicate-implies-integer? r*)
1201+
'exact-integer
1202+
exact-real-pred)
1203+
exact-pred)]
1204+
[(ormap predicate-implies-inexact? r*)
1205+
(if (andmap predicate-implies-real? r*)
1206+
flonum-pred
1207+
inexact-pred)]
1208+
[else
1209+
(if (andmap predicate-implies-real? r*)
1210+
real-pred
1211+
number-pred)]))
1212+
1213+
(define-specialize 2 +
1214+
[() (values `(quote 0) `(quote 0) ntypes #f #f)]
1215+
[(x) (values `(call ,preinfo ,pr ,x)
1216+
(predicate-intersect (get-type x) number-pred) ntypes #f #f)]
1217+
[x* ; x* has at least 2 arguments
1218+
(let* ([r* (get-type x*)]
1219+
[ret (predicate-close/plus
1220+
(map (lambda (r) (predicate-intersect r number-pred)) r*))]
1221+
[ir (and (andmap predicate-implies-real? r*)
1222+
(cond
1223+
[(andmap predicate-implies-fixnum? r*)
1224+
`(call ,preinfo ,(lookup-primref 3 '$fxx+) ,x* ...)]
1225+
[(and (or (enable-arithmetic-left-associative)
1226+
(fx= (length r*) 2))
1227+
; at least one of the first two is a flonum
1228+
(or (predicate-implies-flonum? (car r*))
1229+
(predicate-implies-flonum? (cadr r*))))
1230+
(cond
1231+
[(and (predicate-disjoint? (car r*) `(quote -0.0))
1232+
(predicate-disjoint? (cadr r*) `(quote -0.0)))
1233+
; use 0.0 in the first two and -0.0 in the others
1234+
`(call ,preinfo ,(lookup-primref 3 'fl+)
1235+
,(real-expr->flonum-expr (car x*) (car r*))
1236+
,(real-expr->flonum-expr (cadr x*) (cadr r*))
1237+
,(map real-expr->flonum-expr/- (cddr x*) (cddr r*)) ...)]
1238+
[else
1239+
`(call ,preinfo ,(lookup-primref 3 'fl+)
1240+
,(map real-expr->flonum-expr/- x* r*) ...)])]
1241+
[(and ; all or all but one are flonums, in case they are reordered
1242+
(let-values ([(head* rest*)
1243+
(filter/head+rest predicate-implies-flonum? r*)])
1244+
(or (null? rest*)
1245+
(andmap predicate-implies-flonum? (cdr rest*)))))
1246+
`(call ,preinfo ,(lookup-primref 3 'fl+)
1247+
,(map real-expr->flonum-expr/- x* r*) ...)]
1248+
[else
1249+
#f]))])
1250+
(values (or ir `(call ,preinfo ,pr ,x* ...)) ret ntypes #f #f))])
1251+
)
11441252

11451253
(define-specialize 2 (add1 sub1 1+ 1- -1+)
11461254
[(n) (let ([r (get-type n)])

s/mathprims.ss

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -524,10 +524,27 @@
524524
(#3%$fxu< x y)))
525525

526526
(set! $fxx+
527-
(lambda (x y)
528-
(unless (fixnum? x) (fxargerr '$fxx+ x))
529-
(unless (fixnum? y) (fxargerr '$fxx+ y))
530-
(#3%$fxx+ x y)))
527+
(case-lambda
528+
[(x1 x2)
529+
(unless (fixnum? x1) (fxargerr '$fxx+ x1))
530+
(unless (fixnum? x2) (fxargerr '$fxx+ x2))
531+
(#3%$fxx+ x1 x2)]
532+
[(x1 x2 x3)
533+
(unless (fixnum? x1) (fxargerr '$fxx+ x1))
534+
(unless (fixnum? x2) (fxargerr '$fxx+ x2))
535+
(unless (fixnum? x3) (fxargerr '$fxx+ x3))
536+
(#3%+ (#3%$fxx+ x1 x2) x3)]
537+
[(x1 x2 x3 . rest)
538+
(unless (fixnum? x1) (fxargerr '$fxx+ x1))
539+
(unless (fixnum? x2) (fxargerr '$fxx+ x2))
540+
(let loop ([x1 (#3%$fxx+ x1 x2)] [x3 x3] [rest rest])
541+
(unless (fixnum? x3) (fxargerr '$fxx+ x3))
542+
(let ([x (#3%+ x1 x3)])
543+
(if (null? rest) x (loop x (car rest) (cdr rest)))))]
544+
[(x1)
545+
(unless (fixnum? x1) (fxargerr '$fxx+ x1))
546+
x1]
547+
[() 0]))
531548

532549
(define-addop fxlogand)
533550
(define-addop fxlogior)

s/primdata.ss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@
211211
(nan? [sig [(real) -> (boolean)]] [flags pure mifoldable discard safeongoodargs])
212212
(max [sig [(real real ...) -> (real)]] [flags arith-op mifoldable discard safeongoodargs ieee r5rs cptypes2])
213213
(min [sig [(real real ...) -> (real)]] [flags arith-op mifoldable discard safeongoodargs ieee r5rs cptypes2])
214-
(+ [sig [(number ...) -> (number)]] [flags arith-op partial-folder safeongoodargs ieee r5rs])
214+
(+ [sig [(number ...) -> (number)]] [flags arith-op partial-folder safeongoodargs ieee r5rs cptypes2])
215215
(* [sig [(number ...) -> (number)]] [flags arith-op partial-folder safeongoodargs ieee r5rs])
216216
(- [sig [(number number ...) -> (number)]] [flags arith-op partial-folder safeongoodargs ieee r5rs])
217217
(/ [sig [(number number ...) -> (number)]] [flags arith-op partial-folder ieee r5rs])
@@ -2215,7 +2215,7 @@
22152215
($fxu< [flags single-valued pure cp02])
22162216
($fxvector-ref-check? [sig [(ptr ptr) -> (boolean)]] [flags unrestricted pure])
22172217
($fxvector-set!-check? [sig [(ptr ptr) -> (boolean)]] [flags unrestricted discard])
2218-
($fxx+ [sig [(fixnum fixnum) -> (sint)]] [flags arith-op safeongoodargs])
2218+
($fxx+ [sig [(fixnum ...) -> (sint)]] [flags arith-op partial-folder safeongoodargs])
22192219
($gc-cpu-time [flags true])
22202220
($gc-real-time [flags true])
22212221
($generation [flags single-valued])

s/prims.ss

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -832,10 +832,6 @@
832832
(lambda (x y)
833833
($fx+? x y)))
834834

835-
(define $fxx+
836-
(lambda (x y)
837-
($fxx+ x y)))
838-
839835
(define $fx-?
840836
(lambda (x y)
841837
($fx-? x y)))

0 commit comments

Comments
 (0)