0.7.6.3:
authorWilliam Harold Newman <william.newman@airmail.net>
Tue, 23 Jul 2002 23:52:16 +0000 (23:52 +0000)
committerWilliam Harold Newman <william.newman@airmail.net>
Tue, 23 Jul 2002 23:52:16 +0000 (23:52 +0000)
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
NEWS
src/compiler/info-functions.lisp
src/compiler/ir1opt.lisp
src/compiler/ir1tran.lisp
src/compiler/locall.lisp
src/runtime/bsd-os.h
version.lisp-expr

diff --git a/BUGS b/BUGS
index b53b355..3321811 100644 (file)
--- 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 (file)
--- 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
index b9dfd71..52cf65f 100644 (file)
 
 (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)))))
index 5626039..f034d4a 100644 (file)
   (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))
index 80aba16..579e41d 100644 (file)
       (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
index 9846de7..2a2bd49 100644 (file)
   (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))))
 \f
 ;;;; tail local calls and assignments
 
index 86d8f6e..3cbf029 100644 (file)
@@ -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
index 17859d9..f6bf2b5 100644 (file)
@@ -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"