1.0.14.36: faster PROPAGATE-FROM-SETS
authorNikodemus Siivola <nikodemus@random-state.net>
Mon, 18 Feb 2008 19:25:22 +0000 (19:25 +0000)
committerNikodemus Siivola <nikodemus@random-state.net>
Mon, 18 Feb 2008 19:25:22 +0000 (19:25 +0000)
 20-25% improvement for the test-case in bug 188.

 * New slot in LAMBDA-VAR: LAST-INITIAL-TYPE, which holds the last
   initial-type for that variable seen by PROPAGATE-FROM-SETS.

 * Be lazy, and don't PROPAGATE-TO-REFS unless something of
   interest has happened, to wit:

    -- One of the CSET nodes has a new, more specific type.

    -- INITIAL-TYPE has become more specific.

   This also allows us elide TYPE-UNION computation in the
   uninteresting cases.

 * Requires having NODE-REOPTIMIZE set when IR1-OPTIMIZE-SET
   is called.

BUGS
NEWS
src/compiler/ir1opt.lisp
src/compiler/node.lisp
version.lisp-expr

diff --git a/BUGS b/BUGS
index 4c64490..298e43a 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -479,6 +479,11 @@ WORKAROUND:
                (print (incf start 22))
                (print (incf start 26))))))
 
+  [ Update: 1.0.14.36 improved this quite a bit (20-25%) by
+    eliminating useless work from PROPAGATE-FROM-SETS -- but as alluded
+    below, maybe we should be smarter about when to decide a derived
+    type is "good enough". ]
+
   This example could be solved with clever enough constraint
   propagation or with SSA, but consider
 
diff --git a/NEWS b/NEWS
index 6c04c72..10c3bb2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,10 @@ changes in sbcl-1.0.15 relative to sbcl-1.0.14:
     when SB-DEBUG:*SHOW-ENTRY-POINT-DETAILS* is NIL.
   * unreadably printed representation of hash-tables now includes
     weakness if any.
+  * bug fix: partially fixed #188: type propagation from assignments
+    is now more efficient.
+  * bug fix: fixed #407: (COERCE X 'SINGLE-FLOAT) and (COERCE X
+    'DOUBLE-FLOAT) are not flushable.
   * bug fix: on x86 and x86-64 pointer based EQ-hashing now uses the
     full address of the object, and none of the tag bits.
   * bug fix: readably printing hash-tables now respects other printer
index d574148..548c1c9 100644 (file)
            (when value
              (derive-node-type node (lvar-derived-type value)))))
         (cset
+         ;; PROPAGATE-FROM-SETS can do a better job if NODE-REOPTIMIZE
+         ;; is accurate till the node actually has been reoptimized.
+         (setf (node-reoptimize node) t)
          (ir1-optimize-set node))
         (cast
          (ir1-optimize-cast node)))))
 ;;; the union of the INITIAL-TYPE and the types of all the set
 ;;; values and to a PROPAGATE-TO-REFS with this type.
 (defun propagate-from-sets (var initial-type)
-  (collect ((res initial-type type-union))
-    (dolist (set (basic-var-sets var))
+  (let ((changes (not (csubtypep (lambda-var-last-initial-type var) initial-type)))
+        (types nil))
+    (dolist (set (lambda-var-sets var))
       (let ((type (lvar-type (set-value set))))
-        (res type)
+        (push type types)
         (when (node-reoptimize set)
-          (derive-node-type set (make-single-value-type type))
+          (let ((old-type (node-derived-type set)))
+            (unless (values-subtypep old-type type)
+              (derive-node-type set (make-single-value-type type))
+              (setf changes t)))
           (setf (node-reoptimize set) nil))))
-    (let ((res (res)))
-      (awhen (maybe-infer-iteration-var-type var initial-type)
-        (setq res it))
-      (propagate-to-refs var res)))
+    (when changes
+      (setf (lambda-var-last-initial-type var) initial-type)
+      (let ((res-type (or (maybe-infer-iteration-var-type var initial-type)
+                          (apply #'type-union initial-type types))))
+        (propagate-to-refs var res-type))))
   (values))
 
 ;;; If a LET variable, find the initial value's type and do
                  (initial-type (lvar-type initial-value)))
             (setf (lvar-reoptimize initial-value) nil)
             (propagate-from-sets var initial-type))))))
-
   (derive-node-type node (make-single-value-type
                           (lvar-type (set-value node))))
+  (setf (node-reoptimize node) nil)
   (values))
 
 ;;; Return true if the value of REF will always be the same (and is
index cb88d83..ac17c72 100644 (file)
   ;; determine that this is a set closure variable, and is thus not a
   ;; good subject for flow analysis.
   (constraints nil :type (or sset null))
+  ;; Initial type of a LET variable as last seen by PROPAGATE-FROM-SETS.
+  (last-initial-type *universal-type* :type ctype)
   ;; The FOP handle of the lexical variable represented by LAMBDA-VAR
   ;; in the fopcompiler.
   (fop-value nil))
index 7a7f7b3..eb8296e 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.14.35"
+"1.0.14.36"