Re: Primitive function boxes and unboxes result value

2012-11-21 Thread Gunnar Völkel
Of course. You are right. I did forget about the long constant.
I hope your patch will be included in Clojure 1.5.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Primitive function boxes and unboxes result value

2012-11-21 Thread Christophe Grand
Hi Gunnar,

The only thing I fixed is related to recur (whose type was null and thus
not unifiable with a primitive type).

Concerning your fib2, I think the proble comes from the "then" being a long
(1) and the else a double.
Thus boxing is required to return either a long or double (well a Long and
a Double).
I think if you change fib2 to always return double you'll see the boxing
ops go away:

(defn fib2 ^double [^double n]
  (if (<= n 1) 1.0 (+ (fib2 (dec n)) (fib2 (- n 2)

Concerning multiply-and-square, since my patch deals with correctly typing
recur in a primitive context, it is solved:

   35:  dstore_1
   36:  goto0
   39:  goto44
   42:  pop
   43:  dload_1
   44:  dreturn

Christophe

On Wed, Nov 21, 2012 at 1:34 PM, Gunnar Völkel <
gunnar.voel...@googlemail.com> wrote:

> (defn fib ^long [^long n]
>   (if (<= n 1) 1 (+ (fib (dec n)) (fib (- n 2)
>



-- 
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.cgrand.net/ (en)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Primitive function boxes and unboxes result value

2012-11-21 Thread Gunnar Völkel
I think Cristophe is on the right path. But it is possible that there is 
another Bug concerning primitive functions.
Consider the following two functions:

(defn fib ^long [^long n]
  (if (<= n 1) 1 (+ (fib (dec n)) (fib (- n 2)

(defn fib2 ^double [^double n]
  (if (<= n 1) 1 (+ (fib2 (dec n)) (fib2 (- n 2)

The bytecode of `fib` ends as expected with
42 invokestatic 81;   /* long clojure.lang.Numbers.minus(long arg0, 
long arg1) */
45 invokeinterface 77 3;  /* long invokePrim(long arg0) */
50 invokestatic 84;   /* long clojure.lang.Numbers.add(long arg0, long 
arg1) */
53 lreturn;

But `fib2` boxes and unboxes again:
45 invokestatic 83;   /* double clojure.lang.Numbers.minus(double arg0, 
long arg1) */
48 invokeinterface 79 3;  /* double invokePrim(double arg0) */
53 invokestatic 87;   /* double clojure.lang.Numbers.add(double arg0, 
double arg1) */
56 invokestatic 92;   /* java.lang.Double 
java.lang.Double.valueOf(double arg0) */
59 checkcast 94;  /* java.lang.Number */
62 invokevirtual 98;  /* double doubleValue() */
65 dreturn;

I also rewrote the multiply-and-square algorithm so that it does not use 
`loop`:
(defn multiply-and-square
  ^double [^double result, ^double factor, ^long c]
  (if (> c 0)
(recur 
   (if (first-bit? c)
 (* result factor)
 result),
   (* factor factor),
   (bit-shift-right c 1))
result))

(defn exp-int2
  ^double [^double x, ^long c]
  (multiply-and-square 1.0, x, c))

Here the bytecode of `exp-int2` looks fine, but the recursive function 
`multiply-and-square` performs the boxing and unboxing again:
43 dload_1;   /* result */
44 invokestatic 70;   /* java.lang.Double 
java.lang.Double.valueOf(double factor) */
47 checkcast 72;  /* java.lang.Number */
50 invokevirtual 76;  /* double doubleValue() */
53 dreturn;

Christophe, can you try `fib2` with your patched Clojure?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Primitive function boxes and unboxes result value

2012-11-21 Thread Christophe Grand
I created an issue and attached a patch
http://dev.clojure.org/jira/browse/CLJ-

Now the 5 last lines of bytecode are:
   52:  goto9
   55:  goto61
   58:  pop
   59:  dload   5
   61:  dreturn

Christophe


On Tue, Nov 20, 2012 at 10:27 PM, Christophe Grand wrote:

> I think CLJ-701 is about loop in non-terminal position.
>
>
> On Tue, Nov 20, 2012 at 6:30 PM, Andy Fingerhut 
> wrote:
>
>> Any relationship to CLJ-701, other than similar symptoms?
>>
>> http://dev.clojure.org/jira/browse/CLJ-701
>>
>> Andy
>>
>> On Nov 20, 2012, at 9:15 AM, Christophe Grand wrote:
>>
>> Hi,
>>
>> It looks like, because of the recur, the compiler fails to notice that if
>> returns a primitive.
>> As far as I understand in Compiler.java, RecurExpr does not implement
>> MaybePrimitiveExpr and thus causes on canEmitPrimitive the surrounding
>> IfExpr to return false.
>>
>> Someone to confirm this analysis?
>>
>>
>> On Tue, Nov 20, 2012 at 4:34 PM, Gunnar Völkel <
>> gunnar.voel...@googlemail.com> wrote:
>>
>>> I have written a primitive function for exponentiation with integers as
>>> power using the multiply-and-square algorithm.
>>> For performance reasons I used primitive type hints for the arguments
>>> and the return value.
>>> Profiling the whole application I noticed that there are a lot of
>>> java.lang.Double/valueOf calls.
>>> Looking at the bytecode I see that in Clojure 1.3 as well as in Clojure
>>> 1.4 the result value gets boxed and unboxed like
>>> Double.valueOf(result).doubleValue().
>>>
>>> Am I doing something wrong? Is there a serious bug related to the
>>> support of primitive functions?
>>>
>>> The source code:
>>>
>>> (defn first-bit?
>>>   {:inline (fn [n] `(== 1 (clojure.lang.Numbers/and ~n, 1)) )}
>>>   [^long n]
>>>   (== 1 (clojure.lang.Numbers/and n, 1)))
>>>
>>> (defn exp-int
>>>   ^double [^double x, ^long c]
>>>   (loop [result 1.0, factor x, c c]
>>> (if (> c 0)
>>> (recur
>>>  (if (first-bit? c)
>>>(* result factor)
>>>result),
>>>  (* factor factor),
>>>  (bit-shift-right c 1))
>>>   result)))
>>>
>>> Last lines of the Java bytecode of `exp-int`:
>>> 59 dload 5;   /* result */
>>> 61 invokestatic 40;   /* java.lang.Double
>>> java.lang.Double.valueOf(double c) */
>>> 64 checkcast 85;  /* java.lang.Number */
>>> 67 invokevirtual 89;  /* double doubleValue() */
>>> 70 dreturn;
>>>
>>
>>  --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>>
>
>
>
> --
> Professional: http://cgrand.net/ (fr)
> On Clojure: http://clj-me.cgrand.net/ (en)
>



-- 
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.cgrand.net/ (en)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Primitive function boxes and unboxes result value

2012-11-20 Thread Christophe Grand
I think CLJ-701 is about loop in non-terminal position.


On Tue, Nov 20, 2012 at 6:30 PM, Andy Fingerhut wrote:

> Any relationship to CLJ-701, other than similar symptoms?
>
> http://dev.clojure.org/jira/browse/CLJ-701
>
> Andy
>
> On Nov 20, 2012, at 9:15 AM, Christophe Grand wrote:
>
> Hi,
>
> It looks like, because of the recur, the compiler fails to notice that if
> returns a primitive.
> As far as I understand in Compiler.java, RecurExpr does not implement
> MaybePrimitiveExpr and thus causes on canEmitPrimitive the surrounding
> IfExpr to return false.
>
> Someone to confirm this analysis?
>
>
> On Tue, Nov 20, 2012 at 4:34 PM, Gunnar Völkel <
> gunnar.voel...@googlemail.com> wrote:
>
>> I have written a primitive function for exponentiation with integers as
>> power using the multiply-and-square algorithm.
>> For performance reasons I used primitive type hints for the arguments and
>> the return value.
>> Profiling the whole application I noticed that there are a lot of
>> java.lang.Double/valueOf calls.
>> Looking at the bytecode I see that in Clojure 1.3 as well as in Clojure
>> 1.4 the result value gets boxed and unboxed like
>> Double.valueOf(result).doubleValue().
>>
>> Am I doing something wrong? Is there a serious bug related to the support
>> of primitive functions?
>>
>> The source code:
>>
>> (defn first-bit?
>>   {:inline (fn [n] `(== 1 (clojure.lang.Numbers/and ~n, 1)) )}
>>   [^long n]
>>   (== 1 (clojure.lang.Numbers/and n, 1)))
>>
>> (defn exp-int
>>   ^double [^double x, ^long c]
>>   (loop [result 1.0, factor x, c c]
>> (if (> c 0)
>> (recur
>>  (if (first-bit? c)
>>(* result factor)
>>result),
>>  (* factor factor),
>>  (bit-shift-right c 1))
>>   result)))
>>
>> Last lines of the Java bytecode of `exp-int`:
>> 59 dload 5;   /* result */
>> 61 invokestatic 40;   /* java.lang.Double
>> java.lang.Double.valueOf(double c) */
>> 64 checkcast 85;  /* java.lang.Number */
>> 67 invokevirtual 89;  /* double doubleValue() */
>> 70 dreturn;
>>
>
>  --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>



-- 
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.cgrand.net/ (en)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Primitive function boxes and unboxes result value

2012-11-20 Thread Andy Fingerhut
Any relationship to CLJ-701, other than similar symptoms?

http://dev.clojure.org/jira/browse/CLJ-701

Andy

On Nov 20, 2012, at 9:15 AM, Christophe Grand wrote:

> Hi,
> 
> It looks like, because of the recur, the compiler fails to notice that if 
> returns a primitive.
> As far as I understand in Compiler.java, RecurExpr does not implement 
> MaybePrimitiveExpr and thus causes on canEmitPrimitive the surrounding IfExpr 
> to return false.
> 
> Someone to confirm this analysis?
> 
> 
> On Tue, Nov 20, 2012 at 4:34 PM, Gunnar Völkel 
>  wrote:
> I have written a primitive function for exponentiation with integers as power 
> using the multiply-and-square algorithm.
> For performance reasons I used primitive type hints for the arguments and the 
> return value.
> Profiling the whole application I noticed that there are a lot of 
> java.lang.Double/valueOf calls.
> Looking at the bytecode I see that in Clojure 1.3 as well as in Clojure 1.4 
> the result value gets boxed and unboxed like 
> Double.valueOf(result).doubleValue().
> 
> Am I doing something wrong? Is there a serious bug related to the support of 
> primitive functions?
> 
> The source code:
> 
> (defn first-bit?
>   {:inline (fn [n] `(== 1 (clojure.lang.Numbers/and ~n, 1)) )}
>   [^long n]
>   (== 1 (clojure.lang.Numbers/and n, 1)))
> 
> (defn exp-int
>   ^double [^double x, ^long c]
>   (loop [result 1.0, factor x, c c]
> (if (> c 0)
> (recur 
>  (if (first-bit? c)
>(* result factor)
>result),
>  (* factor factor),
>  (bit-shift-right c 1))
>   result)))
> 
> Last lines of the Java bytecode of `exp-int`:
> 59 dload 5;   /* result */
> 61 invokestatic 40;   /* java.lang.Double java.lang.Double.valueOf(double 
> c) */
> 64 checkcast 85;  /* java.lang.Number */
> 67 invokevirtual 89;  /* double doubleValue() */
> 70 dreturn;

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Primitive function boxes and unboxes result value

2012-11-20 Thread Christophe Grand
Hi,

It looks like, because of the recur, the compiler fails to notice that if
returns a primitive.
As far as I understand in Compiler.java, RecurExpr does not implement
MaybePrimitiveExpr and thus causes on canEmitPrimitive the surrounding
IfExpr to return false.

Someone to confirm this analysis?


On Tue, Nov 20, 2012 at 4:34 PM, Gunnar Völkel <
gunnar.voel...@googlemail.com> wrote:

> I have written a primitive function for exponentiation with integers as
> power using the multiply-and-square algorithm.
> For performance reasons I used primitive type hints for the arguments and
> the return value.
> Profiling the whole application I noticed that there are a lot of
> java.lang.Double/valueOf calls.
> Looking at the bytecode I see that in Clojure 1.3 as well as in Clojure
> 1.4 the result value gets boxed and unboxed like
> Double.valueOf(result).doubleValue().
>
> Am I doing something wrong? Is there a serious bug related to the support
> of primitive functions?
>
> The source code:
>
> (defn first-bit?
>   {:inline (fn [n] `(== 1 (clojure.lang.Numbers/and ~n, 1)) )}
>   [^long n]
>   (== 1 (clojure.lang.Numbers/and n, 1)))
>
> (defn exp-int
>   ^double [^double x, ^long c]
>   (loop [result 1.0, factor x, c c]
> (if (> c 0)
> (recur
>  (if (first-bit? c)
>(* result factor)
>result),
>  (* factor factor),
>  (bit-shift-right c 1))
>   result)))
>
> Last lines of the Java bytecode of `exp-int`:
> 59 dload 5;   /* result */
> 61 invokestatic 40;   /* java.lang.Double
> java.lang.Double.valueOf(double c) */
> 64 checkcast 85;  /* java.lang.Number */
> 67 invokevirtual 89;  /* double doubleValue() */
> 70 dreturn;
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en




-- 
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.cgrand.net/ (en)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Primitive function boxes and unboxes result value

2012-11-20 Thread Gunnar Völkel
I can add some additional information. I compiled the fibonacci example 
with double and long type hints:

(defn fib ^long [^long n]
  (if (<= n 1) 1 (+ (fib (dec n)) (fib (- n 2)

(defn fib ^double [^double n]
  (if (<= n 1) 1 (+ (fib (dec n)) (fib (- n 2)

The one with ^long works as expected but the one with ^double has the 
Double.valueOf(result).
doubleValue() bytecode before the return.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en