[cmucl-imp] Type propagation for load-time-value

Helmut Eller heller at common-lisp.net
Sat Aug 6 20:38:20 CEST 2011


I'm proposing a patch to improve type propagation for load-time-value.
Sorry for the long message:

Let's say we have a file bar.lisp containing:

(defun bar (x y) (declare (ignore x y)))
(defun fun () #'bar)
(defun baz (x y) (funcall #'bar x y))

and another file foo.lisp:

(defun foo (x y)
  (funcall (load-time-value (let ((f (funcall 'fun)))
                              (etypecase f
                                (function f)))
                            t)
           x y))

(defun frob ()
  (time (dotimes (i 10000000) (foo 1 2)))
  (time (dotimes (i 10000000) (baz 1 2))))

and then do

(load (compile-file "bar.lisp"))
(load (compile-file "foo.lisp"))
(frob)

we see that foo runs a bit slower than baz.  If we repeat the same with
the in-memory compiler then foo and baz run at about the same speed:

(compile (defun foo (x y)
           (funcall (load-time-value (let ((f (funcall 'fun)))
                                       (etypecase f
                                         (function f)))
                                     t)
                    x y)))
(frob)


The cause seems to be that the ir1-translator for load-time-value throws
type information away when producing fasl files an so the typecheck is
executed at run time.

The patch does two things:

1. in the ir1-translator actually use the type and insert a truly-the
   form.  I only touched the read-only case; not sure what can
   be done in the other case.

2. change compile-load-time-value a bit: look at the result type of the
   return node instead of looking only at the function type of the
   load-time-lambda.  This type seems to be more precise.  I left the
   function type thing as fallback, though it looks dubious.

With the patch applied the file compiler produces the same code as the
in-memory compiler.  I only tested it with this example.

Helmut




More information about the cmucl-imp mailing list