From 422b88abf96f4842a3d0999cd3b80d96f5a153d6 Mon Sep 17 00:00:00 2001 From: William Harold Newman Date: Tue, 23 Jul 2002 23:52:16 +0000 Subject: [PATCH] 0.7.6.3: tweaked bsd-os.h to make the new sigaltstack(2) stuff build on OpenBSD/x86 fixed bug 189: Now FLET and LABELS inlining respects NOTINLINE declarations as required by ANSI. While I'm at it, suppress FLET/LABELS inlining when (> DEBUG SPEED) too. --- BUGS | 13 +---- NEWS | 7 +++ src/compiler/info-functions.lisp | 7 ++- src/compiler/ir1opt.lisp | 2 +- src/compiler/ir1tran.lisp | 4 +- src/compiler/locall.lisp | 103 +++++++++++++++++++++++--------------- src/runtime/bsd-os.h | 8 +++ version.lisp-expr | 2 +- 8 files changed, 86 insertions(+), 60 deletions(-) diff --git a/BUGS b/BUGS index b53b355..3321811 100644 --- a/BUGS +++ b/BUGS @@ -1456,17 +1456,8 @@ WORKAROUND: (INTEGER 1296 1296) ...)>)[:EXTERNAL] -189: "ignored NOTINLINE for functions defined by FLET or LABELS" - According to the ANSI definition of the NOTINLINE declaration, - NOTINLINE specifies that it is undesirable to compile the functions - named by FUNCTION-NAMES in-line. A compiler is not free to ignore - this declaration; calls to the specified functions must be implemented - as out-of-line subroutine calls. - However, as of sbcl-0.7.5.22, Python ignores this declaration for - functions defined by LABELS and FLET, and merrily optimizes away the - LAMBDAs. (This is an annoyance not just for language lawyers, but for - people who want a useful BACKTRACE for functions which, for whatever - reason, are constrained to be implemented as LABELS or LET.) +(189: "ignored NOTINLINE for functions defined by FLET or LABELS") + (fixed in sbcl-0.7.6.3) DEFUNCT CATEGORIES OF BUGS IR1-#: diff --git a/NEWS b/NEWS index 4e294df..eab5231 100644 --- a/NEWS +++ b/NEWS @@ -1190,6 +1190,13 @@ changes in sbcl-0.7.6 relative to sbcl-0.7.5: (user-invisible) bitrotted stuff. (E.g. *!INITIAL-FDEFN-OBJECTS* is no longer a static symbol.) +changes in sbcl-0.7.7 relative to sbcl-0.7.6: + * fixed bug 189: The compiler now respects NOTINLINE declarations for + functions declared in FLET and LABELS. (I.e. "LET conversion" is + suppressed.) Also now that the compiler is looking at declarations + in the environment, it checks optimization declarations as well, + and suppresses inlining when (> DEBUG SPEED). + planned incompatible changes in 0.7.x: * When the profiling interface settles down, maybe in 0.7.x, maybe later, it might impact TRACE. They both encapsulate functions, and diff --git a/src/compiler/info-functions.lisp b/src/compiler/info-functions.lisp index b9dfd71..52cf65f 100644 --- a/src/compiler/info-functions.lisp +++ b/src/compiler/info-functions.lisp @@ -189,10 +189,9 @@ (defun sb!xc:compiler-macro-function (name &optional env) #!+sb-doc - "If NAME names a compiler-macro, returns the expansion function, - else returns NIL. Note: if the name is shadowed in ENV by a local - definition, or declared NOTINLINE, NIL is returned. Can be - set with SETF." + "If NAME names a compiler-macro, return the expansion function, else + return NIL. Note: if the name is shadowed in ENV by a local definition, + or declared NOTINLINE, NIL is returned. Can be set with SETF." (let ((found (and env (cdr (assoc name (sb!c::lexenv-funs env) :test #'equal))))) diff --git a/src/compiler/ir1opt.lisp b/src/compiler/ir1opt.lisp index 5626039..f034d4a 100644 --- a/src/compiler/ir1opt.lisp +++ b/src/compiler/ir1opt.lisp @@ -1228,7 +1228,7 @@ (derive-node-type node (continuation-type (set-value node))) (values)) -;;; Return true if the value of Ref will always be the same (and is +;;; Return true if the value of REF will always be the same (and is ;;; thus legal to substitute.) (defun constant-reference-p (ref) (declare (type ref ref)) diff --git a/src/compiler/ir1tran.lisp b/src/compiler/ir1tran.lisp index 80aba16..579e41d 100644 --- a/src/compiler/ir1tran.lisp +++ b/src/compiler/ir1tran.lisp @@ -2065,8 +2065,8 @@ (setf (functional-inlinep fun) (defined-fun-inlinep var)) (assert-new-definition var fun) (setf (defined-fun-inline-expansion var) var-expansion) - ;; If definitely not an interpreter stub, then substitute for any - ;; old references. + ;; If definitely not an interpreter stub, then substitute for + ;; any old references. (unless (or (eq (defined-fun-inlinep var) :notinline) (not *block-compile*) (and fun-info diff --git a/src/compiler/locall.lisp b/src/compiler/locall.lisp index 9846de7..2a2bd49 100644 --- a/src/compiler/locall.lisp +++ b/src/compiler/locall.lisp @@ -970,58 +970,79 @@ (reoptimize-continuation (node-cont call)) (values)) +;;; Are there any declarations in force to say CLAMBDA shouldn't be +;;; LET converted? +(defun declarations-suppress-let-conversion-p (clambda) + ;; From the user's point of view, LET-converting something that + ;; has a name is inlining it. (The user can't see what we're doing + ;; with anonymous things, and suppressing inlining + ;; for such things can easily give Python acute indigestion, so + ;; we don't.) + (when (leaf-has-source-name-p clambda) + ;; ANSI requires that explicit NOTINLINE be respected. + (or (eq (lambda-inlinep clambda) :notinline) + ;; If (> DEBUG SPEED) we can guess that inlining generally + ;; won't be appreciated, but if the user specifically requests + ;; inlining, that takes precedence over our general guess. + (and (policy clambda (> debug speed)) + (not (eq (lambda-inlinep clambda) :inline)))))) + ;;; We also don't convert calls to named functions which appear in the ;;; initial component, delaying this until optimization. This ;;; minimizes the likelihood that we will LET-convert a function which ;;; may have references added due to later local inline expansion. (defun ok-initial-convert-p (fun) (not (and (leaf-has-source-name-p fun) - (eq (component-kind (lambda-component fun)) - :initial)))) + (or (declarations-suppress-let-conversion-p fun) + (eq (component-kind (lambda-component fun)) + :initial))))) ;;; This function is called when there is some reason to believe that ;;; CLAMBDA might be converted into a LET. This is done after local -;;; call analysis, and also when a reference is deleted. We only -;;; convert to a let when the function is a normal local function, has -;;; no XEP, and is referenced in exactly one local call. Conversion is -;;; also inhibited if the only reference is in a block about to be -;;; deleted. We return true if we converted. -;;; -;;; These rules may seem unnecessarily restrictive, since there are -;;; some cases where we could do the return with a jump that don't -;;; satisfy these requirements. The reason for doing things this way -;;; is that it makes the concept of a LET much more useful at the -;;; level of IR1 semantics. The :ASSIGNMENT function kind provides -;;; another way to optimize calls to single-return/multiple call -;;; functions. -;;; -;;; We don't attempt to convert calls to functions that have an XEP, -;;; since we might be embarrassed later when we want to convert a -;;; newly discovered local call. Also, see OK-INITIAL-CONVERT-P. +;;; call analysis, and also when a reference is deleted. We return +;;; true if we converted. (defun maybe-let-convert (clambda) (declare (type clambda clambda)) - (let ((refs (leaf-refs clambda))) - (when (and refs - (null (rest refs)) - (member (functional-kind clambda) '(nil :assignment)) - (not (functional-entry-fun clambda))) - (let* ((ref-cont (node-cont (first refs))) - (dest (continuation-dest ref-cont))) - (when (and dest - (basic-combination-p dest) - (eq (basic-combination-fun dest) ref-cont) - (eq (basic-combination-kind dest) :local) - (not (block-delete-p (node-block dest))) - (cond ((ok-initial-convert-p clambda) t) - (t - (reoptimize-continuation ref-cont) - nil))) - (unless (eq (functional-kind clambda) :assignment) - (let-convert clambda dest)) - (reoptimize-call dest) - (setf (functional-kind clambda) - (if (mv-combination-p dest) :mv-let :let)))) - t))) + (unless (declarations-suppress-let-conversion-p clambda) + ;; We only convert to a LET when the function is a normal local + ;; function, has no XEP, and is referenced in exactly one local + ;; call. Conversion is also inhibited if the only reference is in + ;; a block about to be deleted. + ;; + ;; These rules limiting LET conversion may seem unnecessarily + ;; restrictive, since there are some cases where we could do the + ;; return with a jump that don't satisfy these requirements. The + ;; reason for doing things this way is that it makes the concept + ;; of a LET much more useful at the level of IR1 semantics. The + ;; :ASSIGNMENT function kind provides another way to optimize + ;; calls to single-return/multiple call functions. + ;; + ;; We don't attempt to convert calls to functions that have an + ;; XEP, since we might be embarrassed later when we want to + ;; convert a newly discovered local call. Also, see + ;; OK-INITIAL-CONVERT-P. + (let ((refs (leaf-refs clambda))) + (when (and refs + (null (rest refs)) + (member (functional-kind clambda) '(nil :assignment)) + (not (functional-entry-fun clambda))) + (let* ((ref-cont (node-cont (first refs))) + (dest (continuation-dest ref-cont))) + (when (and dest + (basic-combination-p dest) + (eq (basic-combination-fun dest) ref-cont) + (eq (basic-combination-kind dest) :local) + (not (block-delete-p (node-block dest))) + (cond ((ok-initial-convert-p clambda) t) + (t + (reoptimize-continuation ref-cont) + nil))) + (unless (eq (functional-kind clambda) :assignment) + (let-convert clambda dest)) + (reoptimize-call dest) + (setf (functional-kind clambda) + (if (mv-combination-p dest) :mv-let :let)))) + t)))) ;;;; tail local calls and assignments diff --git a/src/runtime/bsd-os.h b/src/runtime/bsd-os.h index 86d8f6e..3cbf029 100644 --- a/src/runtime/bsd-os.h +++ b/src/runtime/bsd-os.h @@ -23,6 +23,14 @@ typedef off_t os_vm_offset_t; typedef int os_vm_prot_t; typedef int os_context_register_t; +#if defined __OpenBSD__ +/* name defined for compatibility between OpenBSD 3.1 sigaltstack(2) and + * Linux sigaltstack(2) */ +typedef struct sigaltstack stack_t; +#elif defined __FreeBSD__ +/* FreeBSD 4.6 already has stack_t defined. */ +#endif + #if defined __FreeBSD__ /* Note: The man page for sigaction(2) in FreeBSD 4.0 says that this * is an mcontext_t, but according to comments by Raymond Wiker in the diff --git a/version.lisp-expr b/version.lisp-expr index 17859d9..f6bf2b5 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -18,4 +18,4 @@ ;;; for internal versions, especially for internal versions off the ;;; main CVS branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"0.7.6.2" +"0.7.6.3" -- 1.7.10.4