X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fsrctran.lisp;h=997e50b12083b32fe41ed9831f1a6398203b9ef4;hb=a6661cdaac013752213d381aa469cb0919a6ce4c;hp=caed9bfead711d1ad49d4cfebb4c58c91101143e;hpb=ab705efcc1d020c427e63349275388a972617385;p=sbcl.git diff --git a/src/compiler/srctran.lisp b/src/compiler/srctran.lisp index caed9bf..997e50b 100644 --- a/src/compiler/srctran.lisp +++ b/src/compiler/srctran.lisp @@ -176,12 +176,11 @@ (loop for (arg next) on args while next do - (let ((lvar-type (lvar-type arg))) - (unless (or (csubtypep list-type lvar-type) - (csubtypep lvar-type list-type)) - (assert-lvar-type arg list-type - (lexenv-policy *lexenv*)) - (return *empty-type*)))) + (when (eq (type-intersection (lvar-type arg) list-type) + *empty-type*) + (assert-lvar-type arg list-type + (lexenv-policy *lexenv*)) + (return *empty-type*))) (loop with all-nil = t for (arg next) on args for lvar-type = (lvar-type arg) @@ -189,7 +188,7 @@ do (cond ;; Cons in the middle guarantees the result will be a cons - ((csubtypep lvar-type cons-type) + ((not (csubtypep null-type lvar-type)) (return cons-type)) ;; If all but the last are NIL the type of the last arg ;; can be used @@ -2823,16 +2822,17 @@ "Convert %ASH/RIGHT by constant back to ASH" `(ash integer ,(- (lvar-value amount)))) - (deftransform %ash/right ((integer amount) * (member -1 0) :node node) - ;; constant-fold large shifts + (deftransform %ash/right ((integer amount) * * :node node) + "strength reduce large variable right shift" (let ((return-type (single-value-type (node-derived-type node)))) (cond ((type= return-type (specifier-type '(eql 0))) 0) ((type= return-type (specifier-type '(eql -1))) -1) + ((csubtypep return-type (specifier-type '(member -1 0))) + `(ash integer ,(- sb!vm:n-word-bits))) (t - (aver (csubtypep (lvar-type integer) (specifier-type 'sb!vm:signed-word))) - `(ash integer ,(- 1 sb!vm:n-word-bits)))))) + (give-up-ir1-transform))))) (defun %ash/right-derive-type-aux (n-type shift same-arg) (declare (ignore same-arg)) @@ -2933,7 +2933,8 @@ (mask-signed-field width constant-value) (ldb (byte width 0) constant-value)))) (unless (= constant-value new-value) - (change-ref-leaf node (make-constant new-value)) + (change-ref-leaf node (make-constant new-value) + :recklessly t) (let ((lvar (node-lvar node))) (setf (lvar-%derived-type lvar) (and (lvar-has-single-use-p lvar) @@ -4653,3 +4654,35 @@ (policy-quality-name-p (lvar-value quality-name))) (give-up-ir1-transform)) '(%policy-quality policy quality-name)) + +(deftransform encode-universal-time + ((second minute hour date month year &optional time-zone) + ((constant-arg (mod 60)) (constant-arg (mod 60)) + (constant-arg (mod 24)) + (constant-arg (integer 1 31)) + (constant-arg (integer 1 12)) + (constant-arg (integer 1899)) + (constant-arg (rational -24 24)))) + (let ((second (lvar-value second)) + (minute (lvar-value minute)) + (hour (lvar-value hour)) + (date (lvar-value date)) + (month (lvar-value month)) + (year (lvar-value year)) + (time-zone (lvar-value time-zone))) + (if (zerop (rem time-zone 1/3600)) + (encode-universal-time second minute hour date month year time-zone) + (give-up-ir1-transform)))) + +#!-(and win32 (not sb-thread)) +(deftransform sleep ((seconds) ((integer 0 #.(expt 10 8)))) + `(sb!unix:nanosleep seconds 0)) + +#!-(and win32 (not sb-thread)) +(deftransform sleep ((seconds) ((constant-arg (real 0)))) + (let ((seconds-value (lvar-value seconds))) + (multiple-value-bind (seconds nano) + (sb!impl::split-seconds-for-sleep seconds-value) + (if (> seconds (expt 10 8)) + (give-up-ir1-transform) + `(sb!unix:nanosleep ,seconds ,nano)))))