The attached patch fixes bug 430: nested structure constructors do not
stack allocate, and more generally makes stack allocation from inlined
functions work properly:
(declaim (inline fii))
(defun fii (&optional (a 1) (b 2))
(list a b))
(defun fii-it (a b)
(let ((fii (fii (fii a b) (fii b a))))
(declare (dynamic-extent fii))
FII-IT can stack allocate the lists with this patch.
The patch breaks one of the current test-cases:
(defun-with-dx let-converted-vars-dx-allocated-bug (x y z)
(let* ((a (list x y z))
(b (list x y z))
(c (list a b)))
(declare (dynamic-extent c))
(values (first c) (second c))))
(with-test (:name :let-converted-vars-dx-allocated-bug)
(multiple-value-bind (i j) (let-converted-vars-dx-allocated-bug 1 2 3)
(assert (and (equal i j)
(equal i (list 1 2 3))))))
...which I don't think is actually a valid test-case -- even though
I'm the one who wrote it in the first place. If returned values are A
and B instead, it works as expected. It is not obvious to me at the
moment how to retain both this behaviour, and allow stack allocation
in the inline case as above.
Input on the validity of this test-case much appreciated, as well as
any insight on how to deal with inline functions in cases like FII-IT
without breaking this case.
* Allow USE-GOOD-FOR-DX-P to inspect COMBINATIONs with CLAMBDA
functionals: if the return value of the function always originates
from a known DX-capable combination, and the arguments of the
original combination are used only by the DX-capable combination,
consider the combination good for DX.
* Allow USE-GOOD-FOR-DX-P to inspect REFs to LAMBDA-VARs: if the var
has no other REFs, is never set, is bound by a single-value
combination, and the LVAR it gets it's value from in the combination
is good for DX ... then the REF is good for DX as well.
Code reviews and more hairy test-cases welcome.