Skip to content

Commit

Permalink
[GCLowering] correctly handle GC.preserve for demoted objects (JuliaL…
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Jan 6, 2020
1 parent 1878343 commit b807029
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 14 deletions.
25 changes: 14 additions & 11 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4317,20 +4317,22 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaval)
for (size_t i = 0; i < nargs; ++i) {
argv[i] = emit_expr(ctx, args[i]);
}
size_t nargsboxed = 0;
Value **vals = (Value**)alloca(sizeof(Value *) * nargs);
std::vector<Value*> vals;
for (size_t i = 0; i < nargs; ++i) {
if (!argv[i].isboxed) {
// This is intentionally not an error to allow writing
// generic code more easily.
continue;
} else if (argv[i].constant) {
const jl_cgval_t &ai = argv[i];
if (ai.constant)
continue;
if (ai.isboxed) {
vals.push_back(ai.Vboxed);
}
else if (!jl_is_pointerfree(ai.typ)) {
Type *at = julia_type_to_llvm(ai.typ);
vals.push_back(emit_unbox(ctx, at, ai, ai.typ));
}
vals[nargsboxed++] = argv[i].Vboxed;
}
Value *token = ctx.builder.CreateCall(prepare_call(gc_preserve_begin_func),
ArrayRef<Value*>(vals, nargsboxed));
Value *token = vals.empty()
? (Value*)ConstantTokenNone::get(jl_LLVMContext)
: ctx.builder.CreateCall(prepare_call(gc_preserve_begin_func), vals);
jl_cgval_t tok(token, NULL, false, (jl_value_t*)jl_void_type, NULL);
return tok;
}
Expand All @@ -4343,7 +4345,8 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaval)
}
jl_cgval_t token = emit_expr(ctx, args[0]);
assert(token.V->getType()->isTokenTy());
ctx.builder.CreateCall(prepare_call(gc_preserve_end_func), {token.V});
if (!isa<ConstantTokenNone>(token.V))
ctx.builder.CreateCall(prepare_call(gc_preserve_end_func), {token.V});
return jl_cgval_t((jl_value_t*)jl_void_type);
}
else {
Expand Down
18 changes: 15 additions & 3 deletions src/llvm-late-gc-lowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1340,9 +1340,21 @@ State LateLowerGCFrame::LocalScan(Function &F) {
Value *V = U;
if (isa<Constant>(V))
continue;
int Num = Number(S, V);
if (Num >= 0)
args.push_back(Num);
if (isa<PointerType>(V->getType())) {
if (isSpecialPtr(V->getType())) {
int Num = Number(S, V);
if (Num >= 0)
args.push_back(Num);
}
} else {
std::vector<int> Nums = NumberAll(S, V);
for (int Num : Nums) {
if (Num < 0)
continue;
if (Num >= 0)
args.push_back(Num);
}
}
}
S.GCPreserves[CI] = args;
continue;
Expand Down
24 changes: 24 additions & 0 deletions test/llvmpasses/gcroots.ll
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,30 @@ top:
ret void
}

define void @gc_preserve_vec([2 x <2 x %jl_value_t addrspace(10)*>] addrspace(11)* nocapture nonnull readonly dereferenceable(16)) {
; CHECK-LABEL: @gc_preserve_vec
; CHECK: %gcframe = alloca %jl_value_t addrspace(10)*, i32 6
top:
%ptls = call %jl_value_t*** @julia.ptls_states()
%v = load [2 x <2 x %jl_value_t addrspace(10)*>], [2 x <2 x %jl_value_t addrspace(10)*>] addrspace(11)* %0, align 8
; CHECK-DAG: [[EXTRACT11:%.*]] = extractvalue [2 x <2 x %jl_value_t addrspace(10)*>] %v, 0
; CHECK-DAG: [[EXTRACT12:%.*]] = extractvalue [2 x <2 x %jl_value_t addrspace(10)*>] %v, 0
; CHECK-DAG: [[EXTRACT21:%.*]] = extractvalue [2 x <2 x %jl_value_t addrspace(10)*>] %v, 1
; CHECK-DAG: [[EXTRACT22:%.*]] = extractvalue [2 x <2 x %jl_value_t addrspace(10)*>] %v, 1
; CHECK-DAG: [[V11:%.*]] = extractelement <2 x %jl_value_t addrspace(10)*> [[EXTRACT11]], i32 0
; CHECK-DAG: [[V12:%.*]] = extractelement <2 x %jl_value_t addrspace(10)*> [[EXTRACT12]], i32 1
; CHECK-DAG: [[V21:%.*]] = extractelement <2 x %jl_value_t addrspace(10)*> [[EXTRACT21]], i32 0
; CHECK-DAG: [[V22:%.*]] = extractelement <2 x %jl_value_t addrspace(10)*> [[EXTRACT22]], i32 1
; CHECK-DAG: store %jl_value_t addrspace(10)* [[V11]]
; CHECK-DAG: store %jl_value_t addrspace(10)* [[V12]]
; CHECK-DAG: store %jl_value_t addrspace(10)* [[V21]]
; CHECK-DAG: store %jl_value_t addrspace(10)* [[V22]]
%tok = call token (...) @llvm.julia.gc_preserve_begin([2 x <2 x %jl_value_t addrspace(10)*>] %v, i64 addrspace(10)* null, %jl_value_t*** %ptls)
call void @jl_safepoint()
ret void
}


@gv1 = external global %jl_value_t*
@gv2 = external global %jl_value_t addrspace(10)*

Expand Down

0 comments on commit b807029

Please sign in to comment.