Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle gc_preserve in lifetime marker insertion #23837

Merged
merged 1 commit into from
Sep 26, 2017
Merged

Conversation

yuyichao
Copy link
Contributor

@yuyichao yuyichao commented Sep 23, 2017

In this case, the lifetime is not just determined by the instructions we see anymore.
We need to extend the use list based on domination information before deciding which block has no use of the allocation.

@yuyichao yuyichao added the bugfix This change fixes an existing bug label Sep 23, 2017
@yuyichao yuyichao requested a review from Keno September 23, 2017 01:47
@yuyichao
Copy link
Contributor Author

yuyichao commented Sep 23, 2017

The issue can be seen here,

julia> function f()
           ref0 = Ref{UInt32}(0)
           Base.@gc_preserve ref0 ccall(:jl_breakpoint, Void, (Ref{Ptr{Void}},),
                                        Ref{Ptr{Void}}(pointer_from_objref(ref0)))
       end
f (generic function with 1 method)

julia> @code_llvm f()
; Function f
; Location: REPL[1]
define %jl_value_t addrspace(10)* @japi1_f_64085(%jl_value_t addrspace(10)*, %jl_value_t addrspace(10)**, i32) #0 {
L14:
  %3 = alloca i64, align 8
  %4 = alloca i32, align 4
  %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
  %6 = bitcast i32* %4 to i8*
  %7 = bitcast i64* %3 to i8*
  call void @llvm.lifetime.start.p0i8(i64 4, i8* %6)
; Location: REPL[1]:2
  store i32 0, i32* %4, align 4
  %8 = ptrtoint i32* %4 to i64
  call void @llvm.lifetime.start.p0i8(i64 8, i8* %7)
; Location: REPL[1]:3
; Function macro expansion; {
; Location: pointer.jl:169
  store i64 %8, i64* %3, align 8
  call void inttoptr (i64 139985854009568 to void (i8*)*)(i8* %7)
;}
  ret %jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 139985567744008 to %jl_value_t*) to %jl_value_t addrspace(10)*)
}

The allocation optimization incorrectly determined that the allocation after the gc_preserve_begin, which is the last visible use of the first allocation, marks the end of the lifetime. With this patch, we get

; Function f
; Location: REPL[1]
define %jl_value_t addrspace(10)* @japi1_f_64028(%jl_value_t addrspace(10)*, %jl_value_t addrspace(10)**, i32) #0 {
L14:
  %3 = alloca i64, align 8
  %4 = alloca i32, align 4
  %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
  %6 = bitcast i64* %3 to i8*
; Location: REPL[1]:2
  store i32 0, i32* %4, align 4
  %7 = ptrtoint i32* %4 to i64
  call void @llvm.lifetime.start.p0i8(i64 8, i8* %6)
; Location: REPL[1]:3
; Function macro expansion; {
; Location: pointer.jl:169
  store i64 %7, i64* %3, align 8
  call void inttoptr (i64 139892293033712 to void (i8*)*)(i8* %6)
;}
  ret %jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 139892005834760 to %jl_value_t*) to %jl_value_t addrspace(10)*)
}

instead.

@yuyichao yuyichao added the compiler:codegen Generation of LLVM IR and native code label Sep 23, 2017
@yuyichao
Copy link
Contributor Author

Actually it turns out that implementing the correct version is faster than waiting for the CI... So here it is...

@yuyichao yuyichao changed the title Disable lifetime marker when there's gc_preserve Handle gc_preserve in lifetime marker insertion Sep 23, 2017
In this case, the lifetime is not just determined by the instructions we see anymore.
We need to extend the use list based on domination information before deciding which block
has no use of the allocation.
@yuyichao yuyichao merged commit 28c49b7 into master Sep 26, 2017
@yuyichao yuyichao deleted the yyc/codegen/alloc branch September 26, 2017 16:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugfix This change fixes an existing bug compiler:codegen Generation of LLVM IR and native code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant