I am having trouble getting the compiler not to box a single-float.
The compiler of both ACL 4.3.1 and 5.0 (Solaris) give the same
'problem'.
I have condensed the situation into this simple function:
USER(26): (defun foo (a)
(let ((C (make-array 2 :element-type 'single-float
:initial-element 2.0)))
(declare (optimize (speed 3) (safety 0) (debug 0))
(single-float a)
(type (simple-array single-float (*)) C)
(:explain :boxing :types :calls))
(incf (aref C 0) (* (the short-float a) 2.0))
C))
FOO
Here is what I get when I compile it:
USER(27): (compile *)
;Examining a (possibly unboxed) call to +_2OP with arguments:
; call to AREF type (SINGLE-FLOAT * *)
; call to *_2OP type (SINGLE-FLOAT * *)
; which returns a value of type (SINGLE-FLOAT * *)
;Examining a (possibly unboxed) call to AREF with arguments:
; symeval G2772 type (SIMPLE-ARRAY (SINGLE-FLOAT * *) (*))
; constant 0 type (INTEGER 0 0)
; which returns a value of type (SINGLE-FLOAT * *)
;Examining a (possibly unboxed) call to *_2OP with arguments:
; symeval A type (SINGLE-FLOAT * *)
; constant 2.0 type (SINGLE-FLOAT 2.0 2.0)
; which returns a value of type (SINGLE-FLOAT * *)
;Generating a SINGLE-FLOAT box <----- !!!!! shiv !!!!!!!!!!! <--------
;Examining a (possibly unboxed) call to .INV-S-AREF with arguments:
; symeval G2773 type (SINGLE-FLOAT * *)
; symeval G2772 type (SIMPLE-ARRAY (SINGLE-FLOAT * *) (*))
; constant 0 type (INTEGER 0 0)
; which returns a value of type (SINGLE-FLOAT * *)
;Examining a call to .INV-S-AREF with arguments:
; symeval G2773 type (SINGLE-FLOAT * *)
; symeval G2772 type (SIMPLE-ARRAY (SINGLE-FLOAT * *) (*))
; constant 0 type (INTEGER 0 0)
; which returns a value of type (SINGLE-FLOAT * *)
FOO
NIL
NIL
I have marked the line (with shiv) where it warns that it is
generating a boxed single-float. As can be seen the declarations are
enough for the compiler to identify all intermediate quantities as
single-float. I guess the problem is that the compiler is not
intelligent enough to see that the + operation in incf generates
output that although ultimately ends up in the output of the function,
can still be unboxed since it is inside a simple-array which contains
unboxed single-floats (phew!). I have tried writing to a temporary
variable first before writing to the output array but with no luck.
Any advice on how to work around this will be appreciated.
Thanks,
--shiv--
Sanity check: this operation (not foo) occurs deep inside a nested
loop in my code.