From: dremon on
When compiling the following code I am getting compiler warnings:

note: unable to optimize due to type uncertainty: The first argument
is a SEQUENCE, not a (SIMPLE-ARRAY * (*)).
note: unable to optimize due to type uncertainty: The first argument
is a SEQUENCE, not a LIST.

(defclass mtest()
((data :accessor data
:type (simple-array float (*))
:initform (make-array 10
:element-type 'float
:initial-element 0.0
:adjustable nil
:fill-pointer nil
:displaced-to nil))))

(defmethod value((obj mtest) (i fixnum) (j fixnum))
(declare (optimize (speed 3) (safety 0)))
(elt (data obj) (+ i j)))

What is wrong with this code? Seems like all the types are known but
still it it doesn't optimize.
From: D Herring on
dremon wrote:
> When compiling the following code I am getting compiler warnings:
>
> note: unable to optimize due to type uncertainty: The first argument
> is a SEQUENCE, not a (SIMPLE-ARRAY * (*)).
> note: unable to optimize due to type uncertainty: The first argument
> is a SEQUENCE, not a LIST.
>
> (defclass mtest()
> ((data :accessor data
> :type (simple-array float (*))
> :initform (make-array 10
> :element-type 'float
> :initial-element 0.0
> :adjustable nil
> :fill-pointer nil
> :displaced-to nil))))
>
> (defmethod value((obj mtest) (i fixnum) (j fixnum))
> (declare (optimize (speed 3) (safety 0)))
> (elt (data obj) (+ i j)))
>
> What is wrong with this code? Seems like all the types are known but
> still it it doesn't optimize.

It looks like SBCL wants to replace ELT with SVREF or NTH; but your
type is not a simple-vector (close) nor a list. Changing the :type to
(SIMPLE-ARRAY * (*)) or the ELT to AREF should resolve this warning.

- Daniel
From: dremon on
Well I tried replacing elt with aref, does help much although the
warnings are different this time:
The first argument is a VECTOR, not a SIMPLE-STRING
The first argument is a VECTOR, not a SIMPLE-ARRAY.

The type-of over that expression gives "(simple-vector 10)".

(simple-array * (*)) doesn't change anything.
From: Christophe Rhodes on
dremon <dmitry.pankratov(a)gmail.com> writes:

> (defclass mtest()
> ((data :accessor data
> :type (simple-array float (*))
> :initform (make-array 10 [...]))))
>
> (defmethod value((obj mtest) (i fixnum) (j fixnum))
> (declare (optimize (speed 3) (safety 0)))
> (elt (data obj) (+ i j)))
>
> What is wrong with this code? Seems like all the types are known but
> still it it doesn't optimize.

All types are not known. At any point, and between any calls to VALUE,
it would be legal to add methods to the DATA generic function, such as
an :AROUND method specialized to MTEST, which can return any object of
any type at all; it would legal to redefine the MTEST class to remove
the type declaration for the slot; it would legal to redefine the MTEST
class to remove the DATA slot and accessor entirely, such that the next
access to any MTEST instance would drop the contents of its DATA slot.
In all these circumstances, the VALUE method must continue to function
in accordance with the standard CLOS behaviour.

There are ways of getting the compiler to make the kinds of assumptions
that you want in CLOS code; most of them involve going into
implementation-specific territory.

Christophe
From: Tamas K Papp on
On Sat, 16 Jan 2010 12:05:24 -0800, dremon wrote:

> When compiling the following code I am getting compiler warnings:
>
> note: unable to optimize due to type uncertainty: The first argument is
> a SEQUENCE, not a (SIMPLE-ARRAY * (*)). note: unable to optimize due to
> type uncertainty: The first argument is a SEQUENCE, not a LIST.
>
> (defclass mtest()
> ((data :accessor data
> :type (simple-array float (*))
> :initform (make-array 10
> :element-type
'float
> :initial-
element 0.0
> :adjustable nil
> :fill-pointer
nil
> :displaced-to
nil))))
>
> (defmethod value((obj mtest) (i fixnum) (j fixnum))
> (declare (optimize (speed 3) (safety 0))) (elt (data obj) (+ i j)))
>
> What is wrong with this code? Seems like all the types are known but
> still it it doesn't optimize.

AFAIK SBCL won't infer types from defclass's :type declarations.
Think of the latter as documentation for yourself, not a hint to the
compiler.

Just use something like

(defclass mtest()
((data :accessor data
:type (simple-array float (*))
:initform (make-array 10 :element-type 'float
:initial-element 0.0))))
;;; note how you don't need to supply the defaults to make-array

(defmethod value((obj mtest) (i fixnum) (j fixnum))
(declare (optimize (speed 3) (safety 0)))
(aref (the (simple-array float (*)) (data obj)) (+ i j)))

HTH,

Tamas