From: Pedro Kroger
Subject: a few questions about declarations
Date: 
Message-ID: <c1fa07bb-2b5e-4848-aa00-d2518d1b3069@i3g2000hsf.googlegroups.com>
Hi,

I have a couple of questions about declarations. First, I don't
understand why sbcl and cmul print a note with "doing float to pointer
coercion (cost 13) to "<return value>"" in the following function:

(defun test (x)
  (declare (single-float x)
           (optimize (speed 3)))
  (+ x x))

The section 5.13.3 of the CMUCL manual has an example just like the
above, but it does not mention how to deal with it. The note is the
same if I do something like:

(defun test (x)
  (declare (single-float x)
           (optimize (speed 3)))
  (the single-float (+ x x)))

The other thing is the note I get with this function (in sbcl and
cmucl):

(defun test2 (x)
  (declare (single-float x)
           (optimize (speed 3)))
  (round (+ x 3)))


; note: forced to do full call
;       unable to do inline float truncate (cost 5) because:
;       The result is a (VALUES INTEGER &OPTIONAL), not a (VALUES
;                                                          (UNSIGNED-
BYTE 32)
;                                                          &REST T).
;       unable to do inline float truncate (cost 5) because:
;       The result is a (VALUES INTEGER &OPTIONAL), not a (VALUES
;                                                          (SIGNED-
BYTE 32) &REST
;                                                          T).

and I just don't know why. If I do something like:

(defun test2 (x)
  (declare (single-float x)
           (optimize (speed 3)))
  (the (values integer single-float) (round (+ x 3))))

the note is the same. I thought that value returned by round is
_supposed_ to be integer.

I'd appreciate any suggestions.

Best regards,

Pedro Kroger

From: Kaz Kylheku
Subject: Re: a few questions about declarations
Date: 
Message-ID: <e725d13b-4712-4e66-83c4-50636498d685@x29g2000prg.googlegroups.com>
On Dec 22, 3:08 pm, Pedro Kroger <············@gmail.com> wrote:
> Hi,
>
> I have a couple of questions about declarations. First, I don't
> understand why sbcl and cmul print a note with "doing float to pointer
> coercion (cost 13) to "<return value>"" in the following function:
>
> (defun test (x)
>   (declare (single-float x)
>            (optimize (speed 3)))
>   (+ x x))

Could it be that the function works with unboxed floating point
numbers and then has to box up the result again, so that it's
compatible with the rest of the Lisp world?

What happens if you declare the entire function. I.e. add:

 (declaim (ftype (function (single-float single-float) single-float))
test)

before the TEST?
From: Pedro Kroger
Subject: Re: a few questions about declarations
Date: 
Message-ID: <055b38b8-4077-4a25-9e4c-8c1530c088a4@j64g2000hsj.googlegroups.com>
On Dec 22, 5:32 pm, Kaz Kylheku <········@gmail.com> wrote:

> What happens if you declare the entire function. I.e. add:
>
>  (declaim (ftype (function (single-float single-float) single-float))
> test)
>
> before the TEST?

I added

(declaim (ftype (function (single-float) single-float) test))

before test, but the result is the same.

Thanks,

Pedro
From: ········@tochka.ru
Subject: Re: a few questions about declarations
Date: 
Message-ID: <6971a1b1-3d47-4460-864c-5d1dbf12d4c9@f53g2000hsg.googlegroups.com>
Hello,

On Dec 23, 4:32 am, Kaz Kylheku <········@gmail.com> wrote:
> On Dec 22, 3:08 pm, Pedro Kroger <············@gmail.com> wrote:
> > (defun test (x)
> >   (declare (single-float x)
> >            (optimize (speed 3)))
> >   (+ x x))
>
> Could it be that the function works with unboxed floating point
> numbers and then has to box up the result again, so that it's
> compatible with the rest of the Lisp world?

Yes.
>  (declaim (ftype (function (single-float single-float) single-float))
> test)
>
> before the TEST?

It does not help. TEST cannot be sure that every caller knows about
this declaration (consider (SETQ *F* #'TEST) ... (FUNCALL *F*)), so it
should use universal calling/returning protocol.
From: Barry Margolin
Subject: Re: a few questions about declarations
Date: 
Message-ID: <barmar-C3981F.02464423122007@comcast.dca.giganews.com>
In article 
<····································@f53g2000hsg.googlegroups.com>,
 ········@tochka.ru wrote:

> Hello,
> 
> On Dec 23, 4:32 am, Kaz Kylheku <········@gmail.com> wrote:
> > On Dec 22, 3:08 pm, Pedro Kroger <············@gmail.com> wrote:
> > > (defun test (x)
> > >   (declare (single-float x)
> > >            (optimize (speed 3)))
> > >   (+ x x))
> >
> > Could it be that the function works with unboxed floating point
> > numbers and then has to box up the result again, so that it's
> > compatible with the rest of the Lisp world?
> 
> Yes.
> >  (declaim (ftype (function (single-float single-float) single-float))
> > test)
> >
> > before the TEST?
> 
> It does not help. TEST cannot be sure that every caller knows about
> this declaration (consider (SETQ *F* #'TEST) ... (FUNCALL *F*)), so it
> should use universal calling/returning protocol.

Then what's the point of FTYPE declarations?  Any function can be called 
this way, even functions proclaimed INLINE, so it means that return 
values ALWAYS have to be boxed.  In that case, why bother with the 
compiler warning, since there's nothing the user can do about it?

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: David Golden
Subject: Re: a few questions about declarations
Date: 
Message-ID: <g_hbj.23874$j7.445605@news.indigo.ie>
Pedro Kroger wrote:

> 
> Hi,
> 
> I have a couple of questions about declarations. First, I don't
> understand why sbcl and cmul print a note with "doing float to pointer
> coercion (cost 13) to "<return value>"" in the following function:
> 
> (defun test (x)
>   (declare (single-float x)
>            (optimize (speed 3)))
>   (+ x x))
> 

Note first it's often best not to leap straight to declarations...

But anyway, the key there is that it's doing it (switching to a less
efficient descriptor representation) to the <return value>.  

Something similar came up relatively recently, you might want to review
this thread:
http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/ae032d4b5b8ca8d3/031b9f6e19d84017
(started by message <··············@pu100877.student.princeton.edu> 
"Optimization Question" by Tamas Papp)

CMUCL/SBCL doesn't know that the test function will only ever be
returning to "callers that know to expect" an unboxed float (and
doesn't know that test won't have an updated definition in future for
that matter...) so boxes the float for return to a "general" caller.

One option may be to declare the function to be inline (which in
CMUCL/SBCL stops the return boxing if you look at the actual code
generated as per just linked thread)... but has the usual ramifications
of inline declaration, of course.

IF you can say with certainty that the function test will only ever
be called by a known set of other functions, another thing you can
do is use a locally-scoped function (labels/flet) with the other
functions in its scope.  Or compile all those functions in the
same "compilation block" (a CMUCL extension) and only expose external
API functions from the block, which amounts to mostly the same thing.
From: Pedro Kroger
Subject: Re: a few questions about declarations
Date: 
Message-ID: <693fdd8b-5834-44c6-8f36-2fb4a3449953@1g2000hsl.googlegroups.com>
On Dec 22, 4:30 pm, David Golden <············@oceanfree.net> wrote:

> Note first it's often best not to leap straight to declarations...

I agree. however, the actual program we are trying to optimize is much
more complex than these toy examples and it's desperately needing more
optimization. We are doing the normal route of profiling, etc. but it
also presents a good opportunity to learn more about CL
declarations ;-)

> Something similar came up relatively recently, you might want to review
> this thread

thanks, I'll check it out.

> IF you can say with certainty that the function test will only ever
> be called by a known set of other functions, another thing you can
> do is use a locally-scoped function (labels/flet) with the other
> functions in its scope.

You mean like:

(defun foo ()
  (flet ((test1 (x)
           (declare (single-float x)
                    (optimize (speed 3)))
           (+ x x)))
    (test1 3.4)))

yes, it works!

> Or compile all those functions in the
> same "compilation block" (a CMUCL extension) and only expose external
> API functions from the block, which amounts to mostly the same thing.

cool, it also works! I'll post the code here for reference:

(declaim (ext:start-block extract-speech-params))

(defun test1 (x)
  (declare (single-float x)
           (optimize (speed 3)))
  (+ x x))

(test1 3.4)

(declaim (ext:end-block))

to bad sbcl doesn't have block compilation :-( (this is not a rant!)

Thanks a lot,

Pedro Kroger
From: David Golden
Subject: Re: a few questions about declarations
Date: 
Message-ID: <FQkbj.23875$j7.445502@news.indigo.ie>
Pedro Kroger wrote:

> You mean like:
> 
> (defun foo ()
>   (flet ((test1 (x)
>            (declare (single-float x)
>                     (optimize (speed 3)))
>            (+ x x)))
>     (test1 3.4)))
> 
> yes, it works!
> 

Um. More like something a bit like:
(labels ((test (x)
                (declare (single-float x)
                        (optimize (speed 3)))
          (+ x x)))
 (defun test-external (y)
                (declare (single-float y)
                        (optimize (speed 3)))
                (test y)))

It will warn about the boxing, but only at the return from the external
func.

- see also
http://common-lisp.net/project/cmucl/doc/cmu-user/compiler-hint.html#toc177

so it's like test-external is a block entry point.  See above link
for further explanation of labels<->block-compilation similarity.


> to bad sbcl doesn't have block compilation :-( (this is not a rant!)

shrug, as you can see from the above link, CMUCL+SBCL's treatment of
labels forms gets very close anyway.