追記(2018/9/7): 配列を含むコードをコンパイルしたい旨を追加

以下のようにJuliaの組み込み型を用いる関数をLLVM IRを経由してPTXにコンパイルしようと試みています。

Juliaにはcode_llvm関数があるので、これによってJuliaで定義された関数をLLVM IRにコンパイルしてみました:

using InteractiveUtils
function main()
  a = [1.0, 2.0]
  b = [3.0, 4.0]
  a + b
end
code_llvm(main, ())

このcode_llvmによって以下が出力されました。

define nonnull %jl_value_t addrspace(10)* @japi1_main_36013(%jl_value_t addrspace(10)*, %jl_value_t addrspace(10)**, i32) #0 {
L20:
  %3 = alloca %jl_value_t addrspace(10)*, i32 3
  %gcframe = alloca %jl_value_t addrspace(10)*, i32 4
  %4 = bitcast %jl_value_t addrspace(10)** %gcframe to i8*
  call void @llvm.memset.p0i8.i32(i8* %4, i8 0, i32 32, i32 0, i1 false)
  %5 = alloca %jl_value_t addrspace(10)**, align 8
  store volatile %jl_value_t addrspace(10)** %1, %jl_value_t addrspace(10)*** %5, align 8
  %thread_ptr = call i8* asm "movq %fs:0, $0", "=r"()
  %ptls_i8 = getelementptr i8, i8* %thread_ptr, i64 -10920
  %ptls = bitcast i8* %ptls_i8 to %jl_value_t***
  %6 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %gcframe, i32 0
  %7 = bitcast %jl_value_t addrspace(10)** %6 to i64*
  store i64 4, i64* %7
  %8 = getelementptr %jl_value_t**, %jl_value_t*** %ptls, i32 0
  %9 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %gcframe, i32 1
  %10 = bitcast %jl_value_t addrspace(10)** %9 to %jl_value_t***
  %11 = load %jl_value_t**, %jl_value_t*** %8
  store %jl_value_t** %11, %jl_value_t*** %10
  %12 = bitcast %jl_value_t*** %8 to %jl_value_t addrspace(10)***
  store %jl_value_t addrspace(10)** %gcframe, %jl_value_t addrspace(10)*** %12
  %13 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %3, i32 0
  store %jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 139958353891376 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %13
  %14 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %3, i32 1
  store %jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 139958353891392 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %14
  %15 = call nonnull %jl_value_t addrspace(10)* @jsys1_vect_30114(%jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 139958473544592 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %3, i32 2)
  %16 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %gcframe, i32 3
  store %jl_value_t addrspace(10)* %15, %jl_value_t addrspace(10)** %16
  %17 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %3, i32 0
  store %jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 139958353891408 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %17
  %18 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %3, i32 1
  store %jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 139958353891424 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %18
  %19 = call nonnull %jl_value_t addrspace(10)* @jsys1_vect_30114(%jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 139958473544592 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %3, i32 2)
  %20 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %gcframe, i32 2
  store %jl_value_t addrspace(10)* %19, %jl_value_t addrspace(10)** %20
  %21 = call [1 x { i64 }] @julia_promote_shape_36014(%jl_value_t addrspace(10)* nonnull %15, %jl_value_t addrspace(10)* nonnull %19)
  %22 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %3, i32 0
  store %jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 139958447711088 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %22
  %23 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %3, i32 1
  store %jl_value_t addrspace(10)* %15, %jl_value_t addrspace(10)** %23
  %24 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %3, i32 2
  store %jl_value_t addrspace(10)* %19, %jl_value_t addrspace(10)** %24
  %25 = call nonnull %jl_value_t addrspace(10)* @japi1_broadcast_36015(%jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 139958447688464 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %3, i32 3)
  %26 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %gcframe, i32 1
  %27 = load %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %26
  %28 = getelementptr %jl_value_t**, %jl_value_t*** %ptls, i32 0
  %29 = bitcast %jl_value_t*** %28 to %jl_value_t addrspace(10)**
  store %jl_value_t addrspace(10)* %27, %jl_value_t addrspace(10)** %29
  ret %jl_value_t addrspace(10)* %25
}

しかしこれをllcで処理しようとすると

$ llc -march=nvptx64 -mcpu=sm_50 add.ll
llc: add.ll:4:16: error: use of undefined type named 'jl_value_t'
define nonnull %jl_value_t addrspace(10)* @japi1_main_36013(%jl_value_t addrspace(10)*, %jl_value_t addrspace(10)**, i32) #0 {

のように定義が足りてないようです。どうすればコンパイルできるIRを得ることができますか?

  • julia version 1.0.0
  • LLVM version 6.0.1