Implict Casts in Truffle DSL

Wei Zhang ndrzmansn at gmail.com
Wed Apr 2 21:26:37 UTC 2014


Thanks for the patch. It works nicely!

Yes, I'm planning to simplify the uses of @TypeCheck and @TypeCast, and use
@ImplicitCast instead for most of the cases.
However, I have a further question on that.
To implement multiple levels of implicit type coercions, e.g., from bool to
int and then to double, do I have to specify all possible conversions
separately?
Or can the generated code chain more than one @ImplicitCasts together to
convert a bool directly to double?

Thanks,

/Wei


On Wed, Apr 2, 2014 at 8:50 AM, Christian Humer
<christian.humer at gmail.com>wrote:

> 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