;;; a utility for defining derive-type methods of integer operations. If
;;; the types of both X and Y are integer types, then we compute a new
;;; integer type with bounds determined Fun when applied to X and Y.
-;;; Otherwise, we use Numeric-Contagion.
+;;; Otherwise, we use NUMERIC-CONTAGION.
(defun derive-integer-type-aux (x y fun)
(declare (type function fun))
(if (and (numeric-type-p x) (numeric-type-p y)
;;; simple utility to flatten a list
(defun flatten-list (x)
- (labels ((flatten-helper (x r);; 'r' is the stuff to the 'right'.
- (cond ((null x) r)
- ((atom x)
- (cons x r))
- (t (flatten-helper (car x)
- (flatten-helper (cdr x) r))))))
- (flatten-helper x nil)))
+ (labels ((flatten-and-append (tree list)
+ (cond ((null tree) list)
+ ((atom tree) (cons tree list))
+ (t (flatten-and-append
+ (car tree) (flatten-and-append (cdr tree) list))))))
+ (flatten-and-append x nil)))
;;; Take some type of lvar and massage it so that we get a list of the
;;; constituent types. If ARG is *EMPTY-TYPE*, return NIL to indicate
(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
- :invalid)
- (funcall fun x y))))
- (cond ((null result))
+ (result (ignore-errors
+ (with-float-traps-masked
+ (:underflow :overflow :divide-by-zero
+ :invalid)
+ (funcall fun x y)))))
+ (cond ((null result) *empty-type*)
((and (floatp result) (float-nan-p result))
(make-numeric-type :class 'float
:format (type-of result)
(defoptimizer (integer-length derive-type) ((x))
(let ((x-type (lvar-type x)))
- (when (and (numeric-type-p x-type)
- (csubtypep x-type (specifier-type 'integer)))
+ (when (numeric-type-p x-type)
;; If the X is of type (INTEGER LO HI), then the INTEGER-LENGTH
;; of X is (INTEGER (MIN lo hi) (MAX lo hi), basically. Be
;; careful about LO or HI being NIL, though. Also, if 0 is
(setf min-len 0))
(specifier-type `(integer ,(or min-len '*) ,(or max-len '*))))))))
+(defoptimizer (isqrt derive-type) ((x))
+ (let ((x-type (lvar-type x)))
+ (when (numeric-type-p x-type)
+ (let* ((lo (numeric-type-low x-type))
+ (hi (numeric-type-high x-type))
+ (lo-res (if lo (isqrt lo) '*))
+ (hi-res (if hi (isqrt hi) '*)))
+ (specifier-type `(integer ,lo-res ,hi-res))))))
+
(defoptimizer (code-char derive-type) ((code))
(specifier-type 'base-char))
(setf (block-reoptimize (node-block node)) t)
(setf (component-reoptimize (node-component node)) t))
(cut-node (node &aux did-something)
- (when (and (combination-p node)
+ (when (and (not (block-delete-p (node-block node)))
+ (combination-p node)
(fun-info-p (basic-combination-kind node)))
(let* ((fun-ref (lvar-use (combination-fun node)))
(fun-name (leaf-source-name (ref-leaf fun-ref)))
`(- (ash (- x) ,shift)))
(- (logand (- x) ,mask)))
(values ,(if (minusp y)
- `(- (ash (- x) ,shift))
+ `(ash (- ,mask x) ,shift)
`(ash x ,shift))
(logand x ,mask))))))
;;; information. If X's high bound is < Y's low, then X < Y.
;;; Similarly, if X's low is >= to Y's high, the X >= Y (so return
;;; NIL). If not, at least make sure any constant arg is second.
-(macrolet ((def (name reflexive-p surely-true surely-false)
+(macrolet ((def (name inverse reflexive-p surely-true surely-false)
`(deftransform ,name ((x y))
(if (same-leaf-ref-p x y)
,reflexive-p
- (let ((x (or (type-approximate-interval (lvar-type x))
- (give-up-ir1-transform)))
- (y (or (type-approximate-interval (lvar-type y))
- (give-up-ir1-transform))))
+ (let ((ix (or (type-approximate-interval (lvar-type x))
+ (give-up-ir1-transform)))
+ (iy (or (type-approximate-interval (lvar-type y))
+ (give-up-ir1-transform))))
(cond (,surely-true
t)
(,surely-false
nil)
((and (constant-lvar-p x)
(not (constant-lvar-p y)))
- `(,',name y x))
+ `(,',inverse y x))
(t
(give-up-ir1-transform))))))))
- (def < nil (interval-< x y) (interval->= x y))
- (def > nil (interval-< y x) (interval->= y x))
- (def <= t (interval->= y x) (interval-< y x))
- (def >= t (interval->= x y) (interval-< x y)))
+ (def < > nil (interval-< ix iy) (interval->= ix iy))
+ (def > < nil (interval-< iy ix) (interval->= iy ix))
+ (def <= >= t (interval->= iy ix) (interval-< iy ix))
+ (def >= <= t (interval->= ix iy) (interval-< ix iy)))
(defun ir1-transform-char< (x y first second inverse)
(cond