[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