Hi,

I have been playing with inlining and I'm confused by the following - my 
inline function `foo2` is clearly less efficient than my normal function 
`foo`.

Does anyone have insight to what is going on? Would this have to do with 
running everything in Main from the REPL (so that it would be OK in 
practice)? Is the inline tag doing something else I wouldn't expect? 
Running `code_warntype` indicates both have strongly typed outputs.

Thanks,
Andy


julia> immutable Bar
          data::Tuple{Int64,Float64,Bool}
       end


julia> function foo{T}(x::T)
           x.data[1]
       end
foo (generic function with 1 method)


julia> function foo2{T}(x::T)
           Expr(:meta,:inline)
           x.data[1]
       end
foo2 (generic function with 1 method)


julia> code_native(foo,(Bar,))
.text
Filename: none
Source line: 2
pushq %rbp
movq %rsp, %rbp
Source line: 2
movq (%rdi), %rax
Source line: 2
popq %rbp
ret


julia> code_native(foo2,(Bar,))
.text
Filename: none
Source line: 2
pushq %rbp
movq %rsp, %rbp
Source line: 2
pushq %r14
pushq %rbx
subq $32, %rsp
movq $4, -48(%rbp)
movabsq $jl_pgcstack, %r14
movq (%r14), %rax
movq %rax, -40(%rbp)
leaq -48(%rbp), %rax
movq %rax, (%r14)
xorps %xmm0, %xmm0
movups %xmm0, -32(%rbp)
movq (%rdi), %rbx
movabsq $140270402987792, %rax  # imm = 0x7F933F8AE710
Source line: 2
movq %rax, -32(%rbp)
Source line: 2
leaq -32(%rbp), %rsi
Source line: 2
movabsq $jl_f_new_expr, %rax
movabsq $140270402996640, %rcx  # imm = 0x7F933F8B09A0
movq %rcx, -24(%rbp)
xorl %edi, %edi
movl $2, %edx
callq *%rax
Source line: 3
movq -40(%rbp), %rax
movq %rax, (%r14)
movq %rbx, %rax
addq $32, %rsp
popq %rbx
popq %r14
popq %rbp
ret


Also:

julia> code_llvm(foo,(bar,))

define i64 @julia_foo_26276(%bar*) {
top:
  %1 = bitcast %bar* %0 to i64*
  %2 = load i64* %1, align 8
  ret i64 %2
}


julia> code_llvm(foo2,(bar,))

define i64 @julia_foo2_26277(%bar*) {
top:
  %1 = alloca [4 x %jl_value_t*], align 8
  %.sub5 = bitcast [4 x %jl_value_t*]* %1 to %jl_value_t**
  %2 = getelementptr [4 x %jl_value_t*]* %1, i64 0, i64 2
  store %jl_value_t* inttoptr (i64 4 to %jl_value_t*), %jl_value_t** 
%.sub5, align 8
  %3 = getelementptr [4 x %jl_value_t*]* %1, i64 0, i64 1
  %4 = load %jl_value_t*** @jl_pgcstack, align 8
  %.c = bitcast %jl_value_t** %4 to %jl_value_t*
  store %jl_value_t* %.c, %jl_value_t** %3, align 8
  store %jl_value_t** %.sub5, %jl_value_t*** @jl_pgcstack, align 8
  store %jl_value_t* null, %jl_value_t** %2, align 8
  %5 = getelementptr [4 x %jl_value_t*]* %1, i64 0, i64 3
  store %jl_value_t* null, %jl_value_t** %5, align 8
  %6 = bitcast %bar* %0 to i64*
  %7 = load i64* %6, align 8
  store %jl_value_t* inttoptr (i64 140270402987792 to %jl_value_t*), 
%jl_value_t** %2, align 8
  store %jl_value_t* inttoptr (i64 140270402996640 to %jl_value_t*), 
%jl_value_t** %5, align 8
  %8 = call %jl_value_t* @jl_f_new_expr(%jl_value_t* null, %jl_value_t** 
%2, i32 2)
  %9 = load %jl_value_t** %3, align 8
  %10 = bitcast %jl_value_t* %9 to %jl_value_t**
  store %jl_value_t** %10, %jl_value_t*** @jl_pgcstack, align 8
  ret i64 %7
}


julia> code_warntype(foo,(bar,))
Variables:
  x::bar

Body:
  begin  # none, line 2:
      return 
(Base.getfield)((top(getfield))(x::bar,:data)::Tuple{Int64,Float64,Bool},1)::Int64
  end::Int64


julia> code_warntype(foo2,(bar,))
Variables:
  x::bar
  ##args#10160::Tuple{Symbol,Symbol}

Body:
  begin  # none, line 2:
      (Base._expr)(:meta,:inline)::Expr # none, line 3:
      return 
(Base.getfield)((top(getfield))(x::bar,:data)::Tuple{Int64,Float64,Bool},1)::Int64
  end::Int64

Reply via email to