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.