X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fknownfun.lisp;h=100f3ee11ef016336e7d2e3e409762c69ffcd922;hb=b7d22ded1428e8d3e87c37164aa6742dd28aa6ce;hp=078b9f103128eab5feab65b5fda026dcf56ae9bf;hpb=34360bf475b3632f625fcc263f626557ef96d94f;p=sbcl.git diff --git a/src/compiler/knownfun.lisp b/src/compiler/knownfun.lisp index 078b9f1..100f3ee 100644 --- a/src/compiler/knownfun.lisp +++ b/src/compiler/knownfun.lisp @@ -25,22 +25,29 @@ ;;; breakdown of side effects, since we do very little code motion on ;;; IR1. We are interested in some deeper semantic properties such as ;;; whether it is safe to pass stack closures to. +;;; +;;; FIXME: This whole notion of "bad" explicit attributes is bad for +;;; maintenance. How confident are we that we have no defknowns for functions +;;; with functional arguments that are missing the CALL attribute? Much better +;;; to have NO-CALLS, as it is much less likely to break accidentally. (!def-boolean-attribute ir1 ;; may call functions that are passed as arguments. In order to ;; determine what other effects are present, we must find the ;; effects of all arguments that may be functions. call - ;; may incorporate function or number arguments into the result or - ;; somehow pass them upward. Note that this applies to any argument - ;; that *might* be a function or number, not just the arguments that - ;; always are. - unsafe ;; may fail to return during correct execution. Errors are O.K. + ;; UNUSED, BEWARE OF BITROT. unwind ;; the (default) worst case. Includes all the other bad things, plus ;; any other possible bad thing. If this is present, the above bad ;; attributes will be explicitly present as well. any + ;; all arguments are safe for dynamic extent. + ;; (We used to have an UNSAFE attribute, which was basically the inverse + ;; of this, but it was unused and bitrotted, so when we started making + ;; use of the information we flipped the name and meaning the safe way + ;; around.) + dx-safe ;; may be constant-folded. The function has no side effects, but may ;; be affected by side effects on the arguments. e.g. SVREF, MAPC. ;; Functions that side-effect their arguments are not considered to @@ -67,9 +74,7 @@ important-result ;; may be moved with impunity. Has no side effects except possibly ;; consing, and is affected only by its arguments. - ;; - ;; Since it is not used now, its distribution in fndb.lisp is - ;; mere random; use with caution. + ;; UNUSED, BEWARE OF BITROT. movable ;; The function is a true predicate likely to be open-coded. Convert ;; any non-conditional uses into (IF T NIL). Not usually @@ -131,7 +136,10 @@ (templates nil :type list) ;; If non-null, then this function is a unary type predicate for ;; this type. - (predicate-type nil :type (or ctype null))) + (predicate-type nil :type (or ctype null)) + ;; If non-null, the index of the argument which becomes the result + ;; of the function. + (result-arg nil :type (or index null))) (defprinter (fun-info) (attributes :test (not (zerop attributes)) @@ -182,7 +190,8 @@ (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 @@ -196,35 +205,40 @@ (declaim (ftype (function (list list attributes &key (:derive-type (or function null)) (:optimizer (or function null)) - (:destroyed-constant-args (or function null))) + (:destroyed-constant-args (or function null)) + (:result-arg (or index null)) + (:overwrite-fndb-silently boolean)) *) %defknown)) -(defun %defknown (names type attributes &key derive-type optimizer destroyed-constant-args) +(defun %defknown (names type attributes + &key derive-type optimizer destroyed-constant-args result-arg + overwrite-fndb-silently) (let ((ctype (specifier-type type)) (info (make-fun-info :attributes attributes :derive-type derive-type :optimizer optimizer - :destroyed-constant-args destroyed-constant-args)) - (target-env *info-environment*)) + :destroyed-constant-args destroyed-constant-args + :result-arg result-arg))) (dolist (name names) - (let ((old-fun-info (info :function :info name))) - (when old-fun-info - ;; This is handled as an error because it's generally a bad - ;; thing to blow away all the old optimization stuff. It's - ;; also a potential source of sneaky bugs: - ;; DEFKNOWN FOO - ;; DEFTRANSFORM FOO - ;; DEFKNOWN FOO ; possibly hidden inside some macroexpansion - ;; ; Now the DEFTRANSFORM doesn't exist in the target Lisp. - ;; However, it's continuable because it might be useful to do - ;; it when testing new optimization stuff interactively. - (cerror "Go ahead, overwrite it." - "~@" - old-fun-info name))) - (setf (info :function :type name target-env) ctype) - (setf (info :function :where-from name target-env) :declared) - (setf (info :function :kind name target-env) :function) - (setf (info :function :info name target-env) info))) + (unless overwrite-fndb-silently + (let ((old-fun-info (info :function :info name))) + (when old-fun-info + ;; This is handled as an error because it's generally a bad + ;; thing to blow away all the old optimization stuff. It's + ;; also a potential source of sneaky bugs: + ;; DEFKNOWN FOO + ;; DEFTRANSFORM FOO + ;; DEFKNOWN FOO ; possibly hidden inside some macroexpansion + ;; ; Now the DEFTRANSFORM doesn't exist in the target Lisp. + ;; However, it's continuable because it might be useful to do + ;; it when testing new optimization stuff interactively. + (cerror "Go ahead, overwrite it." + "~@" + old-fun-info name)))) + (setf (info :function :type name) ctype) + (setf (info :function :where-from name) :declared) + (setf (info :function :kind name) :function) + (setf (info :function :info name) info))) names) ;;; Return the FUN-INFO for NAME or die trying. Since this is