Readability of `@code_warntype`

Hello all,

I find that the readability of @code_warntype has regressed considerably since v0.6. I am no expert on code introspection, but I used to be able to make out some of the meanings, not anymore :slight_smile:

Example from Column iterator - #5 by mschauer, trying to investigate the effects of inlining:

julia> function f7(yy, x) 
           for i in 1:size(yy, 2)
                   y = view(yy, :, i)
                           c(y,x)
                               end
                               end
f7 (generic function with 1 method)

julia> @noinline function c(y,x)
       for j in eachindex(x)
                  @inbounds y[j]=x[j]
           end
       end

On v0.6 with @noinline:

julia> @code_warntype f7(yy,y)
Variables:
  #self# <optimized out>
  yy::Array{Float64,2}
  x::Array{Float64,1}
  i::Int64
  y::SubArray{Float64,1,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},Int64},true}
  #temp#@_6::Int64
  J <optimized out>
  stride1 <optimized out>
  #temp#@_9 <optimized out>
  IP <optimized out>
  Îi@_11::Int64
  Îi@_12::Int64

Body:
  begin 
      SSAValue(2) = (Base.arraysize)(yy::Array{Float64,2}, 2)::Int64
      SSAValue(42) = (Base.select_value)((Base.sle_int)(1, SSAValue(2))::Bool, SSAValue(2), (Base.sub_int)(1, 1)::Int64)::Int64
      #temp#@_6::Int64 = 1
      4: 
      unless (Base.not_int)((#temp#@_6::Int64 === (Base.add_int)(SSAValue(42), 1)::Int64)::Bool)::Bool goto 105
      SSAValue(43) = #temp#@_6::Int64
      SSAValue(44) = (Base.add_int)(#temp#@_6::Int64, 1)::Int64
      i::Int64 = SSAValue(43)
      #temp#@_6::Int64 = SSAValue(44) # line 3:
      $(Expr(:inbounds, false))
      # meta: location subarray.jl view 112
      # meta: location indices.jl to_indices 213
      # meta: location abstractarray.jl indices 64
      SSAValue(6) = (Base.arraysize)(yy::Array{Float64,2}, 1)::Int64
      (Base.arraysize)(yy::Array{Float64,2}, 2)::Int64
      # meta: pop location
      # meta: location multidimensional.jl to_indices 469
      # meta: location multidimensional.jl uncolon 479
      # meta: location indices.jl Type 233
      # meta: location indices.jl Type 233
      # meta: location range.jl convert 764
      SSAValue(8) = (Base.select_value)((Base.slt_int)(SSAValue(6), 0)::Bool, 0, SSAValue(6))::Int64
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      SSAValue(40) = $(Expr(:new, Base.Slice{Base.OneTo{Int64}}, :($(Expr(:new, Base.OneTo{Int64}, :((Base.select_value)((Base.slt_int)(SSAValue(8), 0)::Bool, 0, SSAValue(8))::Int64))))))
      SSAValue(41) = i::Int64 # line 113:
      SSAValue(9) = (Core.tuple)(SSAValue(40), SSAValue(41))::Tuple{Base.Slice{Base.OneTo{Int64}},Int64}
      # meta: location abstractarray.jl checkbounds 362
      # meta: location abstractarray.jl checkbounds 342
      # meta: location abstractarray.jl indices 64
      (Base.arraysize)(yy::Array{Float64,2}, 1)::Int64
      SSAValue(15) = (Base.arraysize)(yy::Array{Float64,2}, 2)::Int64
      # meta: pop location
      # meta: location abstractarray.jl checkbounds_indices 389
      # meta: location abstractarray.jl checkbounds_indices 402
      SSAValue(16) = (Core.getfield)(SSAValue(9), 2)::Int64
      # meta: pop location
      # meta: pop location
      # meta: pop location
      SSAValue(10) = (Base.and_int)(true, (Base.and_int)((Base.sle_int)(1, SSAValue(16))::Bool, (Base.sle_int)(SSAValue(16), (Base.select_value)((Base.slt_int)(SSAValue(15), 0)::Bool, 0, SSAValue(15))::Int64)::Bool)::Bool)::Bool
      unless SSAValue(10) goto 49
      goto 51
      49: 
      $(Expr(:invoke, MethodInstance for throw_boundserror(::Array{Float64,2}, ::Tuple{Base.Slice{Base.OneTo{Int64}},Int64}), :(Base.throw_boundserror), :(yy), SSAValue(9)))
      51: 
      # meta: pop location # line 114:
      # meta: location subarray.jl unsafe_view 119
      # meta: location subarray.jl Type 22
      SSAValue(18) = (Core.tuple)(SSAValue(40), SSAValue(41))::Tuple{Base.Slice{Base.OneTo{Int64}},Int64}
      # meta: location subarray.jl Type 31
      # meta: location subarray.jl compute_stride1 240
      # meta: location abstractarray.jl indices 64
      (Base.arraysize)(yy::Array{Float64,2}, 1)::Int64
      (Base.arraysize)(yy::Array{Float64,2}, 2)::Int64
      # meta: pop location
      # meta: pop location # line 32:
      # meta: location subarray.jl compute_offset1 269
      # meta: location subarray.jl compute_offset1 271
      # meta: location subarray.jl compute_linindex 278
      # meta: location abstractarray.jl indices 64
      SSAValue(34) = (Base.arraysize)(yy::Array{Float64,2}, 1)::Int64
      (Base.arraysize)(yy::Array{Float64,2}, 2)::Int64
      # meta: pop location
      SSAValue(39) = (Base.select_value)((Base.slt_int)(SSAValue(34), 0)::Bool, 0, SSAValue(34))::Int64 # line 279:
      # meta: location subarray.jl compute_linindex 288
      Îi@_11::Int64 = (Base.sub_int)(1, 1)::Int64 # line 289:
      # meta: location subarray.jl compute_linindex 283
      Îi@_12::Int64 = (Base.sub_int)((Core.getfield)(SSAValue(18), 2)::Int64, 1)::Int64
      # meta: pop location
      # meta: pop location
      # meta: pop location
      SSAValue(25) = $(QuoteNode(1))
      # meta: location abstractarray.jl indices 47
      unless (Base.sle_int)(SSAValue(25), 2)::Bool goto 90
      # meta: location abstractarray.jl indices 64
      (Base.arraysize)(yy::Array{Float64,2}, 1)::Int64
      (Base.arraysize)(yy::Array{Float64,2}, 2)::Int64
      # meta: pop location
      goto 91
      90: 
      91: 
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      $(Expr(:inbounds, :pop))
      y::SubArray{Float64,1,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},Int64},true} = $(Expr(:new, SubArray{Float64,1,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},Int64},true}, :(yy), SSAValue(18), :((Base.sub_int)((Base.add_int)((Base.add_int)(1, (Base.mul_int)(Îi@_11, 1)::Int64)::Int64, (Base.mul_int)(Îi@_12, (Base.mul_int)(1, SSAValue(39))::Int64)::Int64)::Int64, (Base.mul_int)(1, 1)::Int64)::Int64), 1)) # line 4:
      $(Expr(:invoke, MethodInstance for c(::SubArray{Float64,1,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},Int64},true}, ::Array{Float64,1}), :(Main.c), :(y), :(x)))
      103: 
      goto 4
      105: 
      return
  end::Void

with @inline:

@code_warntype f7(yy,y)
Variables:
  #self# <optimized out>
  yy::Array{Float64,2}
  x::Array{Float64,1}
  i::Int64
  y <optimized out>
  #temp#@_6::Int64
  J <optimized out>
  stride1 <optimized out>
  #temp#@_9 <optimized out>
  IP <optimized out>
  Îi@_11::Int64
  Îi@_12::Int64
  j <optimized out>
  #temp#@_14::Int64

Body:
  begin 
      SSAValue(2) = (Base.arraysize)(yy::Array{Float64,2}, 2)::Int64
      SSAValue(54) = (Base.select_value)((Base.sle_int)(1, SSAValue(2))::Bool, SSAValue(2), (Base.sub_int)(1, 1)::Int64)::Int64
      #temp#@_6::Int64 = 1
      4: 
      unless (Base.not_int)((#temp#@_6::Int64 === (Base.add_int)(SSAValue(54), 1)::Int64)::Bool)::Bool goto 140
      SSAValue(55) = #temp#@_6::Int64
      SSAValue(56) = (Base.add_int)(#temp#@_6::Int64, 1)::Int64
      i::Int64 = SSAValue(55)
      #temp#@_6::Int64 = SSAValue(56) # line 3:
      $(Expr(:inbounds, false))
      # meta: location subarray.jl view 112
      # meta: location indices.jl to_indices 213
      # meta: location abstractarray.jl indices 64
      SSAValue(6) = (Base.arraysize)(yy::Array{Float64,2}, 1)::Int64
      (Base.arraysize)(yy::Array{Float64,2}, 2)::Int64
      # meta: pop location
      # meta: location multidimensional.jl to_indices 469
      # meta: location multidimensional.jl uncolon 479
      # meta: location indices.jl Type 233
      # meta: location indices.jl Type 233
      # meta: location range.jl convert 764
      SSAValue(8) = (Base.select_value)((Base.slt_int)(SSAValue(6), 0)::Bool, 0, SSAValue(6))::Int64
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      SSAValue(40) = $(Expr(:new, Base.Slice{Base.OneTo{Int64}}, :($(Expr(:new, Base.OneTo{Int64}, :((Base.select_value)((Base.slt_int)(SSAValue(8), 0)::Bool, 0, SSAValue(8))::Int64))))))
      SSAValue(41) = i::Int64 # line 113:
      SSAValue(9) = (Core.tuple)(SSAValue(40), SSAValue(41))::Tuple{Base.Slice{Base.OneTo{Int64}},Int64}
      # meta: location abstractarray.jl checkbounds 362
      # meta: location abstractarray.jl checkbounds 342
      # meta: location abstractarray.jl indices 64
      (Base.arraysize)(yy::Array{Float64,2}, 1)::Int64
      SSAValue(15) = (Base.arraysize)(yy::Array{Float64,2}, 2)::Int64
      # meta: pop location
      # meta: location abstractarray.jl checkbounds_indices 389
      # meta: location abstractarray.jl checkbounds_indices 402
      SSAValue(16) = (Core.getfield)(SSAValue(9), 2)::Int64
      # meta: pop location
      # meta: pop location
      # meta: pop location
      SSAValue(10) = (Base.and_int)(true, (Base.and_int)((Base.sle_int)(1, SSAValue(16))::Bool, (Base.sle_int)(SSAValue(16), (Base.select_value)((Base.slt_int)(SSAValue(15), 0)::Bool, 0, SSAValue(15))::Int64)::Bool)::Bool)::Bool
      unless SSAValue(10) goto 49
      goto 51
      49: 
      $(Expr(:invoke, MethodInstance for throw_boundserror(::Array{Float64,2}, ::Tuple{Base.Slice{Base.OneTo{Int64}},Int64}), :(Base.throw_boundserror), :(yy), SSAValue(9)))
      51: 
      # meta: pop location # line 114:
      # meta: location subarray.jl unsafe_view 119
      # meta: location subarray.jl Type 22
      SSAValue(18) = (Core.tuple)(SSAValue(40), SSAValue(41))::Tuple{Base.Slice{Base.OneTo{Int64}},Int64}
      # meta: location subarray.jl Type 31
      # meta: location subarray.jl compute_stride1 240
      # meta: location abstractarray.jl indices 64
      (Base.arraysize)(yy::Array{Float64,2}, 1)::Int64
      (Base.arraysize)(yy::Array{Float64,2}, 2)::Int64
      # meta: pop location
      # meta: pop location # line 32:
      # meta: location subarray.jl compute_offset1 269
      # meta: location subarray.jl compute_offset1 271
      # meta: location subarray.jl compute_linindex 278
      # meta: location abstractarray.jl indices 64
      SSAValue(34) = (Base.arraysize)(yy::Array{Float64,2}, 1)::Int64
      (Base.arraysize)(yy::Array{Float64,2}, 2)::Int64
      # meta: pop location
      SSAValue(39) = (Base.select_value)((Base.slt_int)(SSAValue(34), 0)::Bool, 0, SSAValue(34))::Int64 # line 279:
      # meta: location subarray.jl compute_linindex 288
      Îi@_11::Int64 = (Base.sub_int)(1, 1)::Int64 # line 289:
      # meta: location subarray.jl compute_linindex 283
      Îi@_12::Int64 = (Base.sub_int)((Core.getfield)(SSAValue(18), 2)::Int64, 1)::Int64
      # meta: pop location
      # meta: pop location
      # meta: pop location
      SSAValue(25) = $(QuoteNode(1))
      # meta: location abstractarray.jl indices 47
      unless (Base.sle_int)(SSAValue(25), 2)::Bool goto 90
      # meta: location abstractarray.jl indices 64
      (Base.arraysize)(yy::Array{Float64,2}, 1)::Int64
      (Base.arraysize)(yy::Array{Float64,2}, 2)::Int64
      # meta: pop location
      goto 91
      90: 
      91: 
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      $(Expr(:inbounds, :pop))
      SSAValue(57) = yy::Array{Float64,2}
      SSAValue(58) = (Base.sub_int)((Base.add_int)((Base.add_int)(1, (Base.mul_int)(Îi@_11::Int64, 1)::Int64)::Int64, (Base.mul_int)(Îi@_12::Int64, (Base.mul_int)(1, SSAValue(39))::Int64)::Int64)::Int64, (Base.mul_int)(1, 1)::Int64)::Int64 # line 4:
      $(Expr(:inbounds, false))
      # meta: location REPL[7] c 2
      # meta: location abstractarray.jl eachindex 764
      # meta: location abstractarray.jl indices1 71
      # meta: location abstractarray.jl indices 64
      SSAValue(47) = (Base.arraysize)(x::Array{Float64,1}, 1)::Int64
      # meta: pop location
      # meta: pop location
      # meta: pop location
      SSAValue(51) = (Base.select_value)((Base.slt_int)(SSAValue(47), 0)::Bool, 0, SSAValue(47))::Int64
      #temp#@_14::Int64 = 1
      114: 
      unless (Base.not_int)((#temp#@_14::Int64 === (Base.add_int)(SSAValue(51), 1)::Int64)::Bool)::Bool goto 135
      SSAValue(52) = #temp#@_14::Int64
      SSAValue(53) = (Base.add_int)(#temp#@_14::Int64, 1)::Int64
      #temp#@_14::Int64 = SSAValue(53) # line 3:
      $(Expr(:inbounds, true))
      SSAValue(44) = (Base.arrayref)(x::Array{Float64,1}, SSAValue(52))::Float64
      $(Expr(:inbounds, false))
      # meta: location subarray.jl setindex! 219
      124: 
      125:  # line 220:
      $(Expr(:inbounds, true))
      (Base.arrayset)(SSAValue(57), SSAValue(44), (Base.add_int)(SSAValue(58), SSAValue(52))::Int64)::Array{Float64,2}
      $(Expr(:inbounds, :pop))
      # meta: pop location
      $(Expr(:inbounds, :pop))
      $(Expr(:inbounds, :pop))
      133: 
      goto 114
      135: 
      # meta: pop location
      $(Expr(:inbounds, :pop))
      138: 
      goto 4
      140: 
      return
  end::Void

Note how y <optimized out> mostly told the story, the views were optimized out in one case, and not in the other.

Now on v1.0:

with @noinline:

Body::Nothing
β”‚β•»             size2 1 ── %1  = (Base.arraysize)(yy, 2)::Int64
β”‚β”‚β•»β•·β•·β•·          Type  β”‚    %2  = (Base.sle_int)(1, %1)::Bool
β”‚β”‚β”‚β•»             unitrange_last  β”‚          (Base.sub_int)(%1, 1)
β”‚β”‚β”‚β”‚            β”‚    %4  = (Base.ifelse)(%2, %1, 0)::Int64
β”‚β”‚β•»β•·β•·           isempty  β”‚    %5  = (Base.slt_int)(%4, 1)::Bool
β”‚β”‚              └───       goto #3 if not %5
β”‚β”‚              2 ──       goto #4
β”‚β”‚              3 ──       goto #4
β”‚               4 ┄─ %9  = Ο† (#2 => true, #3 => false)::Bool
β”‚               β”‚    %10 = Ο† (#3 => 1)::Int64
β”‚               β”‚    %11 = Ο† (#3 => 1)::Int64
β”‚               β”‚    %12 = (Base.not_int)(%9)::Bool
β”‚               └───       goto #16 if not %12
β”‚               5 ┄─ %14 = Ο† (#4 => %10, #15 => %81)::Int64
β”‚               β”‚    %15 = Ο† (#4 => %11, #15 => %82)::Int64
β”‚β•»β•·β•·β•·          view3 β”‚    %16 = (Base.arraysize)(yy, 1)::Int64
││┃││           to_indices  β”‚    %17 = (Base.arraysize)(yy, 2)::Int64
β”‚β”‚β”‚β•»β•·β•·β•·          axes  β”‚    %18 = (Base.slt_int)(%16, 0)::Bool
││││┃│││          map  β”‚    %19 = (Base.ifelse)(%18, 0, %16)::Int64
│││││┃│            Type  β”‚    %20 = %new(Base.OneTo{Int64}, %19)::Base.OneTo{Int64}
β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           Type  β”‚    %21 = (Base.slt_int)(%17, 0)::Bool
│││││││┃             max  β”‚          (Base.ifelse)(%21, 0, %17)
β”‚β”‚β”‚β”‚β•»β•·β•·           uncolon  β”‚    %23 = %new(Base.Slice{Base.OneTo{Int64}}, %20)::Base.Slice{Base.OneTo{Int64}}
β”‚β•»             view  └───       goto #10 if not true
β”‚β”‚              6 ── %25 = (Core.tuple)(%23, %14)::Tuple{Base.Slice{Base.OneTo{Int64}},Int64}
β”‚β”‚β•»β•·β•·           checkbounds  β”‚    %26 = (Base.arraysize)(yy, 1)::Int64
│││┃││           checkbounds  β”‚    %27 = (Base.arraysize)(yy, 2)::Int64
β”‚β”‚β”‚β”‚β•»β•·β•·β•·          axes  β”‚    %28 = (Base.slt_int)(%26, 0)::Bool
│││││┃│││          map  β”‚          (Base.ifelse)(%28, 0, %26)
β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           Type  β”‚    %30 = (Base.slt_int)(%27, 0)::Bool
│││││││┃│            Type  β”‚    %31 = (Base.ifelse)(%30, 0, %27)::Int64
β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           checkbounds_indices  β”‚    %32 = (Base.sle_int)(1, %14)::Bool
││││││┃│            checkindex  β”‚    %33 = (Base.sle_int)(%14, %31)::Bool
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             &  β”‚    %34 = (Base.and_int)(%32, %33)::Bool
β”‚β”‚β”‚β”‚β”‚β”‚β•»             &  β”‚    %35 = (Base.and_int)(%34, true)::Bool
β”‚β”‚β”‚β”‚β”‚β•»             &  β”‚    %36 = (Base.and_int)(true, %35)::Bool
β”‚β”‚β”‚             └───       goto #8 if not %36
β”‚β”‚β”‚             7 ──       goto #9
β”‚β”‚β”‚             8 ──       invoke Base.throw_boundserror(_2::Array{Float64,2}, %25::Tuple{Base.Slice{Base.OneTo{Int64}},Int64})
β”‚β”‚β”‚             └───       $(Expr(:unreachable))
β”‚               9 ┄─       nothing
β”‚β”‚β•»β•·β•·           unsafe_view  10 ─ %42 = (Core.tuple)(%23, %14)::Tuple{Base.Slice{Base.OneTo{Int64}},Int64}
β”‚β”‚β”‚β•»β•·β•·           Type  β”‚    %43 = (Base.arraysize)(yy, 1)::Int64
││││┃│││          Type  β”‚    %44 = (Base.arraysize)(yy, 2)::Int64
β”‚β”‚β”‚β”‚β”‚β•»β•·β•·β•·          compute_stride1  β”‚    %45 = (Base.slt_int)(%43, 0)::Bool
││││││┃││││         axes  β”‚          (Base.ifelse)(%45, 0, %43)
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           map  β”‚    %47 = (Base.slt_int)(%44, 0)::Bool
││││││││┃││           Type  β”‚          (Base.ifelse)(%47, 0, %44)
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·            Type  β”‚          (Base.ifelse)(false, 0, 1)
β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           compute_offset1  β”‚    %50 = (Base.add_int)(1, 1)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β•»             find_extended_dims  β”‚          (Base.add_int)(%50, 1)
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           compute_linindex  β”‚    %52 = (Base.arraysize)(yy, 1)::Int64
││││││││┃│            axes  β”‚    %53 = (Base.arraysize)(yy, 2)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·β•·          map  β”‚    %54 = (Base.slt_int)(%52, 0)::Bool
││││││││││┃││           Type  β”‚    %55 = (Base.ifelse)(%54, 0, %52)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           Type  β”‚    %56 = (Base.slt_int)(%53, 0)::Bool
││││││││││││┃             max  β”‚    %57 = (Base.ifelse)(%56, 0, %53)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·            Type  β”‚          (Base.ifelse)(false, 0, 1)
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           compute_linindex  β”‚    %59 = (Base.sub_int)(%55, 0)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             *  β”‚    %60 = (Base.mul_int)(1, %59)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             -  β”‚    %61 = (Base.sub_int)(%14, 1)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             *  β”‚    %62 = (Base.mul_int)(%61, %60)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             +  β”‚    %63 = (Base.add_int)(1, %62)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             -  β”‚    %64 = (Base.sub_int)(%57, 0)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             *  β”‚          (Base.mul_int)(%60, %64)
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·            axes  β”‚    %66 = (Base.arraysize)(yy, 1)::Int64
│││││││││┃             size  β”‚    %67 = (Base.arraysize)(yy, 2)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·β•·          Type  β”‚    %68 = (Base.slt_int)(%66, 0)::Bool
│││││││││││┃│            Type  β”‚          (Base.ifelse)(%68, 0, %66)
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           Type  β”‚    %70 = (Base.slt_int)(%67, 0)::Bool
││││││││││││┃             max  β”‚          (Base.ifelse)(%70, 0, %67)
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             -  β”‚    %72 = (Base.sub_int)(%63, 1)::Int64
β”‚β”‚β”‚β”‚β”‚β•»             Type  β”‚    %73 = %new(SubArray{Float64,1,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},Int64},true}, yy, %42, %72, 1)::SubArray{Float64,1,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},Int64},true}
β”‚β”‚              └───       goto #11
β”‚             4 11 ─       invoke Main.c(%73::SubArray{Float64,1,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},Int64},true}, _3::Array{Float64,1})
β”‚β•»             iterate  β”‚    %76 = (%15 === %4)::Bool
β”‚β”‚              └───       goto #13 if not %76
β”‚β”‚              12 ─       goto #14
β”‚β”‚β•»             +  13 ─ %79 = (Base.add_int)(%15, 1)::Int64
β”‚β•»             iterate  └───       goto #14
β”‚               14 β”„ %81 = Ο† (#13 => %79)::Int64
β”‚               β”‚    %82 = Ο† (#13 => %79)::Int64
β”‚               β”‚    %83 = Ο† (#12 => true, #13 => false)::Bool
β”‚               β”‚    %84 = (Base.not_int)(%83)::Bool
β”‚               └───       goto #16 if not %84
β”‚               15 ─       goto #5
β”‚               16 ─       return

and with @inline:

@code_warntype f7(yy, y)
Body::Nothing
β”‚β•»             size2 1 ── %1   = (Base.arraysize)(yy, 2)::Int64
β”‚β”‚β•»β•·β•·β•·          Type  β”‚    %2   = (Base.sle_int)(1, %1)::Bool
β”‚β”‚β”‚β•»             unitrange_last  β”‚           (Base.sub_int)(%1, 1)
β”‚β”‚β”‚β”‚            β”‚    %4   = (Base.ifelse)(%2, %1, 0)::Int64
β”‚β”‚β•»β•·β•·           isempty  β”‚    %5   = (Base.slt_int)(%4, 1)::Bool
β”‚β”‚              └───        goto #3 if not %5
β”‚β”‚              2 ──        goto #4
β”‚β”‚              3 ──        goto #4
β”‚               4 ┄─ %9   = Ο† (#2 => true, #3 => false)::Bool
β”‚               β”‚    %10  = Ο† (#3 => 1)::Int64
β”‚               β”‚    %11  = Ο† (#3 => 1)::Int64
β”‚               β”‚    %12  = (Base.not_int)(%9)::Bool
β”‚               └───        goto #32 if not %12
β”‚               5 ┄─ %14  = Ο† (#4 => %10, #31 => %120)::Int64
β”‚               β”‚    %15  = Ο† (#4 => %11, #31 => %121)::Int64
β”‚β•»β•·β•·β•·          view3 β”‚    %16  = (Base.arraysize)(yy, 1)::Int64
││┃││           to_indices  β”‚    %17  = (Base.arraysize)(yy, 2)::Int64
β”‚β”‚β”‚β•»β•·β•·β•·          axes  β”‚    %18  = (Base.slt_int)(%16, 0)::Bool
││││┃│││          map  β”‚    %19  = (Base.ifelse)(%18, 0, %16)::Int64
│││││┃│            Type  β”‚    %20  = %new(Base.OneTo{Int64}, %19)::Base.OneTo{Int64}
β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           Type  β”‚    %21  = (Base.slt_int)(%17, 0)::Bool
│││││││┃             max  β”‚           (Base.ifelse)(%21, 0, %17)
β”‚β”‚β”‚β”‚β•»β•·β•·           uncolon  β”‚    %23  = %new(Base.Slice{Base.OneTo{Int64}}, %20)::Base.Slice{Base.OneTo{Int64}}
β”‚β•»             view  └───        goto #10 if not true
β”‚β”‚              6 ── %25  = (Core.tuple)(%23, %14)::Tuple{Base.Slice{Base.OneTo{Int64}},Int64}
β”‚β”‚β•»β•·β•·           checkbounds  β”‚    %26  = (Base.arraysize)(yy, 1)::Int64
│││┃││           checkbounds  β”‚    %27  = (Base.arraysize)(yy, 2)::Int64
β”‚β”‚β”‚β”‚β•»β•·β•·β•·          axes  β”‚    %28  = (Base.slt_int)(%26, 0)::Bool
│││││┃│││          map  β”‚           (Base.ifelse)(%28, 0, %26)
β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           Type  β”‚    %30  = (Base.slt_int)(%27, 0)::Bool
│││││││┃│            Type  β”‚    %31  = (Base.ifelse)(%30, 0, %27)::Int64
β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           checkbounds_indices  β”‚    %32  = (Base.sle_int)(1, %14)::Bool
││││││┃│            checkindex  β”‚    %33  = (Base.sle_int)(%14, %31)::Bool
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             &  β”‚    %34  = (Base.and_int)(%32, %33)::Bool
β”‚β”‚β”‚β”‚β”‚β”‚β•»             &  β”‚    %35  = (Base.and_int)(%34, true)::Bool
β”‚β”‚β”‚β”‚β”‚β•»             &  β”‚    %36  = (Base.and_int)(true, %35)::Bool
β”‚β”‚β”‚             └───        goto #8 if not %36
β”‚β”‚β”‚             7 ──        goto #9
β”‚β”‚β”‚             8 ──        invoke Base.throw_boundserror(_2::Array{Float64,2}, %25::Tuple{Base.Slice{Base.OneTo{Int64}},Int64})
β”‚β”‚β”‚             └───        $(Expr(:unreachable))
β”‚               9 ┄─        nothing
β”‚β”‚β•»β•·β•·           unsafe_view  10 ─ %42  = (Core.tuple)(%23, %14)::Tuple{Base.Slice{Base.OneTo{Int64}},Int64}
β”‚β”‚β”‚β•»β•·β•·           Type  β”‚    %43  = (Base.arraysize)(yy, 1)::Int64
││││┃│││          Type  β”‚    %44  = (Base.arraysize)(yy, 2)::Int64
β”‚β”‚β”‚β”‚β”‚β•»β•·β•·β•·          compute_stride1  β”‚    %45  = (Base.slt_int)(%43, 0)::Bool
││││││┃││││         axes  β”‚           (Base.ifelse)(%45, 0, %43)
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           map  β”‚    %47  = (Base.slt_int)(%44, 0)::Bool
││││││││┃││           Type  β”‚           (Base.ifelse)(%47, 0, %44)
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·            Type  β”‚           (Base.ifelse)(false, 0, 1)
β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           compute_offset1  β”‚    %50  = (Base.add_int)(1, 1)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β•»             find_extended_dims  β”‚           (Base.add_int)(%50, 1)
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           compute_linindex  β”‚    %52  = (Base.arraysize)(yy, 1)::Int64
││││││││┃│            axes  β”‚    %53  = (Base.arraysize)(yy, 2)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·β•·          map  β”‚    %54  = (Base.slt_int)(%52, 0)::Bool
││││││││││┃││           Type  β”‚    %55  = (Base.ifelse)(%54, 0, %52)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           Type  β”‚    %56  = (Base.slt_int)(%53, 0)::Bool
││││││││││││┃             max  β”‚    %57  = (Base.ifelse)(%56, 0, %53)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·            Type  β”‚           (Base.ifelse)(false, 0, 1)
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           compute_linindex  β”‚    %59  = (Base.sub_int)(%55, 0)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             *  β”‚    %60  = (Base.mul_int)(1, %59)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             -  β”‚    %61  = (Base.sub_int)(%14, 1)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             *  β”‚    %62  = (Base.mul_int)(%61, %60)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             +  β”‚    %63  = (Base.add_int)(1, %62)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             -  β”‚    %64  = (Base.sub_int)(%57, 0)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             *  β”‚           (Base.mul_int)(%60, %64)
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·            axes  β”‚    %66  = (Base.arraysize)(yy, 1)::Int64
│││││││││┃             size  β”‚    %67  = (Base.arraysize)(yy, 2)::Int64
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·β•·          Type  β”‚    %68  = (Base.slt_int)(%66, 0)::Bool
│││││││││││┃│            Type  β”‚           (Base.ifelse)(%68, 0, %66)
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»β•·β•·           Type  β”‚    %70  = (Base.slt_int)(%67, 0)::Bool
││││││││││││┃             max  β”‚           (Base.ifelse)(%70, 0, %67)
β”‚β”‚β”‚β”‚β”‚β”‚β”‚β•»             -  β”‚    %72  = (Base.sub_int)(%63, 1)::Int64
β”‚β”‚β”‚β”‚β”‚β•»             Type  β”‚    %73  = %new(SubArray{Float64,1,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},Int64},true}, yy, %42, %72, 1)::SubArray{Float64,1,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},Int64},true}
β”‚β”‚              └───        goto #11
β”‚β•»β•·β•·β•·β•·         c4 11 ─ %75  = (Base.arraysize)(x, 1)::Int64
β”‚β”‚β•»β•·β•·β•·          eachindex  β”‚    %76  = (Base.slt_int)(%75, 0)::Bool
│││┃│││││        axes1  β”‚    %77  = (Base.ifelse)(%76, 0, %75)::Int64
β”‚β”‚β”‚β•»β•·β•·           isempty  β”‚    %78  = (Base.slt_int)(%77, 1)::Bool
β”‚β”‚β”‚             └───        goto #13 if not %78
β”‚β”‚β”‚             12 ─        goto #14
β”‚β”‚β”‚             13 ─        goto #14
β”‚β”‚              14 β”„ %82  = Ο† (#12 => true, #13 => false)::Bool
β”‚β”‚              β”‚    %83  = Ο† (#13 => 1)::Int64
β”‚β”‚              β”‚    %84  = Ο† (#13 => 1)::Int64
β”‚β”‚              β”‚    %85  = (Base.not_int)(%82)::Bool
β”‚β”‚              └───        goto #26 if not %85
β”‚β”‚              15 β”„ %87  = Ο† (#14 => %83, #25 => %108)::Int64
β”‚β”‚              β”‚    %88  = Ο† (#14 => %84, #25 => %109)::Int64
β”‚β”‚β•»             getindex  β”‚    %89  = (Base.arrayref)(false, x, %87)::Float64
β”‚β”‚β•»             setindex!  └───        goto #20 if not false
β”‚β”‚β”‚             16 ─ %91  = (Core.tuple)(%87)::Tuple{Int64}
β”‚β”‚β”‚β•»β•·β•·           checkbounds  β”‚    %92  = (Base.sle_int)(1, %87)::Bool
││││┃││           checkbounds  β”‚    %93  = (Base.sle_int)(%87, %19)::Bool
β”‚β”‚β”‚β”‚β”‚β•»             checkindex  β”‚    %94  = (Base.and_int)(%92, %93)::Bool
β”‚β”‚β”‚β”‚            └───        goto #18 if not %94
β”‚β”‚β”‚β”‚            17 ─        goto #19
β”‚β”‚β”‚β”‚            18 ─        invoke Base.throw_boundserror(%73::SubArray{Float64,1,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},Int64},true}, %91::Tuple{Int64})
β”‚β”‚β”‚β”‚            └───        $(Expr(:unreachable))
β”‚               19 β”„        nothing
β”‚β”‚β”‚β•»             +  20 ─ %100 = (Base.add_int)(%72, %87)::Int64
β”‚β”‚β”‚β•»             setindex!  β”‚           (Base.arrayset)(false, yy, %89, %100)
β”‚β”‚β•»             setindex!  └───        goto #21
β”‚β”‚β”‚β•»             ==  21 ─ %103 = (%88 === %77)::Bool
β”‚β”‚β”‚             └───        goto #23 if not %103
β”‚β”‚β”‚             22 ─        goto #24
β”‚β”‚β”‚β•»             +  23 ─ %106 = (Base.add_int)(%88, 1)::Int64
β”‚β”‚β•»             iterate  └───        goto #24
β”‚β”‚              24 β”„ %108 = Ο† (#23 => %106)::Int64
β”‚β”‚              β”‚    %109 = Ο† (#23 => %106)::Int64
β”‚β”‚              β”‚    %110 = Ο† (#22 => true, #23 => false)::Bool
β”‚β”‚              β”‚    %111 = (Base.not_int)(%110)::Bool
β”‚β”‚              └───        goto #26 if not %111
β”‚β”‚              25 ─        goto #15
β”‚β”‚              26 ─        goto #27
β”‚β”‚β•»             ==  27 ─ %115 = (%15 === %4)::Bool
β”‚β”‚              └───        goto #29 if not %115
β”‚β”‚              28 ─        goto #30
β”‚β”‚β•»             +  29 ─ %118 = (Base.add_int)(%15, 1)::Int64
β”‚β•»             iterate  └───        goto #30
β”‚               30 β”„ %120 = Ο† (#29 => %118)::Int64
β”‚               β”‚    %121 = Ο† (#29 => %118)::Int64
β”‚               β”‚    %122 = Ο† (#28 => true, #29 => false)::Bool
β”‚               β”‚    %123 = (Base.not_int)(%122)::Bool
β”‚               └───        goto #32 if not %123
β”‚               31 ─        goto #5
β”‚               32 ─        return

I guess the same information is hidden in invoke Main.c(%73::SubArray... but this is a guess based on the hint from v0.6.

The last thing I want is for this post to sound like a rant, it isn’t! I fully appreciate the fact that getting v1.0 out was more important than the beauty of the output of @code_warntype; but can’t we just be greedy and have everything :wink:

Also, I would appreciate any pointers on how to read the output or more appropriate tools to accomplish such tasks.

Thanks!

4 Likes

Filed here:
https://github.com/JuliaLang/julia/issues/29287

1 Like

Traceur seems to be a good answer to this:

1 Like

If I understand correctly (feel free to correct me), in this case, there is no type instability per se. So Traceur would not raise any flags.

The info in the previous form was much more than just type instability.