From: Shiv

Subject: Battling the ACL compiler

Date: 1999-3-8 19:06


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.