上記の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