values in other threads.
* new feature: SB-INTROSPECT:ALLOCATION-INFORMATION provides information
about object allocation.
+ * optimization: more efficient complex float and real float operations
+ on x86-64.
+ * optimization: division of a real float by a complex float is implemented
+ with a specialised code sequence.
* optimization: MAKE-INSTANCE with non-constant class-argument but constant
keywords is an order of magnitude faster.
* optimization: MAKE-INSTANCE with constant keyword arguments is somewhat
* optimization: compiler now optimizes (EXPT -1 INTEGER), (EXPT -1.0 INTEGER),
and (EXPT -1.0d0 INTEGER) into an ODDP test. (thanks to Stas Boukarev and
Paul Khuong)
+ * improvement: less unsafe constant folding in floating point arithmetic,
+ especially for mixed complex/real -float operations.
+ * improvement: complex float division is slightly more stable.
* improvement: DESCRIBE output has been reworked to be easier to read and
contains more pertinent information.
* improvement: failure to provide requested stack allocation compiler notes
(bignum-cross-fixnum ,op ,big-op)
(float-contagion ,op x y)
- ((complex complex)
+ ((complex complex) +
(canonical-complex (,op (realpart x) (realpart y))
(,op (imagpart x) (imagpart y))))
(((foreach bignum fixnum ratio single-float double-float
#!+long-float long-float) complex)
- (complex (,op x (realpart y)) (,op (imagpart y))))
+ (complex (,op x (realpart y)) (,op 0 (imagpart y))))
((complex (or rational float))
- (complex (,op (realpart x) y) (imagpart x)))
+ (complex (,op (realpart x) y) (,op (imagpart x) 0)))
(((foreach fixnum bignum) ratio)
(let* ((dy (denominator y))
(values (type= (numeric-contagion x y)
(numeric-contagion y y)))))))
+(def!type exact-number ()
+ '(or rational (complex rational)))
+
;;; Fold (+ x 0).
;;;
-;;; If y is not constant, not zerop, or is contagious, or a positive
-;;; float +0.0 then give up.
-(deftransform + ((x y) (t (constant-arg t)) *)
+;;; Only safely applicable for exact numbers. For floating-point
+;;; x, one would have to first show that neither x or y are signed
+;;; 0s, and that x isn't an SNaN.
+(deftransform + ((x y) (exact-number (constant-arg (eql 0))) *)
"fold zero arg"
- (let ((val (lvar-value y)))
- (unless (and (zerop val)
- (not (and (floatp val) (plusp (float-sign val))))
- (not-more-contagious y x))
- (give-up-ir1-transform)))
'x)
;;; Fold (- x 0).
-;;;
-;;; If y is not constant, not zerop, or is contagious, or a negative
-;;; float -0.0 then give up.
-(deftransform - ((x y) (t (constant-arg t)) *)
+(deftransform - ((x y) (exact-number (constant-arg (eql 0))) *)
"fold zero arg"
- (let ((val (lvar-value y)))
- (unless (and (zerop val)
- (not (and (floatp val) (minusp (float-sign val))))
- (not-more-contagious y x))
- (give-up-ir1-transform)))
'x)
;;; Fold (OP x +/-1)
-(macrolet ((def (name result minus-result)
- `(deftransform ,name ((x y) (t (constant-arg real)) *)
- "fold identity operations"
- (let ((val (lvar-value y)))
- (unless (and (= (abs val) 1)
- (not-more-contagious y x))
- (give-up-ir1-transform))
- (if (minusp val) ',minus-result ',result)))))
+;;;
+;;; %NEGATE might not always signal correctly.
+(macrolet
+ ((def (name result minus-result)
+ `(deftransform ,name ((x y)
+ (exact-number (constant-arg (member 1 -1))))
+ "fold identity operations"
+ (if (minusp (lvar-value y)) ',minus-result ',result))))
(def * x (%negate x))
(def / x (%negate x))
(def expt x (/ 1 x)))
(assert (eql 0.0d0 (funcall f 123.0d0 0.0d0)))
(assert (eql 0.0d0 (funcall f 123.0 0.0d0)))))
-
-;; 1.0.29.xFIXMEx introduces a ton of changes for complex floats
+;; 1.0.29.44 introduces a ton of changes for complex floats
;; on x86-64. Huge test of doom to help catch weird corner
;; cases.
(with-test (:name :complex-floats)
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.29.46"
+"1.0.29.47"