Skip to content

Commit

Permalink
Merge pull request #24416 from JuliaLang/yyc/codegen/alloc
Browse files Browse the repository at this point in the history
Improve allocation optimization with gc_preserve intrinsics
  • Loading branch information
yuyichao authored Nov 1, 2017
2 parents 9b5d1e4 + 328680e commit a62ca27
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/llvm-alloc-opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -606,13 +606,24 @@ void AllocOpt::replaceUsesWith(Instruction *orig_inst, Instruction *new_inst,
call->eraseFromParent();
return;
}
// Also remove the preserve intrinsics so that it can be better optimized.
if (gc_preserve_begin && gc_preserve_begin == call->getCalledFunction()) {
while (!call->use_empty()) {
auto end = cast<Instruction>(*call->user_begin());
// gc_preserve_end returns void.
assert(end->use_empty());
end->eraseFromParent();
}
call->eraseFromParent();
return;
}
if (auto intrinsic = dyn_cast<IntrinsicInst>(call)) {
if (Intrinsic::ID ID = intrinsic->getIntrinsicID()) {
replaceIntrinsicUseWith(intrinsic, ID, orig_i, new_i);
return;
}
}
// remove from operand bundle or arguments for gc_perserve_begin
// remove from operand bundle
Type *orig_t = orig_i->getType();
user->replaceUsesOfWith(orig_i, ConstantPointerNull::get(cast<PointerType>(orig_t)));
}
Expand Down
57 changes: 57 additions & 0 deletions test/llvmpasses/alloc-opt2.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# RUN: julia --startup-file=no %s | opt -load libjulia.so -AllocOpt -S - | FileCheck %s

isz = sizeof(UInt) == 8 ? "i64" : "i32"

println("""
%jl_value_t = type opaque
@tag = external addrspace(10) global %jl_value_t
""")

# Test that the gc_preserve intrinsics are deleted directly.

# CHECK-LABEL: @preserve_branches
# CHECK: alloca i64
# CHECK: call %jl_value_t*** @julia.ptls_states()
# CHECK: L1:
# CHECK-NEXT: call void @llvm.lifetime.start{{.*}}(i64 8,
# CHECK-NEXT: @external_function()
# CHECK-NEXT: br i1 %b2, label %L2, label %L3

# CHECK: L2:
# CHECK-NOT: call void @llvm.lifetime.end{{.*}}(i64 8,
# CHECK: @external_function()
# CHECK-NEXT: br label %L3

# CHECK: L3:
# CHECK-NEXT: call void @llvm.lifetime.end{{.*}}(i64 8,
println("""
define void @preserve_branches(i8* %fptr, i1 %b, i1 %b2) {
%ptls = call %jl_value_t*** @julia.ptls_states()
%ptls_i8 = bitcast %jl_value_t*** %ptls to i8*
br i1 %b, label %L1, label %L3
L1:
%v = call noalias %jl_value_t addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, $isz 8, %jl_value_t addrspace(10)* @tag)
%tok = call token (...) @llvm.julia.gc_preserve_begin(%jl_value_t addrspace(10)* %v)
call void @external_function()
br i1 %b2, label %L2, label %L3
L2:
call void @external_function()
br label %L3
L3:
ret void
}
""")
# CHECK-LABEL: }

println("""
declare void @external_function()
declare %jl_value_t*** @julia.ptls_states()
declare noalias %jl_value_t addrspace(10)* @julia.gc_alloc_obj(i8*, $isz, %jl_value_t addrspace(10)*)
declare i64 @julia.pointer_from_objref(%jl_value_t addrspace(11)*)
declare void @llvm.memcpy.p11i8.p0i8.i64(i8 addrspace(11)* nocapture writeonly, i8* nocapture readonly, i64, i32, i1)
declare token @llvm.julia.gc_preserve_begin(...)
declare void @llvm.julia.gc_preserve_end(token)
""")

1 comment on commit a62ca27

@nanosoldier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Executing the daily benchmark build, I will reply here when finished:

@nanosoldier runbenchmarks(ALL, isdaily = true)

Please sign in to comment.