comp.lang.ada
 help / color / mirror / Atom feed
From: "Nick Roberts" <nick.roberts@acm.org>
Subject: Re: Where are returned values stored?
Date: Sun, 30 May 2004 22:17:17 +0100
Date: 2004-05-30T22:17:17+01:00	[thread overview]
Message-ID: <2hv1auFhi91aU1@uni-berlin.de> (raw)
In-Reply-To: 1dptc.49822$tb4.1731604@news20.bellglobal.com

"Warren W. Gay VE3WWG" <ve3wwg@cogeco.ca> wrote in message
news:1dptc.49822$tb4.1731604@news20.bellglobal.com...

> If you're worried about the inefficiency of copying data around,
> then I would suggest that the above advice is good. Leave that
> up to the compiler/machine team.
>
> If you really must know more than that, then you'll need to look
> at the assembler output, but maybe the following explanation
> might save you from bothering/worrying about it:
>
> Conceptually, there is _no_ reason a compiler _must_ copy a
> return value. Consider a function like:
>
> function Foo return String is
>    I : Integer := 23;
>    S : String(1..3) := "Bar";
>    X : Natural := 0;
> begin
>    ...
>    return S;
> end;
>
> To return S, all the compiler needs to do is to extend the
> caller's stack frame to claim all the storage up to and
> including S (I and S assuming sequential assignment), at
> the point when Foo returns (return effectively does
> reclaim the storage used for X however).
>
> Then the calling code can reference S as if it were a
> local variable.  The space used for I is
> wasted at this point, but temporarily, who cares?
>
> Once the compiler knows that the caller's use of the returned
> value S is no longer required, the stack frame can be shrunk
> back to the original size that it had prior to calling Foo.
>
> Is this done? Is it done by GNAT? I have no idea, but I
> suspect that this is done in some places, some of the time,
> by some compilers. Perhaps, someone in this group
> can confirm/debunk this idea.

I don't think any compiler does quite as you suggest, Warren, but many do
something similar: they allocate two stacks to each task, usually called the
'primary' and 'secondary' stacks; the primary stack is used as the normal
stack, and the secondary is used exclusively for returning indefinite
function results.

In the common case of all the return statements in a function being of the
form 'return S' (as above), S will be allocated on the secondary stack. When
Foo returns, its stack frame (containing I and X plus some other stuff) is
deallocated (from the primary stack), but the calling code can access the
result (S) on the secondary stack. When the calling code has finished with
S, it deallocates it (from the secondary stack).

In the general case (return statements returning expressions), an anonymous
intermediate variable is used instead of S, and it is this anonymous
variable that is allocated on the secondary stack.

You can see that this works fine for recursive functions, although a
rewriting (so it is no longer recursive) of a recursive function that
returns an indefinite type may produce a much more memory-efficient
algorithm.

The only problem is that you have two stacks per task. That can add up to a
lot of stacks for some programs! One optimisation is to determine if a task
will never call a function that needs a secondary stack, and eliminate the
(allocation of) the secondary stack for such tasks; if my memory serves me,
I think I've heard of an Ada compiler that does this optimisation.

I think all those compilers which don't use a secondary stack use the heap
(or some storage pool) instead.

-- 
Nick Roberts





  parent reply	other threads:[~2004-05-30 21:17 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-05-26 19:46 Where are returned values stored? (follow up to yesterday's question) James Alan Farrell
2004-05-26 20:44 ` Simon Wright
2004-05-27  7:51   ` Dmitry A. Kazakov
2004-05-27  9:39 ` Where are returned values stored? Marius Amado Alves
2004-05-27 17:05   ` Warren W. Gay VE3WWG
2004-05-27 20:24     ` James Alan Farrell
2004-05-28 20:33       ` Warren W. Gay VE3WWG
2004-05-29  7:03         ` Martin Krischik
2004-05-29 13:19           ` Larry Kilgallen
2004-05-30  7:10             ` Martin Krischik
2004-06-02  3:14         ` Robert I. Eachus
2004-05-30 21:17     ` Nick Roberts [this message]
2004-05-31 12:58       ` Warren W. Gay VE3WWG
2004-06-02  4:07         ` Robert I. Eachus
2004-06-02 12:42           ` Warren W. Gay VE3WWG
2004-06-03  2:00             ` Nick Roberts
2004-06-03  4:34             ` Robert I. Eachus
2004-06-03 16:06               ` Warren W. Gay VE3WWG
2004-06-03 16:13               ` Nick Roberts
2004-06-07  1:53                 ` Robert I. Eachus
2004-06-07 13:09                   ` Larry Kilgallen
2004-06-09  7:03                     ` Robert I. Eachus
2004-06-05 17:13             ` Simon Wright
2004-05-27 17:11   ` Martin Krischik
2004-05-27 17:07 ` Where are returned values stored? (follow up to yesterday's question) Martin Krischik
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox