julia - 如何正确读取 `@code_warntype`的输出?

标签 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

最佳答案

这里有详细解释https://github.com/JuliaLang/julia/blob/master/base/compiler/ssair/show.jl#L170 .

总结:

  • 行数表示嵌套级别;
  • 半角线 (╷) 表示范围的开始,全角线 (│) 表示 持续的范围;
  • 范围相应行的粗细增加表明在行后打印输入范围的启发式名称。

关于julia - 如何正确读取 `@code_warntype`的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51767230/

相关文章:

struct - 在 Julia 中为结构数组创建和赋值

julia - 在 Julia 中导航自动微分生态系统

julia - 为什么 Julia 不在条件中打印 `false`?

julia - 复合类型的子类型

dataframe - Julia 数据帧 : Create new column sum of col values :x by :y

parallel-processing - Julia 中工作人员的局部变量访问

types - 如何解决函数签名中的 "UndefVarError: T not defined"

jupyter-notebook - 更改 Julia 笔记本中的绘图窗口大小

jupyter-notebook - MethodError:没有方法匹配/(::Int64,::typeof(r)) [Julia]

arrays - 在 Julia 中仅用另一个数组的值替换数组中的零