On Thu, Sep 18, 2014 at 2:33 PM, Ivar Nesje <iva...@gmail.com> wrote:

> Seems like Julia is not smart enough to guess that i::IdType will always
> ensure that i is a Int64 when IdType might change.


Since IdType is not constant, it can change at any time – generating code
on the premise that it cannot change would be incorrect. Instead, the code
generated for this function needs to handle the possibility that IdType can
change at any point, which basically makes all optimizations impossible.
It's a bit low level (we should really expose this better), but you can use
@code_typed to see what the inferred types of all the local variables are:

julia> (@code_typed manual_iter1(1,2))[1].args[2][2]
38-element Array{Any,1}:
 {:dt1,Int64,0}
 {:dt2,Int64,0}
 {:zeroIdType,Any,18}
 {:oneIdType,Any,18}
 {:zeroDType,Any,18}
 {symbol("#s5149"),Any,18}
 {symbol("#s5150"),Any,18}
 {:dt1id1,Any,18}
 {:dt1D,Any,18}
 {symbol("#s5151"),Any,18}
 {symbol("#s5152"),Any,18}
 {symbol("#s5153"),Any,18}
 {:dt2id2,Any,18}
 {:dt2D1,Any,18}
 {:dt2D2,Any,18}
 {:MAX_INT,Any,18}
 {:MAX_D,Any,18}
 {:nrow1,Any,18}
 {:nrow2,Any,18}
 {:i1,Any,2}
 {:i1id1,Any,2}
 {:i1D,Any,2}
 {:i2Lower,Any,2}
 {:i2LowerD2,Any,2}
 {:i2Upper,Any,2}
 {:i2UpperD1,Any,2}
 {:i2UpperD2,Any,2}
 {:i2Match,Any,2}
 {:i,Any,2}
 {:nrowMax,Any,18}
 {:resid1,Any,18}
 {:resid2,Any,18}
 {:resD1,Any,18}
 {:resD,Any,18}
 {:resD2,Any,18}
 {:i2MatchD2,Any,18}
 {:i2MatchD1,Any,18}
 {symbol("#s5154"),Any,18}


As you can see, it's not pretty: given Int arguments, literally only the
types of the arguments themselves are more specific than Any. If you
declare IdType and DType to be const, it gets better, but still not ideal:

julia> (@code_typed manual_iter1(1,2))[1].args[2][2]
38-element Array{Any,1}:
 {:dt1,Int64,0}
 {:dt2,Int64,0}
 {:zeroIdType,Int64,18}
 {:oneIdType,Int64,18}
 {:zeroDType,Int64,18}
 {symbol("#s122"),Any,18}
 {symbol("#s121"),Any,18}
 {:dt1id1,Any,18}
 {:dt1D,Any,18}
 {symbol("#s120"),Any,18}
 {symbol("#s119"),Any,18}
 {symbol("#s118"),Any,18}
 {:dt2id2,Any,18}
 {:dt2D1,Any,18}
 {:dt2D2,Any,18}
 {:MAX_INT,Int64,18}
 {:MAX_D,Int64,18}
 {:nrow1,Int64,18}
 {:nrow2,Int64,18}
 {:i1,Int64,2}
 {:i1id1,Int64,2}
 {:i1D,Int64,2}
 {:i2Lower,Int64,2}
 {:i2LowerD2,Int64,2}
 {:i2Upper,Int64,2}
 {:i2UpperD1,Int64,2}
 {:i2UpperD2,Int64,2}
 {:i2Match,Int64,2}
 {:i,Int64,2}
 {:nrowMax,Int64,18}
 {:resid1,Any,18}
 {:resid2,Any,18}
 {:resD1,Any,18}
 {:resD,Any,18}
 {:resD2,Any,18}
 {:i2MatchD2,Any,18}
 {:i2MatchD1,Any,18}
 {symbol("#s117"),Any,18}


When you pull something out of an untyped structure like dt1id1, dt1D, etc.
it is a good idea to provide some type annotations if you can. Most of the
other type annotations inside the function body are unnecessary, however.

Reply via email to