[Top][All Lists]

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

[Gcl-devel] Re: Random noise on values

From: Camm Maguire
Subject: [Gcl-devel] Re: Random noise on values
Date: 13 Jul 2006 13:02:44 -0400
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2


Robert Boyer <address@hidden> writes:

> > might there be some other construct which could be used to
> > regain the exact arity
> Dunno, but here are some more unjustified opinions.
> A. I think you should reflect on the syntax in
> cmpnew/gcl_cmpopt.lsp.  There, one deals with type
> expression that are conditional: if the inputs are of such
> and such a type, then the outputs are of such and such a
> type.  This is very important for efficiency.

Agreed!  We've expanded on this significantly by the type propagator
functions you can find in gcl_cmptype.lsp, and the inline-types
fuctions (mostly for aref and aset)you can find in gcl_cmpinline.lsp.
The idea being that functions give more flexibility and a finer degree
of control than a preset list of discrete possibilities.

> B. I hope you utterly stop using the symbol 'values' because
> I think it does not make real and practical sense yet to me.

Probably a good idea, but thus far, 'values means 'returns-at-most.
We do distinguish this from returns-exactly as you so helpfully
suggested -- thanks!  Its just a simple text editor replacement to do
as you suggest, however.

> C. For internal GCL compiler purposes only, simply not
> visible to the ordinary user, the compiler should use a
> language for talking about the outputs of a function that
> permits only three basic options (depending of course upon
> conditions on the types of inputs, as suggested above).
> (1) the stupid case of 'I know nothing'
> *                      ; meaning any number of values of any type possible,
>                        ; including the possibility of no values at all.
>                        ; callee will have to set some indicator of
>                        ; number of values returned (and maybe even where
>                        ; they are returned and what their types are).
>                        ; calls to functions of this output type
>                        ; must read the indicator of # of values returned.
>                        ; calls to such functions are slow!  The user will
>                        ; learn not to use such functions except in very
>                        ; special cases, such as when the user must resort
>                        ; to calling 'eval'

Right now, '* means the callee writes to the traditional value stack,
and sets vs_base and vs_top.  The caller retrieves the values from

> (2) the 'vanilla' case of exactly one value always returned
> bar         ; meaning that one value of type bar is returned, where type bar
>             ; is built up out of 'and', 'or', 'not'
>             ; and atomic types like t and fixnum, and vector
>             ; (but no use of 'values' is permitted).
>             ; Any caller of a function with such an output type
>             ; knows this will be an ordinary c function call
>             ; returning one thing in the ordinary way a c function does

This is typically returned in a register when fast linking is on.  For
correctness with Paul's random compiler tester, we may have a few
excessive resets of vs_top for safety still.  Most functions set base
to be their vs_top on entry, sup which exceeds base by a computed
amount needed by the function, and then vs_top to sup.  Calls to '*
functions push values up from here.  On exit, vs_top is reset to
base.  When the caller is done extracting values, it sets vs_top back
to sup for the next call to avoid value stack leaks -- sometimes we do
this even in this case, where we should know that the callee has left
vs_top alone.  This might take a little thought :-)

> (3) the 'chocolate' case of exactly 4 values always returned 
>     (obviously for any specific number 4)
> (si::returns-exactly fixnum t t foo) 
>                        ; meaning that exactly and always,
>                        ; 4 outputs are returned, the first
>                        ; a fixnum, the second and third unknown,
>                        ; and the last of type foo (defined with
>                        ; 'and', or, 'not', and atomic types but no
>                        ; use of 'values').
> When some function foo is being compiled and foo's code
> calls a function bar, if the compiler knows that bar is of
> type 2 or 3 above, then it can lay down an ordinary c
> function call that 'knows' where and how many values are
> returned and does not need to ask or be told anything about
> the number of values returned.  However, if, when compiling
> foo, the compiler does not (yet) know that the output type
> of bar fits into exactly one of class 2 or and 3 above, the
> compiler lays down a more general call of bar that at
> runtime will pay the price for an unknown return number; the
> compiler leaves a note to recompile foo if and when it
> learns that bar is of type 2 or 3.  And the compiler notes
> that whenever bar is redefined by anyone, the compiler must
> consider recompiling foo, especially if bar used to have
> output type 2 or 3 and that changes.

OK so we have both returns-exactly, and values at present.

In the former case, the callee writes to the provided area if not
null, and sets vs_top only to the end of the space.  The caller does
nothing but reset vs_top and proceed, as the values are already in
place.  We have the callee setting vs_top at present to prevent error
in the case where it is redefined and the caller is not recompiled --
the fast link is not reestablished here with a warning printed to the
screen, and only the number allowed by the caller are written into
place.  We could actually achieve the same effect by using a element
in the sfn and vfn structures that now hold the number of values
returned -- this will probably accelerate things somewhat.  You can
see the warning if you like by setting *disable-recompile* to t,
compiling foo with (values 1 2), bar with a mvbind, then foo again
with (values 1 2 3), then trying to run bar.

In the values case (as opposed to returns-exactly), the callee is as
before, but the caller reads vs_top to set any unset variables to
nil.  Actually, in the returns-exactly case, the same is done when
binding more variables that the callee returns.  This could be sped up
a bit too.

Take care,

> Some example output type expressions for some primititives:
>    apropos       *
>    eval          *
>    cons          t
>    intern        (si::returns-exactly symbol boolean)
>    gethash       (si::returns-exactly t boolean)
>    read          t
>    eq            boolean
>    nconc         t
> Obviously all special operators have to been handled
> specially because they are 'special', e.g.,
>    quote         --  type of the object quoted
>    progn         --  the return type of the last element, or 'symbol' if
>                      no elements
>    catch         --  *very* hard to tell.
>                      depends upon whether you can analyze all
>                      possible throws to the tag.  probably *.
>    values        --  (returns-exactly ... first output type for each arg)
>                      or * if there are none
>    if            --  'union' of the output values of the then-form
>                       and the else-form, which is * unless both have
>                       the exact same number of outputs, and otherwise
>                       one forms the pointwise 'or' of those outputs
> Bob

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]