;;; Bind the value and make a closure that returns it.
(define-source-transform constantly (value)
- (let ((rest (gensym "CONSTANTLY-REST-"))
- (n-value (gensym "CONSTANTLY-VALUE-")))
+ (with-unique-names (rest n-value)
`(let ((,n-value ,value))
(lambda (&rest ,rest)
(declare (ignore ,rest))
;;; are equal to an intermediate convention for which they are
;;; considered different which is more natural for some of the
;;; optimisers.
-#!-negative-zero-is-not-zero
(defun convert-numeric-type (type)
(declare (type numeric-type type))
;;; Only convert real float interval delimiters types.
:low (if lo-float-zero-p
(if (consp lo)
(list (float 0.0 lo-val))
- (float -0.0 lo-val))
+ (float (load-time-value (make-unportable-float :single-float-negative-zero)) lo-val))
lo)
:high (if hi-float-zero-p
(if (consp hi)
- (list (float -0.0 hi-val))
+ (list (float (load-time-value (make-unportable-float :single-float-negative-zero)) hi-val))
(float 0.0 hi-val))
hi))
type))
;;; Convert back from the intermediate convention for which -0.0 and
;;; 0.0 are considered different to the standard type convention for
;;; which and equal.
-#!-negative-zero-is-not-zero
(defun convert-back-numeric-type (type)
(declare (type numeric-type type))
;;; Only convert real float interval delimiters types.
type))
;;; Convert back a possible list of numeric types.
-#!-negative-zero-is-not-zero
(defun convert-back-numeric-type-list (type-list)
(typecase type-list
(list
;;; FIXME: MAKE-CANONICAL-UNION-TYPE and CONVERT-MEMBER-TYPE probably
;;; belong in the kernel's type logic, invoked always, instead of in
-;;; the compiler, invoked only during some type optimizations.
+;;; the compiler, invoked only during some type optimizations. (In
+;;; fact, as of 0.pre8.100 or so they probably are, under
+;;; MAKE-MEMBER-TYPE, so probably this code can be deleted)
;;; Take a list of types and return a canonical type specifier,
;;; combining any MEMBER types together. If both positive and negative
(setf members (union members (member-type-members type)))
(push type misc-types)))
#!+long-float
- (when (null (set-difference '(-0l0 0l0) members))
- #!-negative-zero-is-not-zero
- (push (specifier-type '(long-float 0l0 0l0)) misc-types)
- #!+negative-zero-is-not-zero
- (push (specifier-type '(long-float -0l0 0l0)) misc-types)
- (setf members (set-difference members '(-0l0 0l0))))
- (when (null (set-difference '(-0d0 0d0) members))
- #!-negative-zero-is-not-zero
- (push (specifier-type '(double-float 0d0 0d0)) misc-types)
- #!+negative-zero-is-not-zero
- (push (specifier-type '(double-float -0d0 0d0)) misc-types)
- (setf members (set-difference members '(-0d0 0d0))))
- (when (null (set-difference '(-0f0 0f0) members))
- #!-negative-zero-is-not-zero
- (push (specifier-type '(single-float 0f0 0f0)) misc-types)
- #!+negative-zero-is-not-zero
- (push (specifier-type '(single-float -0f0 0f0)) misc-types)
- (setf members (set-difference members '(-0f0 0f0))))
+ (when (null (set-difference `(,(load-time-value (make-unportable-float :long-float-negative-zero)) 0.0l0) members))
+ (push (specifier-type '(long-float 0.0l0 0.0l0)) misc-types)
+ (setf members (set-difference members `(,(load-time-value (make-unportable-float :long-float-negative-zero)) 0.0l0))))
+ (when (null (set-difference `(,(load-time-value (make-unportable-float :double-float-negative-zero)) 0.0d0) members))
+ (push (specifier-type '(double-float 0.0d0 0.0d0)) misc-types)
+ (setf members (set-difference members `(,(load-time-value (make-unportable-float :double-float-negative-zero)) 0.0d0))))
+ (when (null (set-difference `(,(load-time-value (make-unportable-float :single-float-negative-zero)) 0.0f0) members))
+ (push (specifier-type '(single-float 0.0f0 0.0f0)) misc-types)
+ (setf members (set-difference members `(,(load-time-value (make-unportable-float :single-float-negative-zero)) 0.0f0))))
(if members
(apply #'type-union (make-member-type :members members) misc-types)
(apply #'type-union misc-types))))
(defun one-arg-derive-type (arg derive-fcn member-fcn
&optional (convert-type t))
(declare (type function derive-fcn)
- (type (or null function) member-fcn)
- #!+negative-zero-is-not-zero (ignore convert-type))
+ (type (or null function) member-fcn))
(let ((arg-list (prepare-arg-for-derive-type (continuation-type arg))))
(when arg-list
(flet ((deriver (x)
;; Otherwise convert to a numeric type.
(let ((result-type-list
(funcall derive-fcn (convert-member-type x))))
- #!-negative-zero-is-not-zero
(if convert-type
(convert-back-numeric-type-list result-type-list)
- result-type-list)
- #!+negative-zero-is-not-zero
- result-type-list)))
+ result-type-list))))
(numeric-type
- #!-negative-zero-is-not-zero
(if convert-type
(convert-back-numeric-type-list
(funcall derive-fcn (convert-numeric-type x)))
- (funcall derive-fcn x))
- #!+negative-zero-is-not-zero
- (funcall derive-fcn x))
+ (funcall derive-fcn x)))
(t
*universal-type*))))
;; Run down the list of args and derive the type of each one,
(defun two-arg-derive-type (arg1 arg2 derive-fcn fcn
&optional (convert-type t))
(declare (type function derive-fcn fcn))
- #!+negative-zero-is-not-zero
- (declare (ignore convert-type))
- (flet (#!-negative-zero-is-not-zero
- (deriver (x y same-arg)
+ (flet ((deriver (x y same-arg)
(cond ((and (member-type-p x) (member-type-p y))
(let* ((x (first (member-type-members x)))
(y (first (member-type-members y)))
(convert-back-numeric-type-list result)
result)))
(t
- *universal-type*)))
- #!+negative-zero-is-not-zero
- (deriver (x y same-arg)
- (cond ((and (member-type-p x) (member-type-p y))
- (let* ((x (first (member-type-members x)))
- (y (first (member-type-members y)))
- (result (with-float-traps-masked
- (:underflow :overflow :divide-by-zero)
- (funcall fcn x y))))
- (if result
- (make-member-type :members (list result)))))
- ((and (member-type-p x) (numeric-type-p y))
- (let ((x (convert-member-type x)))
- (funcall derive-fcn x y same-arg)))
- ((and (numeric-type-p x) (member-type-p y))
- (let ((y (convert-member-type y)))
- (funcall derive-fcn x y same-arg)))
- ((and (numeric-type-p x) (numeric-type-p y))
- (funcall derive-fcn x y same-arg))
- (t
*universal-type*))))
(let ((same-arg (same-leaf-ref-p arg1 arg2))
(a1 (prepare-arg-for-derive-type (continuation-type arg1)))
) ; PROGN
-
-;;; KLUDGE: All this ASH optimization is suppressed under CMU CL
-;;; because as of version 2.4.6 for Debian, CMU CL blows up on (ASH
-;;; 1000000000 -100000000000) (i.e. ASH of two bignums yielding zero)
-;;; and it's hard to avoid that calculation in here.
-#-(and cmu sb-xc-host)
-(progn
-
(defun ash-derive-type-aux (n-type shift same-arg)
(declare (ignore same-arg))
+ ;; KLUDGE: All this ASH optimization is suppressed under CMU CL for
+ ;; some bignum cases because as of version 2.4.6 for Debian and 18d,
+ ;; CMU CL blows up on (ASH 1000000000 -100000000000) (i.e. ASH of
+ ;; two bignums yielding zero) and it's hard to avoid that
+ ;; calculation in here.
+ #+(and cmu sb-xc-host)
+ (when (and (or (typep (numeric-type-low n-type) 'bignum)
+ (typep (numeric-type-high n-type) 'bignum))
+ (or (typep (numeric-type-low shift) 'bignum)
+ (typep (numeric-type-high shift) 'bignum)))
+ (return-from ash-derive-type-aux *universal-type*))
(flet ((ash-outer (n s)
(when (and (fixnump s)
(<= s 64)
(defoptimizer (ash derive-type) ((n shift))
(two-arg-derive-type n shift #'ash-derive-type-aux #'ash))
-) ; PROGN
#+sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
(macrolet ((frob (fun)