SBCL gurus,
I'm trying to optimize some calls and fighting a bit with SBCL on some
type declarations. In particular, it looks like INLINE and FTYPE
declarations don't want to mix very well. I have a couple of functions
at the bottom of my call graph:
(defun get-byte (buffer size index)
"Get a byte from the foreign object array at the specified index."
(declare (optimize (speed 3) (safety 0) (space 0))
(byte-ptr buffer)
(fixnum size)
(fixnum index))
(assert (and (<= 0 index) (< index size)))
(uffi:deref-array buffer :unsigned-byte index))
(defun get16 (buffer size index)
"Get a 16-bit quantity from the foreign object array, starting at
the specified index, in big-endian byte order."
(declare (optimize (speed 3) (safety 0) (space 0))
(byte-ptr buffer)
(fixnum size)
(fixnum index)
(inline get-byte)
(ftype (function (byte-ptr fixnum fixnum) fixnum) get-byte))
(logior (the fixnum (ash (get-byte buffer size index) 8))
(get-byte buffer size (1+ index))))
I want GET16 to inline GET-BYTE. At first, I had originally added the
FTYPE declaration in GET16 without the INLINE, to make the LOGIOR and
ASH forms more efficient. By declaring GET-BYTE to return a fixnum, SBCL
seems to eliminate generic calls and produce x86 or and shift
instructions. Now, when I add the INLINE declaration, it seems like SBCL
takes no notice of the FTYPE anymore and complains:
; in: LAMBDA NIL
; (ASH (GET-BYTE BUFFER SIZE INDEX) 8)
;
; note: forced to do full call
; unable to do inline ASH (cost 2) because:
; The first argument is a INTEGER, not a FIXNUM.
; unable to do inline ASH (cost 3) because:
; The first argument is a INTEGER, not a (UNSIGNED-BYTE 32).
; The result is a (VALUES FIXNUM
; &OPTIONAL), not a (VALUES (UNSIGNED-BYTE
32)
; &REST
; T).
; etc.
; (LOGIOR (THE FIXNUM (ASH (GET-BYTE BUFFER SIZE INDEX) 8))
; (GET-BYTE BUFFER SIZE (1+ INDEX)))
;
; note: forced to do static-fun Two-arg-ior (cost 53)
; unable to do inline fixnum arithmetic (cost 2) because:
; The second argument is a INTEGER, not a FIXNUM.
; The result is a (VALUES INTEGER &OPTIONAL), not a (VALUES FIXNUM
&REST T).
; unable to do inline (signed-byte 32) arithmetic (cost 3) because:
; The second argument is a INTEGER, not a (SIGNED-BYTE 32).
; The result is a (VALUES INTEGER
; &OPTIONAL), not a (VALUES (SIGNED-BYTE 32)
; &REST
; T).
; etc.
; (GET-BYTE BUFFER SIZE (1+ INDEX))
;
; note: doing signed word to integer coercion (cost 20)
Now, I could insert (the fixnum ...) everywhere in the code. But
shouldn't this work as I have written it, with both the INLINE and FTYPE
declarations in force at the same time, or am I doing something wrong
here?
Thanks,
-- Dave
--
Dave Roberts <ldave@...>
|