;; in the safe code. If a function MUST signal errors, then it is
;; not unsafely-flushable even if it is movable or foldable.
unsafely-flushable
+ ;; return value is important, and ignoring it is probably a mistake.
+ ;; Unlike the other attributes, this is used only for style
+ ;; warnings and has no effect on optimization.
+ important-result
;; may be moved with impunity. Has no side effects except possibly
;; consing, and is affected only by its arguments.
;;
;; The function does explicit argument type checking, so the
;; declared type should not be asserted when a definition is
;; compiled.
- explicit-check)
+ explicit-check
+ ;; The function should always be translated by a VOP (i.e. it should
+ ;; should never be converted into a full call). This is used strictly
+ ;; as a consistency checking mechanism inside the compiler during IR2
+ ;; transformation.
+ always-translatable)
(defstruct (fun-info #-sb-xc-host (:pure t))
;; boolean attributes of this function.
;; further optimiz'ns) is backwards from the return convention for
;; transforms. -- WHN 19990917
(optimizer nil :type (or function null))
+ ;; a function computing the constant or literal arguments which are
+ ;; destructively modified by the call.
+ (destroyed-constant-args nil :type (or function null))
;; If true, a special-case LTN annotation method that is used in
;; place of the standard type/policy template selection. It may use
;; arbitrary code to choose a template, decide to do a full call, or
(eq (transform-important x) important)))
(fun-info-transforms info))))
(cond (old
- (style-warn "Overwriting ~S" old)
+ (style-warn 'sb!kernel:redefinition-with-deftransform
+ :transform old)
(setf (transform-function old) fun
(transform-note old) note))
(t
;;; and optimizers.
(declaim (ftype (function (list list attributes &key
(:derive-type (or function null))
- (:optimizer (or function null)))
+ (:optimizer (or function null))
+ (:destroyed-constant-args (or function null)))
*)
%defknown))
-(defun %defknown (names type attributes &key derive-type optimizer)
+(defun %defknown (names type attributes &key derive-type optimizer destroyed-constant-args)
(let ((ctype (specifier-type type))
(info (make-fun-info :attributes attributes
:derive-type derive-type
- :optimizer optimizer))
+ :optimizer optimizer
+ :destroyed-constant-args destroyed-constant-args))
(target-env *info-environment*))
(dolist (name names)
(let ((old-fun-info (info :function :info name)))
real-ctype)
ctype)))))))))
+(defun remove-non-constants-and-nils (fun)
+ (lambda (list)
+ (remove-if-not #'lvar-value
+ (remove-if-not #'constant-lvar-p (funcall fun list)))))
+
+;;; FIXME: bad name (first because it uses 1-based indexing; second
+;;; because it doesn't get the nth constant arguments)
+(defun nth-constant-args (&rest indices)
+ (lambda (list)
+ (let (result)
+ (do ((i 1 (1+ i))
+ (list list (cdr list))
+ (indices indices))
+ ((null indices) (nreverse result))
+ (when (= i (car indices))
+ (when (constant-lvar-p (car list))
+ (push (car list) result))
+ (setf indices (cdr indices)))))))
+
+;;; FIXME: a number of the sequence functions not only do not destroy
+;;; their argument if it is empty, but also leave it alone if :start
+;;; and :end bound a null sequence, or if :count is 0. This test is a
+;;; bit complicated to implement, verging on the impossible, but for
+;;; extra points (fill #\1 "abc" :start 0 :end 0) should not cause a
+;;; warning.
+(defun nth-constant-nonempty-sequence-args (&rest indices)
+ (lambda (list)
+ (let (result)
+ (do ((i 1 (1+ i))
+ (list list (cdr list))
+ (indices indices))
+ ((null indices) (nreverse result))
+ (when (= i (car indices))
+ (when (constant-lvar-p (car list))
+ (let ((value (lvar-value (car list))))
+ (unless (or (typep value 'null)
+ (typep value '(vector * 0)))
+ (push (car list) result))))
+ (setf indices (cdr indices)))))))
+
(/show0 "knownfun.lisp end of file")