上記のJulia 0.6でやったことと同じですが、Julia 1.0がリリースされたので変化があったか見てみました。
前回と同じくadd1()
を関数定義します。これはJulia 0.6でも1.0でも同じ。
julia> function add1(x) return x+1 end add1 (generic function with 1 method)
Julia 0.6では@code_llvm
と@code_native
の出力結果は以下のようになっていました。
julia> @code_llvm add1(10) define i64 @julia_add1_62318(i64) #0 !dbg !5 { top: %1 = add i64 %0, 1 ret i64 %1 } julia> @code_native add1(10) .section __TEXT,__text,regular,pure_instructions Filename: REPL[1] pushl %ebp decl %eax movl %esp, %ebp Source line: 2 decl %eax leal 1(%edi), %eax popl %ebp retl nop nop nop nop nop nop
Julia 1.0では以下のとおり。
julia> @code_llvm add1(10) ; Function add1 ; Location: REPL[1]:2 define i64 @julia_add1_35956(i64) { top: ; Function +; { ; Location: int.jl:53 %1 = add i64 %0, 1 ;} ret i64 %1 } julia> @code_native add1(10) .section __TEXT,__text,regular,pure_instructions ; Function add1 { ; Location: REPL[1]:2 ; Function +; { ; Location: REPL[1]:2 decl %eax leal 1(%edi), %eax ;} retl nopw %cs:(%eax,%eax) ;}
コメントが挟まるようになり、何をしているかが分かりやすくなりました。LLVMコードは同じままですが、ネイティブコードの見た目がだいぶ変わりました。最近のアセンブリはわからないのですが、なんとなく雰囲気からEAX(レジスタ名)、DEC(1だけ引き算)、LEA(当該アドレスを返す)、RET(プロシージャから帰る)、NOP(何もしない)あたりだと考えられます。末尾にLがついているのは64 bit(Long)、Wは任意長(Words)でしょうか? NOPを続けるのは一連の命令の合計長さを64 bitの倍数にしたいから?
ちゃんと理解しようと思うとIntelのマニュアルとか読むといいのかもしれませんね。
Intel® 64 and IA-32 Architectures Software Developer Manuals | Intel® Software