mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-03-12 16:00:31 -07:00
cmp: disable inlining for global functions that are closures
For functions already compiled and loaded, we simply check if the
definition is a closure. For functions defined in the same file, we
don't store their definition in the compiler environment but instead
use *global-funs*. The advantage is that this directly allows us to
determine whether a function is a closure or not and we don't have to
run the first compiler pass again each time we inline the function.
This commit also fixes some minor issues with the inline policy,
described in detail as follows:
1. The inline policy differed subtly between `proclaim` and `declaim`.
If a file like
(eval-when (:compile-toplevel)
(proclaim '(inline f)))
(defun f ...)
was compiled (but not loaded), subsequent compilations would inline
`f` but for
(declaim (inline f))
(defun f ...)
the function `f` would only get inlined if the file was compiled _and_
loaded. We now use the latter approach for both cases. Thus, calling
`compile-file` without `load` has no side-effects regarding whether
functions are inlined or not.
2. We did not distinguish between functions which were declared inline
at a global versus local level such that e.g. in
(locally
(declare (inline f))
(defun f ...))
the function f would get inlined outside the scope of the `locally`
form. This is changed now such that local inline declarations only
apply to the scope in which they are made.
3. Inline declarations were made by expanding into statements like
(eval-when (:compile-toplevel)
(c::declare-inline ...))
during the macroexpansion of `defun`. However this only works if the
`defun` appears at the toplevel and hence in code like
(declaim (inline f))
(let (...)
(defun f ...))
the function `f` could not get inlined later on in the same file. This
is fixed now by calling the code which should run during compilation
directly when macro expanding defun.
This commit is contained in:
parent
4da9cc3a87
commit
fdcf5e7eff
4 changed files with 95 additions and 43 deletions
|
|
@ -1874,24 +1874,48 @@
|
|||
;; global function in same file, declaimed inline
|
||||
(load (with-compiler ("inline-closure.lsp")
|
||||
'(in-package #:cl-test)
|
||||
'(declaim (inline set-b.0079 get-b.0079))
|
||||
'(declaim (inline set-b.0079a get-b.0079a))
|
||||
'(let ((b 123))
|
||||
(defun set-b.0079 (x)
|
||||
(setf b x))
|
||||
(defun get-b.0079 () b))
|
||||
'(defun foo.0079 ()
|
||||
(defun set-b.0079a (x)
|
||||
(setf b x))
|
||||
(defun get-b.0079a () b))
|
||||
'(defun foo.0079a ()
|
||||
(let (results)
|
||||
(push (get-b.0079) results)
|
||||
(push (get-b.0079a) results)
|
||||
(let ((b 345))
|
||||
(push (get-b.0079) results)
|
||||
(push (get-b.0079a) results)
|
||||
(push b results)
|
||||
(set-b.0079 0)
|
||||
(push (get-b.0079) results)
|
||||
(set-b.0079a 0)
|
||||
(push (get-b.0079a) results)
|
||||
(push b results))
|
||||
(push (get-b.0079) results)
|
||||
(push (get-b.0079a) results)
|
||||
(nreverse results)))))
|
||||
(is (equal
|
||||
(funcall 'foo.0079)
|
||||
(funcall 'foo.0079a)
|
||||
'(123 123 345 0 345 0)))
|
||||
;; global function in different file, proclaimed inline
|
||||
(proclaim '(inline set-b.0079b get-b.0079b))
|
||||
(load (with-compiler ("inline-closure-1.lsp")
|
||||
'(in-package #:cl-test)
|
||||
'(let ((b 123))
|
||||
(defun set-b.0079b (x)
|
||||
(setf b x))
|
||||
(defun get-b.0079b () b))))
|
||||
(load (with-compiler ("inline-closure-2.lsp")
|
||||
'(in-package #:cl-test)
|
||||
'(defun foo.0079b ()
|
||||
(let (results)
|
||||
(push (get-b.0079b) results)
|
||||
(let ((b 345))
|
||||
(push (get-b.0079b) results)
|
||||
(push b results)
|
||||
(set-b.0079b 0)
|
||||
(push (get-b.0079b) results)
|
||||
(push b results))
|
||||
(push (get-b.0079b) results)
|
||||
(nreverse results)))))
|
||||
(is (equal
|
||||
(funcall 'foo.0079b)
|
||||
'(123 123 345 0 345 0))))
|
||||
|
||||
;;; Date 2020-05-08
|
||||
|
|
@ -2112,3 +2136,26 @@
|
|||
'(eq '#7=((#7# . a) . b) '#8=((#8# . a) . b))
|
||||
'(eq '#9=((a . #9#) . b) '#10=((a . #10#) . b))
|
||||
'(eq '#11=(#11# . #11#) '#12=(#12# . #12#)))))
|
||||
|
||||
;;; Date 2022-12-30
|
||||
;;; Description
|
||||
;;;
|
||||
;;; Check that function redefinitions for functions which are
|
||||
;;; declared as inline are picked up correctly even if we can't
|
||||
;;; inline the new definition (e.g. because it is a closure).
|
||||
;;;
|
||||
(test cmp.0092.inline-redefinition
|
||||
(setf (compiler-macro-function 'foo) nil)
|
||||
(finishes (with-compiler ("inline-redefinition-1.lsp" :load t)
|
||||
'(declaim (inline foo))
|
||||
'(defun foo () 1)
|
||||
'(defun bar () (foo))))
|
||||
(is (eql (bar) 1))
|
||||
(finishes (with-compiler ("inline-redefinition-2.lsp" :load t)
|
||||
'(let ((a 2))
|
||||
(defun ensure-compiler-cannot-optimize-away-the-let-statement (x)
|
||||
(setf a x))
|
||||
(defun foo ()
|
||||
a))
|
||||
'(defun bar () (foo))))
|
||||
(is (eql (bar) 2)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue