Thank you Mike for clearing that up. Actually, the docs say @inline simply 
inserts that :meta: http://docs.julialang.org/en/release-0.4/devdocs/meta/. 
Maybe that's too simplistic.

Actually, I *was* looking at this because I wanted to make inline generated 
functions and see how they behave with code_native/code_llvm. But as you 
can see 
from https://groups.google.com/forum/#!topic/julia-users/4pkWhcap1Zg I have 
been struggling to see the code from generated functions, so I did as Tim 
Holy suggested and stuck the code into a function and saw how it compiled 
(since I couldn't figure out another way). I'm assuming including the 
Expr(:meta,:inline) is the correct thing to do for generated functions?

Andy



On Thursday, February 11, 2016 at 5:46:40 PM UTC+10, Michael Hatherly wrote:
>
> Manually adding an Expr(:meta, :inline) to the function is not equivalent 
> to using @inline since it does not “splice” it into the function’s ast 
> but rather just creates a new Expr object at runtime each time the 
> function is called. Have a look at the difference in code_typed output 
> between foo2 and the following function
>
> @inline function foo3{T}(x::T)
>     x.data[1]
> end
>
> julia> code_warntype(foo3, (Bar,))
> Variables:
>   #self#::#foo3
>   x::Bar
>
> Body:
>   begin 
>       $(Expr(:meta, :inline)) # none, line 2:
>       return 
> (Base.getfield)((top(getfield))(x::Bar,:data)::Tuple{Int64,Float64,Bool},1)::Int64
>   end::Int64
>
> You should always use @inline unless you’re manually building an entire 
> Expr to be returned by a macro or generated function.
>
> — Mike
> ​
>
> On Thursday, 11 February 2016 08:37:17 UTC+2, Andy Ferris wrote:
>>
>> 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