使用数组时的Julia llvm函数签名

使用数组时的Julia llvm函数签名,llvm,julia,llvm-ir,Llvm,Julia,Llvm Ir,当查看julia编译器生成的LLVM IR(使用code\LLVM)时,我注意到当使用数组作为参数时,函数签名中有一些奇怪的东西。让我举一个例子: function test(a,b,c) return nothing end (这是一个无用的示例,但结果与其他函数相同,此示例的结果IR只是不那么混乱) 使用code\ulvm(test,(Int,Int,Int)),我得到以下输出: ; Function Attrs: sspreq define void @julia_test148

当查看julia编译器生成的LLVM IR(使用
code\LLVM
)时,我注意到当使用数组作为参数时,函数签名中有一些奇怪的东西。让我举一个例子:

function test(a,b,c)
    return nothing
end
(这是一个无用的示例,但结果与其他函数相同,此示例的结果IR只是不那么混乱)

使用
code\ulvm(test,(Int,Int,Int))
,我得到以下输出:

; Function Attrs: sspreq
define void @julia_test14855(i64, i64, i64) #2 {
top:
  ret void, !dbg !366
}
使用
code_llvm(test,(Array{Int},Array{Int},Array{Int}))
,我得到了一个(至少对我来说)意外的结果:

; Function Attrs: sspreq
define %jl_value_t* @julia_test14856(%jl_value_t*, %jl_value_t**, i32) #2 {
top:
  %3 = icmp eq i32 %2, 3, !dbg !369
  br i1 %3, label %ifcont, label %else, !dbg !369

else:                                             ; preds = %top
  call void @jl_error(i8* getelementptr inbounds ([26 x i8]* @_j_str0, i64 0, i64 0)), !dbg !369
  unreachable, !dbg !369

ifcont:                                           ; preds = %top
  %4 = load %jl_value_t** inttoptr (i64 36005472 to %jl_value_t**), align 32, !dbg !370
  ret %jl_value_t* %4, !dbg !370
}

为什么llvm函数的签名不只是将3个变量列为
i64*
之类的东西?为什么函数不再返回
void

我假设这是因为
数组{Int,N}
是一个部分初始化的类型,并且它与代码生成所寻找的模式不匹配

也试试

julia> code_llvm(test, (Array{Int,1},Array{Int,1},Array{Int,1}))

define void @julia_test15626(%jl_value_t*, %jl_value_t*, %jl_value_t*) {
top:
  ret void, !dbg !974
}

这可能被认为是代码生成中的一个错误,但我不知道。

为什么llvm函数的签名不只是将3个变量列为i64*

这个签名是通用的Julia调用约定(因为,正如@ivarne所提到的,类型是不完整的)

@julia\u test14856(%jl\u value\u t*,%jl\u value\u t**,i32)
参数为:

  • 指向函数闭包的指针
  • 指向装箱参数的指针(jl_value_t是基本的装箱类型)
  • 参数数
  • @ivarne显示的签名是专门的呼叫约定。参数仍然以盒装形式传递,但参数类型和计数已经已知(函数闭包是不必要的,因为它已经被专门化了)

    关于示例函数的输出,本节检查参数的数量(如果不是3->goto label
    else:
    ):

    本节返回错误:

    else:                                             ; preds = %top
      call void @jl_error(i8* getelementptr inbounds ([26 x i8]* @_j_str0, i64 0, i64 0)), !dbg !369
      unreachable, !dbg !369
    
    最后,默认情况转到这一行,它提取存储在地址
    36005472
    中的
    nothing
    的值(在@ivarne版本中,这是有保证的,因此可以直接返回
    void


    %4=加载%jl\u值**inttoptr(i64 36005472到%jl\u值**),对齐32!dbg!370

    谢谢。很高兴看到我的直觉指引我走向正确的方向。
    else:                                             ; preds = %top
      call void @jl_error(i8* getelementptr inbounds ([26 x i8]* @_j_str0, i64 0, i64 0)), !dbg !369
      unreachable, !dbg !369