Implict Casts in Truffle DSL

Christian Humer christian.humer at
Wed Apr 2 14:43:14 UTC 2014

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

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
Apr 02 00:06:40 2014 -0700
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.addParameter(new
+            if (expectType == null) {
+                method.addParameter(new
+            }
             if (expectType != null) {

- Christian Humer

On Tue, Apr 1, 2014 at 10:10 PM, Wei Zhang <ndrzmansn at> wrote:

> Hi Christian,
> I'm experiencing a problem when using @ImplicitCast.
> I added the following code in
> @ImplicitCast
> public String unboxPString(PString value) {
>       return value.getValue();
> }
> This use causes a javac error in the generated
> 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> 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