[pro] return-with-dynamic-extent...

Nikodemus Siivola nikodemus at random-state.net
Sun May 6 19:49:40 UTC 2012


On 6 May 2012 22:27, Pascal Costanza <pc at p-cos.net> wrote:

> What would be nice is, if we could instead have some form of saying that we want to
> return a data structure on the stack:
>
> (defun vplus (v1 v2)
>  (let ((v (make-vec :x (+ (vec-x v1) (vec-x v2))
>                     :y (+ (vec-y v1) (vec-y v2))
>                     :z (+ (vec-z v1) (vec-z v2)))))
>    (declare (dynamic-extent v))
>    (return-with-dynamic-extent v))
>
> The idea is that now, the data that v refers to is returned by value on the stack.
> If the call site receives the value with a matching dynamic-extent declaration,
> then v can just stay on the stack. Same (hopefully) for intermediate results in
> more complex expressions.

I don't see a way to support this in SBCL without massive effort. On
the face of it this is very much at odds with the way SBCL reasons
about stack allocation. No idea about other implementations.

However, you /can/ write code like this in SBCL and "just" have it
work by inlining VPLUS -- and leaving the DX declarations out from
there. If that doesn't produce the expected results, I would consider
it a bug in SBCLs intended level of DX support.

In my experience, what is more helpful is a way to declare the a
certain argument is either dynamic extent (ie. not retained or
incorportated into the result), or specifically incorporated to the
result -- but not retained in any other way.

So:

(declaim (ftype (function ((dynamic-extent t) (result-extent t)) t) foo)

would mean that in

(let ((x (foo (list 1) (list 2)))
      (y (foo (list 3) (list 4)))
   (declare (dynamic-extent x y))
   ...)

the compiler would know it can stack allocate (LIST 1) and (LIST 2),
because the first argument to FOO is /always/ DX, and it can also
stack allocate (LIST 4) because the second argument to FOO is DX if
the result of FOO is DX.

SBCL implements the RESULT-EXTENT bit internally for things like FILL,
but the DX argument bit isn't actually in place -- but could be added
almost trivially.

I would guess that implementations supporting DX could take advantage
of such declarations as well with only reasonable (in the "SMOP"
sense...) amount of work.

Cheers,

 -- nikodemus




More information about the pro mailing list