Implict Casts in Truffle DSL

Christian Humer christian.humer at gmail.com
Wed Apr 2 15:50:11 UTC 2014


Ups that was too quick. Forget my previous patch and use the one below
instead. In principle the DSL supports execute methods without a
VirtualFrame parameter. However there are some glitches here and there. So
please try to avoid them for now and always add a VirtualFrame parameter to
execute methods.

diff -r ed373ed4b717
graal/edu.uci.python.nodes/src/edu/uci/python/nodes/expression/CastToBooleanNode.java
---
a/graal/edu.uci.python.nodes/src/edu/uci/python/nodes/expression/CastToBooleanNode.java
Wed
Apr 02 00:06:40 2014 -0700
+++
b/graal/edu.uci.python.nodes/src/edu/uci/python/nodes/expression/CastToBooleanNode.java
Wed
Apr 02 17:47:21 2014 +0200
@@ -40,7 +40,7 @@

 public abstract class CastToBooleanNode extends UnaryOpNode {

-    public abstract boolean executeBoolean(Object value);
+    public abstract boolean executeBoolean(VirtualFrame frame, Object
value);

     @Override
     public abstract boolean executeBoolean(VirtualFrame frame);






- Christian Humer


On Wed, Apr 2, 2014 at 4:43 PM, Christian Humer
<christian.humer at gmail.com>wrote:

> Hi Wei,
>
> You found a bug. Thanks for the report. In the future don't hesitate to
> send a report even if you are not sure if it is already fixed. Here is a
> temporary patch for you. I will push this fix with my next greater push to
> openjdk.
>
> BTW.: you should get rid of your overly complicated @TypeCheck and
> @TypeCast implementations in the type system. There may be a major
> performance problem hidden here. Ideally you should only use the ones that
> are generated by default. I think you can get rid of them mostly by using
> ImplicitCasts. But maybe that's the thing you wanted to do anyway. Feel
> free to contact me again if you need help with that.
>
> diff -r ed373ed4b717
> graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java
> ---
> a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Wed
> Apr 02 00:06:40 2014 -0700
> +++
> b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Wed
> Apr 02 16:34:32 2014 +0200
> @@ -2032,7 +2032,11 @@
>
>              CodeExecutableElement method = new
> CodeExecutableElement(modifiers(PROTECTED, expectType != null ? STATIC :
> FINAL), param.getType(), childExecuteName);
>
>  method.getThrownTypes().add(getContext().getTruffleTypes().getUnexpectedValueException());
> -            method.addParameter(new
> CodeVariableElement(getContext().getTruffleTypes().getFrame(),
> "frameValue"));
> +
> +            if (expectType == null) {
> +                method.addParameter(new
> CodeVariableElement(getContext().getTruffleTypes().getFrame(),
> "frameValue"));
> +            }
> +
>              if (expectType != null) {
>                  method.addParameter(new
> CodeVariableElement(expectType.getPrimitiveType(),
> valueNameEvaluated(param)));
>              }
>
>
> - Christian Humer
>
>
> On Tue, Apr 1, 2014 at 10:10 PM, Wei Zhang <ndrzmansn at gmail.com> wrote:
>
>> Hi Christian,
>>
>> I'm experiencing a problem when using @ImplicitCast.
>>
>> I added the following code in PythonTypes.java:
>>
>> @ImplicitCast
>> public String unboxPString(PString value) {
>>       return value.getValue();
>> }
>>
>> This use causes a javac error in the generated
>> CastToBooleanNodeFactory.java.
>>
>> You can pull the latest change from ZipPy to reproduce this.
>> I've commented the use of @ImplicitCast in PythonTypes.
>> I did not report this problem earlier because I have not merge with the
>> Graal repo for a while and expected that it might be fixed in a recent
>> commit.
>>
>> Any suggestion?
>> Thanks,
>>
>> /Wei
>>
>>
>> On Sat, Dec 21, 2013 at 8:49 AM, Christian Humer <
>> christian.humer at gmail.com> wrote:
>>
>>> Hey folks,
>>>
>>> There were some questions floating around about the ImplicitCast feature
>>> in Truffle DSL.
>>> So here is a short description of what it does:
>>>
>>> The idea behind ImplicitCasts is that it tries to reduce the number of
>>> specializations required to define an operation. Imagine you got
>>> arithmetics with tree different types. That could be int, double and
>>> complex. However in our guest language we have several different
>>> representations of the same type for optimization reasons. For instance an
>>> int could be represented as Java int, IntSequence, IntVector or even as
>>> LogicalToIntVectorClosure (this example is borrowed from R).
>>> This makes a lot of combinations of types in binary operation to fully
>>> specialize itself. So assuming that double and complex have the same number
>>> of different representations and their number may even rise, the number of
>>> specializations will explode at some point in time.
>>> The solution for this problem was to introduce a new concept to the DSL,
>>> namely @ImplicitCast. The idea behind is that you can define casts that
>>> are inserted before a specialization is called on demand.
>>>
>>> So assume we have defined the specializations for a binary operation
>>> which fully specializes for the types int and IntVector. Without
>>> implicit casts you would have to define these four specializations.
>>>
>>> @Specialization int doOp(int left, int right) {...}
>>> @Specialization int doOp(IntVector left, int right) {...}
>>> @Specialization int doOp(int left, IntVector right) {...}
>>> @Specialization int doOp(IntVector left, IntVector right) {...}
>>>
>>> However if we assume that all four specializations would want to
>>> specialize to basically the same code we can use implicit casts to
>>> declare this more elegantly. For this we introduce a new interface called
>>> AbstractIntVector which is the base interface for IntVector, IntSequence
>>> etc. and we have to define some implicit casts in the type system like
>>> this:
>>>
>>>     @ImplicitCast
>>>     public AbstractIntVector toAbstractIntVector(int value) {
>>>         return DataFactory.createIntVectorFromScalar(value);
>>>     }
>>>     @ImplicitCast
>>>     public AbstractIntVector toAbstractIntVector(IntVector vector) {
>>>         return vector;
>>>     }
>>>
>>>
>>> @Specialization int
>>> doOp(AbstractIntVector left, AbstractIntVector right) {...}
>>>
>>> Now we can just define one specialization and we get the same
>>> specialization combinations as in the first example. Please be aware that
>>> this is not completely the same thing as before since the implicit cast method
>>> toAbstractIntVector is invoked prior to the invocation of the
>>> specialization. However Graal/Truffle is pretty good in removing
>>> unnecessary allocations for boxing if it sees the position of boxing as
>>> well as the position of the unboxing.
>>>
>>> You may even combine both the upper with the lower approach, like this:
>>>
>>> @Specialization int doOp(int left, int right) {...}
>>> @Specialization int
>>> doOp(AbstractIntVector left, AbstractIntVector right) {...}
>>>
>>> In this case you can provide a more optimized version for (int, int) but
>>> not having to specialize all the other combinations. Implicit casts are
>>> even more useful if the number of representations of the same logical type
>>> is high. This enables you to keep the number of specializations in binary
>>> nodes under control without breaking your fingers.
>>>
>>> Please note: On the contrary to custom @TypeCheck and @TypeCast methods,
>>> @ImplicitCasts are inserted on-demand. This means that they do not
>>> introduce additional overhead in compiled code as custom @TypeCheck or
>>> @TypeCast methods would.
>>>
>>> Feel free to ask further questions.
>>>
>>> - Christian Humer
>>>
>>
>>
>


More information about the graal-dev mailing list