Hello Luis,
 
Indeed, I am guilty as well of writing a compiler-macro based Lisp-form compiler - as hinted in the pro@c-l.net post :)
It was one of the motivations to add FTYPEs everywhere. Thank you for the interesting pointer.

As stated in the quoted comment, double-float boxing is one of the reasons why we inline CFFI stubs.
It's not like SBCL could chose a different call convention depending on known type declarations.
Once inlined, there will be no difference for FABS-1 and FABS-2 - with or without type of ftype declarations.
Thank you for the excellent example illustrating this classic issue.

The FTYPEs help SBCL produce better code if the double-float function stubs are not inlined (for some reason).
Also, going back to the post you have mentioned, having FTYPEs on CFFI could help compiler-macros
take informed decisions about code transformations. 

E.g. (quickly typed - might not compile)

(declaim (ftype (function (double-float double-float) (values double-float &optional)) pow) (inline pow))
(defcfun pow :double (base :double) (exp :double))

(defun test (&rest nums)
   (sum (bind #'pow 2) nums))

Could expand to:

(defun test (&rest nums)
  (flet ((#:f1 (#:e1)
           (declare (double-float #:e1))
           (pow 2 #:e1)))
    (declare (ftype (function (double-float) (values double-float &optional)) #:f1)
                  (dynamic-extent #'#:f1))
    (let ((#:a1 (first nums)))
      (declare (double-float #:a1))
      (dolist (#:n1 (rest nums) #:a1)
        (setf #:a1 (+ #:a1 (funcall #'#:f1 #:n1)))))))

Which should allow the compiler to choose an unboxed representation for passing arguments to the internal #'#:f1.
BTW: I am sure SBCL would do just fine with just 1/3rd of the declarations above - but unsure which 1/3rd ... this time of year.   
   
Cheers,

On Tue, Nov 7, 2017 at 7:12 PM, Luís Oliveira <luismbo@gmail.com> wrote:
On Mon, Nov 6, 2017 at 5:10 PM, Andrzej Walczak
<andrzejwalczak@google.com> wrote:
> After some thoughts, I agree, that the inlining control is not a fully-baked
> idea, yet.

Incidentally, this recent pro@c-l.net message makes me a whole lot
less skeptical about your suggested approach:
<https://mailman.common-lisp.net/pipermail/pro/2017-November/001464.html>.
The introspect-environment library seems to provide a nice portable
API for inspecting optimization policies. Alas, there doesn't seem to
be away to define your own declarations; I was hoping we might be able
to something like (declaim (inline-cffi-functions <boolean>)) or
something along those lines.


> I'll split the patch into INLINE and FTYPE parts.

Sounds like a good idea.


> You may ask why we have decided to inline (almost) every of the DEFCFUNs?
> CFFI interfaces to C - obviously - and a lot of code in C deals with
> double-floats and 64-bit integers.
> Without the stubs being inline, every call to C and back produces boxed
> values, impacting the performance.

Right. Float boxing; that's a classic. But, I (perhaps naively) didn't
expect boxing to happen even without the declarations. Take the
following example:

(in-package :cffi)

(declaim (optimize (speed 3) (space 0) (safety 0) (debug 0)))

(declaim (inline fabs-1))
(defun fabs-1 (x)
  (foreign-funcall "fabs" :double x :double))

(declaim (inline fabs-2))
(defun fabs-2 (x)
  (declare (double-float x))
  (foreign-funcall "fabs" :double x :double))

(defun foo-1 (x)
  (floatp (fabs-1 x)))

(defun foo-2 (x)
  (floatp (fabs-2 x)))

I expected FABS-1 and FABS-2 to be identical. (FOREIGN-FUNCALL
eventually expands to ALIEN-FUNCALL and I was expecting that would
provide all the type information SBCL's compiler might need.) The
disassembly shows that FAB-2 is one instruction shorter. But
disassembling FOO-1 and FOO-2 shows that they're identical.

Perhaps this example is too contrived. Do you have a better one?

Cheers,

--
Luís Oliveira
http://kerno.org/~luis/



--
Andrzej Walczak 
(Google/ITA Software Engineer)