Nicolas Neuss <[EMAIL PROTECTED]> writes:

> again a question in the direction of getting most of speed out of
> CMUCL.  From Pierre I've learned about defknown/deftransform, and I
> guess that I could be able to use it for my application.
> Unfortunately, it seems that I do not yet understand it sufficiently
> well.

Sorry for not responding earlier, but I got distracted with other
things...

> An example:
>
> (defstruct test-4 (alpha 0.0d0 :type double-float))
> (defmethod foo ((obj test-4)) (test-4-alpha obj))
> (defmethod foo (x) nil)
>
> (c:defknown foo (t) t (c:foldable c:movable c:flushable))
> (c:deftransform foo ((obj) (test-4) double-float :when :both)
>   '(test-4-alpha obj))

The reason this deftransform isn't triggered is because of the
double-float return-type specification.  This requires that the
compiler prove that double-float is the expected result-type at the
call site, before the transform is triggered.  Since the
transformation you want to perform is legal regardless of the
expected result-type, you can just remove this requirement, and the
transformation will be triggered as expected, e.g. with

(c:deftransform foo ((obj) (test-4) * :when :both)
  '(test-4-alpha obj))

we get:

* (time
 (let ((obj (make-test-4 :alpha 1.0d0)))
   (declare (optimize (speed 3) (space 0) (debug 0) (safety 0)))
   (declare (type test-4 obj))
   (loop for i fixnum below 1000000
         summing
         (test-4-alpha obj)
         double-float)))
Compiling LAMBDA NIL: 
Compiling Top-Level Form: 

Evaluation took:
  0.03 seconds of real time
  0.02 seconds of user run time
  0.0 seconds of system run time
  0 page faults and
1000000.0d0
* (time
 (let ((obj (make-test-4 :alpha 1.0d0)))
   (declare (optimize (speed 3) (space 0) (debug 0) (safety 0)))
   (declare (type test-4 obj))
   (loop for i fixnum below 1000000
         summing
         (foo obj)
         double-float)))
Compiling LAMBDA NIL: 
Compiling Top-Level Form: 

Evaluation took:
  0.02 seconds of real time
  0.02 seconds of user run time
  0.0 seconds of system run time
  0 page faults and
  0 bytes consed.
1000000.0d0

In case you included the double-float in the hope of _informing_ the
compiler of the result type, this is not necessary in this case, since
the compiler will be able to derive the result-type of the foo form
automatically based on the lambda resulting from the deftransform, and
the information it has on test-4-alpha.

In cases where this isn't possible, you'd have to write a derive-type
optimizer to inform the compiler of the result-type...

Regs, Pierre.


Reply via email to