如何正确读取右侧的@code_warntype新诊断输出?

时间:2018-08-09 12:36:17

标签: julia

尤其是那些虚线,是什么意思?

julia> @code_warntype gcd(4,5)
Body::Int64
31 1 ── %1  = %new(Base.:(#throw1#307))::Core.Compiler.Const(getfield(Base, Symbol("#throw1#307"))(), false)
32 │    %2  = (a === 0)::Bool                           │╻     ==
   └───       goto #3 if not %2                         │     
   2 ── %4  = (Base.flipsign_int)(b, b)::Int64          ││╻     flipsign
   └───       return %4                                 │     
33 3 ── %6  = (b === 0)::Bool                           │╻     ==
   └───       goto #5 if not %6                         │     
   4 ── %8  = (Base.flipsign_int)(a, a)::Int64          ││╻     flipsign
   └───       return %8                                 │     
34 5 ── %10 = (Base.cttz_int)(a)::Int64                 │╻     trailing_zeros
35 │    %11 = (Base.cttz_int)(b)::Int64                 │╻     trailing_zeros
36 │    %12 = (Base.slt_int)(%11, %10)::Bool            │╻╷    min
   │    %13 = (Base.ifelse)(%12, %11, %10)::Int64       ││    
37 │    %14 = (Base.sle_int)(0, %10)::Bool              │╻╷    >>
   │    %15 = (Base.bitcast)(UInt64, %10)::UInt64       ││╻     unsigned
   │    %16 = (Base.ashr_int)(a, %15)::Int64            ││╻     >>
   │    %17 = (Base.neg_int)(%10)::Int64                ││╻     -
   │    %18 = (Base.bitcast)(UInt64, %17)::UInt64       │││╻     reinterpret
   │    %19 = (Base.shl_int)(a, %18)::Int64             ││╻     <<
   │    %20 = (Base.ifelse)(%14, %16, %19)::Int64       ││    
   │    %21 = (Base.flipsign_int)(%20, %20)::Int64      ││╻     flipsign
   │    %22 = (Base.bitcast)(UInt64, %21)::UInt64       ││╻     reinterpret
38 │    %23 = (Base.sle_int)(0, %11)::Bool              │╻╷    >>
   │    %24 = (Base.bitcast)(UInt64, %11)::UInt64       ││╻     unsigned
   │    %25 = (Base.ashr_int)(b, %24)::Int64            ││╻     >>
   │    %26 = (Base.neg_int)(%11)::Int64                ││╻     -
   │    %27 = (Base.bitcast)(UInt64, %26)::UInt64       │││╻     reinterpret
   │    %28 = (Base.shl_int)(b, %27)::Int64             ││╻     <<
   │    %29 = (Base.ifelse)(%23, %25, %28)::Int64       ││    
   │    %30 = (Base.flipsign_int)(%29, %29)::Int64      ││╻     flipsign
   └─── %31 = (Base.bitcast)(UInt64, %30)::UInt64       ││╻     reinterpret
39 6 ┄─ %32 = φ (#5 => %22, #15 => %40)::UInt64         │     
   │    %33 = φ (#5 => %31, #15 => %61)::UInt64         │     
   │    %34 = (%32 === %33)::Bool                       │╻     !=
   │    %35 = (Base.not_int)(%34)::Bool                 ││╻     !
   └───       goto #16 if not %35                       │     
40 7 ── %37 = (Base.ult_int)(%33, %32)::Bool            │╻╷    >
   └───       goto #9 if not %37                        │     
   8 ──       nothing                                   │     
43 9 ── %40 = φ (#8 => %33, #7 => %32)::UInt64          │     
   │    %41 = φ (#8 => %32, #7 => %33)::UInt64          │     
   │    %42 = (Base.sub_int)(%41, %40)::UInt64          │╻     -
44 │    %43 = (Base.cttz_int)(%42)::UInt64              │╻     trailing_zeros
   │    %44 = (Core.lshr_int)(%43, 63)::UInt64          ││╻╷╷   Type
   │    %45 = (Core.trunc_int)(Core.UInt8, %44)::UInt8  │││┃││   toInt64
   │    %46 = (Core.eq_int)(%45, 0x01)::Bool            ││││┃│    check_top_bit
   └───       goto #11 if not %46                       │││││ 
   10 ─       invoke Core.throw_inexacterror(:check_top_bit::Symbol, UInt64::Any, %43::UInt64)
   └───       $(Expr(:unreachable))                     │││││ 
   11 ─       goto #12                                  │││││ 
   12 ─ %51 = (Core.bitcast)(Core.Int64, %43)::Int64    ││││  
   └───       goto #13                                  ││││  
   13 ─       goto #14                                  │││   
   14 ─       goto #15                                  ││    
   15 ─ %55 = (Base.sle_int)(0, %51)::Bool              ││╻     <=
   │    %56 = (Base.bitcast)(UInt64, %51)::UInt64       │││╻     reinterpret
   │    %57 = (Base.lshr_int)(%42, %56)::UInt64         ││╻     >>
   │    %58 = (Base.neg_int)(%51)::Int64                ││╻     -
   │    %59 = (Base.bitcast)(UInt64, %58)::UInt64       │││╻     reinterpret
   │    %60 = (Base.shl_int)(%42, %59)::UInt64          ││╻     <<
   │    %61 = (Base.ifelse)(%55, %57, %60)::UInt64      ││    
   └───       goto #6                                   │     
46 16 ─ %63 = (Base.sle_int)(0, %13)::Bool              │╻╷    <<
   │    %64 = (Base.bitcast)(UInt64, %13)::UInt64       ││╻     unsigned
   │    %65 = (Base.shl_int)(%32, %64)::UInt64          ││╻     <<
   │    %66 = (Base.neg_int)(%13)::Int64                ││╻     -
   │    %67 = (Base.bitcast)(UInt64, %66)::UInt64       │││╻     reinterpret
   │    %68 = (Base.lshr_int)(%32, %67)::UInt64         ││╻     >>
   │    %69 = (Base.ifelse)(%63, %65, %68)::UInt64      ││    
48 │    %70 = (Base.ult_int)(0x7fffffffffffffff, %69)::Bool╷   >
   │    %71 = (Base.or_int)(false, %70)::Bool           ││╻     <
   └───       goto #18 if not %71                       │     
   17 ─       invoke %1(_2::Int64, _3::Int64)           │     
   └───       $(Expr(:unreachable))                     │     
49 18 ─ %75 = (Base.bitcast)(Int64, %69)::Int64         │╻     rem
   └───       return %75                                │     

源代码:

30 function gcd(a::T, b::T) where T<:Union{Int8,UInt8,Int16,UInt16,Int32,UInt32,Int64,UInt64,Int128,UInt128}
31    @noinline throw1(a, b) = throw(OverflowError("gcd($a, $b) overflows"))
32    a == 0 && return abs(b)
33    b == 0 && return abs(a)
34    za = trailing_zeros(a)
35    zb = trailing_zeros(b)
36    k = min(za, zb)
37    u = unsigned(abs(a >> za))
38    v = unsigned(abs(b >> zb))
39    while u != v
40        if u > v
41            u, v = v, u
42        end
43        v -= u
44        v >>= trailing_zeros(v)
45    end
46    r = u << k
47    # T(r) would throw InexactError; we want OverflowError instead
48    r > typemax(T) && throw1(a, b)
49    r % T
50 end

1 个答案:

答案 0 :(得分:2)

https://github.com/JuliaLang/julia/blob/master/base/compiler/ssair/show.jl#L170对此进行了详细说明。

总结:

  • 行数表示嵌套级别;
  • 半角线(╷)表示范围的开始,而全角线(│)表示 持续的范围;
  • 合并范围适当的行的增加的厚度表示在行之后打印输入的合并范围的启发式名称。