[cmucl-imp] Type propagation for load-time-value
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
* Helmut Eller [2011-08-06 18:38] writes:
I'm proposing a patch to improve type propagation for load-time-value.
Oops, something removed the attachment. Here it is again: --- ltv.lisp.~1.4.~ 2010-04-28 09:40:16.000000000 +0200 +++ ltv.lisp 2011-08-06 20:28:13.792158931 +0200 @@ -35,10 +35,10 @@ (compile-load-time-value (if read-only-p form `(make-value-cell ,form))) - (declare (ignore type)) (ir1-convert start cont (if read-only-p - `(%load-time-value ',handle) + `(truly-the ,(type-specifier type) + (%load-time-value ',handle)) `(value-cell-ref (%load-time-value ',handle))))) (let ((value (handler-case (eval form) --- main.lisp.~1.159.~ 2010-12-29 15:51:19.000000000 +0100 +++ main.lisp 2011-08-06 20:21:03.709158808 +0200 @@ -1246,10 +1246,13 @@ (let ((lambda (compile-load-time-stuff form name t))) (values (fasl-dump-load-time-value-lambda lambda *compile-object*) - (let ((type (leaf-type lambda))) - (if (function-type-p type) - (single-value-type (function-type-returns type)) - *wild-type*))))) + (or (let ((return (lambda-return lambda))) + (if return + (single-value-type (return-result-type return)))) + (let ((type (leaf-type lambda))) + (if (function-type-p type) + (single-value-type (function-type-returns type)))) + *wild-type*)))) ;;; COMPILE-MAKE-LOAD-FORM-INIT-FORMS -- internal. ;;;
participants (2)
-
Helmut Eller -
Raymond Toy