Skip to content

Commit

Permalink
1.0.14.36: faster PROPAGATE-FROM-SETS
Browse files Browse the repository at this point in the history
 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.
  • Loading branch information
nikodemus committed Feb 18, 2008
1 parent 81153b7 commit 6d3b9d5
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 10 deletions.
5 changes: 5 additions & 0 deletions BUGS
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 17 additions & 9 deletions src/compiler/ir1opt.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@
(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)))))
Expand Down Expand Up @@ -1342,17 +1345,22 @@
;;; 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
Expand All @@ -1368,9 +1376,9 @@
(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
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/node.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,8 @@
;; 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))
Expand Down
2 changes: 1 addition & 1 deletion version.lisp-expr
Original file line number Diff line number Diff line change
Expand Up @@ -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"

0 comments on commit 6d3b9d5

Please sign in to comment.