gcl-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gcl-devel] Re: woe unto me: multiple value


From: Camm Maguire
Subject: [Gcl-devel] Re: woe unto me: multiple value
Date: 21 Apr 2006 14:01:32 -0400
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

Greetings!

Nay, woe unto me!

Robert Boyer <address@hidden> writes:

> > I surmise that Allegro is avoiding even one copy by making
> > the call like this:
> > (*LI1)(x,y,&r1,&r2,&r3);
> 
> I really have no idea what Allegro is doing (or, really,
> what GCL is doing, other than to say GCL produces C).  Once
> upon a time, I could read some machine code, but not for the
> x86.  And considering how, or so I imagine, that the x86
> code is itself translated into some nonpublic RISC like
> code, who ever knows what is really taking place except the
> microprocessor manufacturer?

True.  Thankfully most performance issues can be fruitfully analyzed
at a much higher level,

> 
> My off-the-top-of-the-head reaction is:
> 
> 1.  Wouldn't it slow things down a lot to pass five values
> to that function (*LI1) instead of two, x and y?
> 

I don't think so.  Consider the case of one value the traditional way:

a) two words copied to stack at call beginning.
b) if proclaimed, no extra arg copying in function
c) result is copied to top of stack at function end
d) top of stack is copied to result stack variable at call end.

As compared to

a) three words copied to stack at call beginning.
b) same as above.
c) if smart, result can be produced in its final location in function,
   otherwise one copy of result to address given in last arg
d) no copy at function call end

So in the smart case, we avoid one copy, else its a wash.  Each
additional value has the same relative overhead, plus the savings of
avoiding the value stack arithmetic on vs_base and vs_top.

> 2.  Wouldn't one have to change, by hand, a gazillion
> hand-coded C functions to follow that discipline?

I don't see why.  Following the evident GCL historical development
model, we don't eliminate the old, we only add the new for suitably
proclaimed functions written by the compiler.

> 
> 3.  How does one efficiently deal with the curious Common
> Lisp semantics that permits any number of values to returned
> by a function (regardless of whether a function has been
> proclaimed to have a fixed number of return values)?
> 

Well, first by taking the very useful step as you have of informing
your clueless GCL maintainer that this is the case!  Thanks!  It is
hard for me to fathom that this is not a mistake in the spec -- what
other possible meaning could be given to the proclamation?

Witness our current behavior with

(proclaim '(ftype (function (t) t) foo))(defun foo (x) (values x
x))(compile 'foo)

values-list at the minimum needs to follow this pattern, but is not
such a policy compliant?  If it is, then we should enforce the
proclamation, otherwise, we have to invent our own proclamation, as is
explicitly permitted by the spec.  This applies as well to our
earlier discussion regarding auto-proclamation.  Redefining the
function must wipe out or redefine the proclamation info with a big
warning when the signature changes.  I don't see how we can go forward
if we permit and maintain a function proclamation at variance with an
actually defined function of the same name.

> 4.  How can one suitably efficiently make sure that NILs get
> passed in the several ways that they need to be passed, by
> default, e.g.,
> 
>   (list (values) (values)) => (NIL NIL)
> 
>   (multiple-value-bind (a b c d e) (+ 2 3) (list a b c d e)) => (5 NIL NIL 
> NIL NIL)
>   

If we have the signature at compile time, we simply set the extra
values to nil.  Otherwise (i.e. the call is compiled before the
proclamation/function definition is made), we need support in
call_or_link (as is currently the case with one arg results), to
simulate the call via the value stack.

> 5.  Let me remind you of the at-least-7 year old remarks by
> Schelter in the file gcl/doc/multiple-values.
> 

Thanks!  Some comments here:

=============================================================================
Proclaimed functions of a fixed number of args are much more
efficient.   It is still possible to pass multiple values
efficiently (but not quite with the CL semantics)

=============================================================================

Agreed!  As to the last point, it would be helpful if one could
identify some section of the spec which explicitly permits functions
to violate their proclaimed signatures.

=============================================================================
;; It is not the same as the common lisp multiple values in general:
;;    1)  The information on how many values are being passed is not
;;        recorded [ unless of course that number is one of the values ! ]
;;    2)  If you ask for more values than were specified you will get
;;        a random value.   Common lisp values would say you get nil.
;; Now it is true that it would be possible to make AKCL pass multiple
;; values more efficiently, but this is really a large overhaul of the
;; system.   There are lots of system functions, hand coded using the
;; old scheme.   I have been thinking about ways to do this for the
;; last little while, but have not settled on anything.
=============================================================================

1) If we can agree that the proclamation is binding, this is not an
   issue.  If necessary, of course, we could pass an additional
   numeric address argument, but then the gains over the existing
   value stack calls might be diminished.

2) I don't see why we cannot enforce nil.

I think Dr. Schelter acknowledges that there are possible improvements
in this area above.  My understanding of the "system functions using
the old scheme" issue refers to the o/* files, which I believe can be
left untouched if we overlay an additional call pattern on top of what
we have now (which already supports several possibilities), the use of
which is suitably restricted to cases in which certain explicit
proclamations are in force.

> 
> Bob
> 
> P. S.  In ANSI Common Lisp, even if a function has been
> proclaimed by the user to return one value, it can legally
> return many, I believe.  I believe that there is no proclaim
> (or declaim or declare or ftype or function or any other)
> method to say in ANSI Common Lisp: we hereby assert, for the
> benefit of the compiler, that function 'foo' always returns
> exactly 3 values.  The ANSI doc says such things about some

Are you sure about this?


> specific functions, of course.  And ACL2 code, by the way,
> follows an enforced discipline that one must say how many
> return values there are going to be for each function and
> stick with it.
> 
> So the following transcript illustrates a big bad bug in GCL
> that I did not know about until just now.  (Allegro, SBCL,
> ABCL, and Clisp all return 5 values at the end, not one.)
> 

Yep, thanks!  What about adding the warning for (values x x) to apply
to values-list too?

Take care,

> Bob
> 
> -------------------------------------------------------------------------------
> 
> % xg
> GCL (GNU Common Lisp)  2.7.0 ANSI    Apr 17 2006 13:38:10
> 
> >(proclaim '(ftype (function (t) t) foo))
> (defun foo (x) (values-list x))
> (compile 'foo)
> (foo '(1 2 3 4 5))
> 
> NIL
> 
> >
> FOO
> 
> >
> ;; Compiling /tmp/gazonk_1111_0.lsp.
> ;; End of Pass 1.  
> ;; End of Pass 2.  
> ;; OPTIMIZE levels: Safety=0 (No runtime error checking), Space=0, Speed=3, 
> (Debug quality ignored)
> ;; Finished compiling /tmp/gazonk_1111_0.o.
> Loading /tmp/gazonk_1111_0.o
> start address -T 0xab47350 Finished loading /tmp/gazonk_1111_0.o
> #<compiled-function FOO>
> NIL
> NIL
> 
> >
> 1
> 
> >
> 
> 
> 

-- 
Camm Maguire                                            address@hidden
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah




reply via email to

[Prev in Thread] Current Thread [Next in Thread]