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

Get rid of legacy gc use markers #22419

Merged
merged 1 commit into from
Jun 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 3 additions & 23 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,6 @@ static Value *julia_to_address(Type *to, jl_value_t *jlto, jl_unionall_t *jlto_e
data_pointer(jvinfo, ctx, slot->getType()),
(uint64_t)jl_datatype_size(ety),
(uint64_t)jl_datatype_align(ety));
mark_gc_use(jvinfo);
}
if (slot->getType() != to)
slot = emit_bitcast(slot, to);
Expand Down Expand Up @@ -642,7 +641,6 @@ static Value *julia_to_native(Type *to, bool toboxed, jl_value_t *jlto, jl_union
data_pointer(jvinfo, ctx, slot->getType()),
(uint64_t)jl_datatype_size(jlto),
(uint64_t)jl_datatype_align(jlto));
mark_gc_use(jvinfo);
}
return slot;
}
Expand Down Expand Up @@ -1021,7 +1019,6 @@ static jl_cgval_t emit_llvmcall(jl_value_t **args, size_t nargs, jl_codectx_t *c

Value *v = julia_to_native(t, toboxed, tti, NULL, arg, false, i, ctx, NULL);
bool issigned = jl_signed_type && jl_subtype(tti, (jl_value_t*)jl_signed_type);
// make sure args are rooted
argvals[i] = llvm_type_rewrite(v, t, issigned, ctx);
}

Expand Down Expand Up @@ -1134,22 +1131,9 @@ static jl_cgval_t emit_llvmcall(jl_value_t **args, size_t nargs, jl_codectx_t *c
f->setLinkage(GlobalValue::LinkOnceODRLinkage);
}

// the actual call
builder.CreateCall(prepare_call(gcroot_flush_func));
SmallVector<Value*, 16> gc_uses;
for (size_t i = 0; i < nargt; ++i) {
const jl_cgval_t &arg = argv[i];
push_gc_use(gc_uses, arg);
}
// Mark GC use before **and** after the llvmcall to make sure the arguments
// are alive during the llvmcall even if the llvmcall has `unreachable`.
// If the llvmcall generates GC safepoint, it might need to emit its own
// gckill.
mark_gc_uses(gc_uses);
CallInst *inst = builder.CreateCall(f, ArrayRef<Value*>(&argvals[0], nargt));
if (isString)
f->addFnAttr(Attribute::AlwaysInline);
mark_gc_uses(gc_uses);

JL_GC_POP();

Expand Down Expand Up @@ -1859,14 +1843,15 @@ static jl_cgval_t emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)

jl_cgval_t &arg = argv[ai];
arg = emit_expr((jl_value_t*)argi, ctx);
push_gc_use(gc_uses, arg);

// Julia (expression) value of current parameter gcroot
jl_value_t *argi_root = args[i + 1];
if (jl_is_long(argi_root))
continue;
jl_cgval_t arg_root = emit_expr(argi_root, ctx);
push_gc_use(gc_uses, arg_root);
Value *gcuse = arg_root.gcroot ? builder.CreateLoad(arg_root.gcroot) : arg_root.V;
if (gcuse)
gc_uses.push_back(gcuse);
}

function_sig_t sig(lrt, rt, retboxed, (jl_svec_t*)at, unionall, (nargs - 3) / 2, isVa, cc, llvmcall);
Expand Down Expand Up @@ -2079,9 +2064,6 @@ jl_cgval_t function_sig_t::emit_a_ccall(
}
}

// Mark GC use before **and** after the ccall to make sure the arguments
// are alive during the ccall even if the function called is `noreturn`.
mark_gc_uses(gc_uses);
OperandBundleDef OpBundle("jl_roots", gc_uses);
// the actual call
Value *ret = builder.CreateCall(prepare_call(llvmf),
Expand All @@ -2101,9 +2083,7 @@ jl_cgval_t function_sig_t::emit_a_ccall(
ctx->f->addFnAttr(Attribute::StackProtectReq);
}

mark_gc_uses(gc_uses);
if (rt == jl_bottom_type) {
// Do this after we marked all the GC uses.
CreateTrap(builder);
return jl_cgval_t();
}
Expand Down
11 changes: 1 addition & 10 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2099,10 +2099,6 @@ static Value *box_union(const jl_cgval_t &vinfo, jl_codectx_t *ctx, const SmallB
builder.CreateUnreachable();
}
else {
if (vinfo.gcroot && vinfo.V != vinfo.gcroot) {
// if this is a derived pointer, make sure the root usage itself is also visible to the delete-root pass
mark_gc_use(vinfo);
}
// We're guaranteed here that Load(.gcroot) == .V, because we have determined
// that this union is a boxed value, rather than an interior pointer of some sort
box_merge->addIncoming(builder.CreateLoad(vinfo.gcroot), defaultBB);
Expand Down Expand Up @@ -2216,10 +2212,6 @@ static void emit_unionmove(Value *dest, const jl_cgval_t &src, Value *skip, bool
builder.CreateBr(postBB);
}
builder.SetInsertPoint(postBB);
if (src.gcroot && src.V != src.gcroot) {
// if this is a derived pointer, make sure the root usage itself is also visible to the delete-root pass
mark_gc_use(src);
}
}
else {
Value *datatype = emit_typeof_boxed(src, ctx);
Expand Down Expand Up @@ -2331,11 +2323,10 @@ static void emit_setfield(jl_datatype_t *sty, const jl_cgval_t &strct, size_t id
ConstantInt::get(T_size, jl_field_offset(sty, idx0)));
jl_value_t *jfty = jl_svecref(sty->types, idx0);
if (jl_field_isptr(sty, idx0)) {
Value *r = maybe_decay_untracked(boxed(rhs, ctx, false)); // don't need a temporary gcroot since it'll be rooted by strct (but should ensure strct is rooted via mark_gc_use)
Value *r = maybe_decay_untracked(boxed(rhs, ctx, false)); // don't need a temporary gcroot since it'll be rooted by strct
tbaa_decorate(strct.tbaa, builder.CreateStore(r,
emit_bitcast(addr, T_pprjlvalue)));
if (wb && strct.isboxed) emit_checked_write_barrier(ctx, boxed(strct, ctx), r);
mark_gc_use(strct);
}
else {
int align = jl_field_offset(sty, idx0);
Expand Down
57 changes: 0 additions & 57 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,9 +354,6 @@ static Function *jlarray_data_owner_func;
static GlobalVariable *jlgetworld_global;

// placeholder functions
static Function *gcroot_func;
static Function *gckill_func;
static Function *jlcall_frame_func;
static Function *gcroot_flush_func;
static Function *except_enter_func;
static Function *pointer_from_objref_func;
Expand Down Expand Up @@ -573,7 +570,6 @@ class jl_codectx_t {
static jl_cgval_t emit_expr(jl_value_t *expr, jl_codectx_t *ctx);

static Value *emit_local_root(jl_codectx_t *ctx, jl_varinfo_t *vi = NULL);
static void mark_gc_use(const jl_cgval_t &v);
static Value *global_binding_pointer(jl_module_t *m, jl_sym_t *s,
jl_binding_t **pbnd, bool assign, jl_codectx_t *ctx);
static jl_cgval_t emit_checked_var(Value *bp, jl_sym_t *name, jl_codectx_t *ctx, bool isvol, MDNode *tbaa);
Expand All @@ -589,21 +585,6 @@ static Value *emit_jlcall(Value *theFptr, Value *theF, jl_cgval_t *args,
static Value *emit_jlcall(Value *theFptr, Value *theF, jl_value_t **args,
size_t nargs, jl_codectx_t *ctx);

template<typename T> static void push_gc_use(T &&vec, const jl_cgval_t &v)
{
if (v.gcroot) {
vec.push_back(v.gcroot);
}
}

template<typename T> static void mark_gc_uses(T &&vec)
{
auto f = prepare_call(gckill_func);
for (auto &v: vec) {
builder.CreateCall(f, v);
}
}

// --- convenience functions for tagging llvm values with julia types ---

static GlobalVariable *get_pointer_to_constant(Constant *val, StringRef name, Module &M)
Expand Down Expand Up @@ -987,9 +968,6 @@ static jl_cgval_t convert_julia_type(const jl_cgval_t &v, jl_value_t *typ, jl_co
}
builder.CreateStore(newroot, froot);
}
else {
mark_gc_use(v);
}
if (v.V == NULL) {
// v.V might be NULL if it was all ghost objects before
return jl_cgval_t(boxv, froot, false, typ, new_tindex);
Expand Down Expand Up @@ -2212,17 +2190,6 @@ static Value *emit_local_root(jl_codectx_t *ctx, jl_varinfo_t *vi)
return newroot;
}


// Marks a use (and thus a potential kill) of a gcroot
// Note that if the operation that needs the root has terminating control flow
// (e.g. `unreachable`, `noreturn` functions) the use needs to be marked before
// the operation as well as after it.
static void mark_gc_use(const jl_cgval_t &v)
{
if (v.gcroot)
builder.CreateCall(prepare_call(gckill_func), v.gcroot);
}

static void jl_add_method_root(jl_codectx_t *ctx, jl_value_t *val)
{
if (jl_is_leaf_type(val) || jl_is_bool(val) || jl_is_symbol(val) ||
Expand Down Expand Up @@ -2470,8 +2437,6 @@ static bool emit_builtin_call(jl_cgval_t *ret, jl_value_t *f, jl_value_t **args,
v2 = update_julia_type(v2, expr_type(args[2], ctx), ctx); // patch up typ if necessary
// emit comparison test
Value *ans = emit_f_is(v1, v2, ctx);
mark_gc_use(v1);
mark_gc_use(v2);
*ret = mark_julia_type(builder.CreateZExt(ans, T_int8), false, jl_bool_type, ctx);
JL_GC_POP();
return true;
Expand Down Expand Up @@ -3097,7 +3062,6 @@ static jl_cgval_t emit_call_function_object(jl_method_instance_t *li, const jl_c
break;
}

SmallVector<Value*, 16> gc_uses;
for (size_t i = 0; i < nargs + 1; i++) {
jl_value_t *jt = jl_nth_slot_type(li->specTypes, i);
bool isboxed;
Expand All @@ -3121,7 +3085,6 @@ static jl_cgval_t emit_call_function_object(jl_method_instance_t *li, const jl_c
jl_cgval_t arg = i == 0 ? theF : emit_expr(args[i], ctx);
assert(arg.ispointer());
argvals[idx] = decay_derived(data_pointer(arg, ctx, at));
push_gc_use(gc_uses, arg);
}
else {
assert(at == et);
Expand All @@ -3133,10 +3096,8 @@ static jl_cgval_t emit_call_function_object(jl_method_instance_t *li, const jl_c
idx++;
}
assert(idx == nfargs);
mark_gc_uses(gc_uses);
CallInst *call = builder.CreateCall(returninfo.decl, ArrayRef<Value*>(&argvals[0], nfargs));
call->setAttributes(returninfo.decl->getAttributes());
mark_gc_uses(gc_uses);

jl_cgval_t retval;
switch (returninfo.cc) {
Expand Down Expand Up @@ -6739,24 +6700,6 @@ static void init_julia_llvm_env(Module *m)
#endif
add_named_global(jlarray_data_owner_func, jl_array_data_owner);

gcroot_func =
Function::Create(FunctionType::get(T_pprjlvalue, false),
Function::ExternalLinkage,
"julia.gc_root_decl");
add_named_global(gcroot_func, (void*)NULL, /*dllimport*/false);

gckill_func =
Function::Create(FunctionType::get(T_void, ArrayRef<Type*>(T_pprjlvalue), false),
Function::ExternalLinkage,
"julia.gc_root_kill");
add_named_global(gckill_func, (void*)NULL, /*dllimport*/false);

jlcall_frame_func =
Function::Create(FunctionType::get(T_pprjlvalue, ArrayRef<Type*>(T_int32), false),
Function::ExternalLinkage,
"julia.jlcall_frame_decl");
add_named_global(jlcall_frame_func, (void*)NULL, /*dllimport*/false);

gcroot_flush_func = Function::Create(FunctionType::get(T_void, false),
Function::ExternalLinkage,
"julia.gcroot_flush");
Expand Down
6 changes: 0 additions & 6 deletions src/intrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +307,6 @@ static Value *emit_unbox(Type *to, const jl_cgval_t &x, jl_value_t *jt, Value *d
return NULL;
}

// if this is a derived pointer, make sure the root usage itself is also visible to the delete-root pass
if (x.gcroot && x.V != x.gcroot)
mark_gc_use(x);

// bools stored as int8, so an extra Trunc is needed to get an int1
Value *p = x.constant ? literal_pointer_val(x.constant) : x.V;
Type *ptype = (to == T_int1 ? T_pint8 : to->getPointerTo());
Expand Down Expand Up @@ -839,8 +835,6 @@ static jl_cgval_t emit_intrinsic(intrinsic f, jl_value_t **args, size_t nargs,
boxed(x, ctx));
}
jl_value_t *jt = (t1 == t2 ? t1 : (jl_value_t*)jl_any_type);
mark_gc_use(x);
mark_gc_use(y);
return mark_julia_type(ifelse_result, isboxed, jt, ctx);
}

Expand Down
5 changes: 1 addition & 4 deletions src/llvm-late-gc-lowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,6 @@ struct LateLowerGCFrame: public FunctionPass {
Type *T_size;
Type *T_int32;
MDNode *tbaa_gcframe;
Function *gc_kill_func;
Function *ptls_getter;
Function *gc_flush_func;
Function *pointer_from_objref_func;
Expand Down Expand Up @@ -1023,8 +1022,7 @@ bool LateLowerGCFrame::CleanupIR(Function &F) {
continue;
}
CallingConv::ID CC = CI->getCallingConv();
if ((gc_kill_func != nullptr && CI->getCalledFunction() == gc_kill_func) ||
(gc_flush_func != nullptr && CI->getCalledFunction() == gc_flush_func)) {
if (gc_flush_func != nullptr && CI->getCalledFunction() == gc_flush_func) {
/* No replacement */
} else if (pointer_from_objref_func != nullptr &&
CI->getCalledFunction() == pointer_from_objref_func) {
Expand Down Expand Up @@ -1201,7 +1199,6 @@ void LateLowerGCFrame::PlaceRootsAndUpdateCalls(Function &F, std::vector<int> &C

bool LateLowerGCFrame::doInitialization(Module &M) {
ptls_getter = M.getFunction("jl_get_ptls_states");
gc_kill_func = M.getFunction("julia.gc_root_kill");
gc_flush_func = M.getFunction("julia.gcroot_flush");
pointer_from_objref_func = M.getFunction("julia.pointer_from_objref");
return false;
Expand Down