Skip to content

Commit

Permalink
codegen: Respect binding partition
Browse files Browse the repository at this point in the history
Minor changes to make codegen correct in the face of partitioned constant
bindings. Does not yet handle the envisioned semantics for globals
that change restriction type, which will require a fair bit of additional
work.
  • Loading branch information
Keno committed Nov 7, 2024
1 parent 8593792 commit af68d7d
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 15 deletions.
42 changes: 27 additions & 15 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3435,26 +3435,33 @@ static jl_value_t *jl_ensure_rooted(jl_codectx_t &ctx, jl_value_t *val)

// --- generating function calls ---

static jl_cgval_t emit_globalref_runtime(jl_codectx_t &ctx, jl_binding_t *bnd, jl_module_t *mod, jl_sym_t *name)
{
Value *bp = julia_binding_gv(ctx, bnd);
Value *v = ctx.builder.CreateCall(prepare_call(jlgetbindingvalue_func), { bp });
undef_var_error_ifnot(ctx, ctx.builder.CreateIsNotNull(v), name, (jl_value_t*)mod);
return mark_julia_type(ctx, v, true, jl_any_type);
}

static jl_cgval_t emit_globalref(jl_codectx_t &ctx, jl_module_t *mod, jl_sym_t *name, AtomicOrdering order)
{
jl_binding_t *bnd = jl_get_module_binding(mod, name, 1);
jl_binding_partition_t *bpart = jl_get_binding_partition(bnd, ctx.max_world);
assert(bnd);
jl_binding_partition_t *bpart = jl_get_binding_partition_all(bnd, ctx.min_world, ctx.max_world);
if (!bpart) {
return emit_globalref_runtime(ctx, bnd, mod, name);
}
jl_ptr_kind_union_t pku = jl_atomic_load_relaxed(&bpart->restriction);
if (jl_bkind_is_some_guard(decode_restriction_kind(pku))) {
// try to look this up now.
// TODO: This is bad and we'd like to delete it.
jl_get_binding(mod, name);
}
assert(bnd);
Value *bp = NULL;
// bpart was updated in place - this will change with full partition
pku = jl_atomic_load_acquire(&bpart->restriction);
if (jl_bkind_is_some_guard(decode_restriction_kind(pku))) {
// Redo the lookup at runtime
bp = julia_binding_gv(ctx, bnd);
Value *v = ctx.builder.CreateCall(prepare_call(jlgetbindingvalue_func), { bp });
undef_var_error_ifnot(ctx, ctx.builder.CreateIsNotNull(v), name, (jl_value_t*)mod);
return mark_julia_type(ctx, v, true, jl_any_type);
return emit_globalref_runtime(ctx, bnd, mod, name);
} else {
while (true) {
if (!bpart)
Expand All @@ -3465,7 +3472,9 @@ static jl_cgval_t emit_globalref(jl_codectx_t &ctx, jl_module_t *mod, jl_sym_t *
cg_bdw(ctx, name, bnd);
}
bnd = (jl_binding_t*)decode_restriction_value(pku);
bpart = jl_get_binding_partition(bnd, ctx.max_world);
bpart = jl_get_binding_partition_all(bnd, ctx.min_world, ctx.max_world);
if (!bpart)
break;
pku = jl_atomic_load_acquire(&bpart->restriction);
}
if (bpart && jl_bkind_is_some_constant(decode_restriction_kind(pku))) {
Expand All @@ -3477,7 +3486,10 @@ static jl_cgval_t emit_globalref(jl_codectx_t &ctx, jl_module_t *mod, jl_sym_t *
return mark_julia_const(ctx, constval);
}
}
bp = julia_binding_gv(ctx, bnd);
if (!bpart) {
return emit_globalref_runtime(ctx, bnd, mod, name);
}
Value *bp = julia_binding_gv(ctx, bnd);
if (bnd->deprecated) {
cg_bdw(ctx, name, bnd);
}
Expand All @@ -3496,7 +3508,7 @@ static jl_cgval_t emit_globalop(jl_codectx_t &ctx, jl_module_t *mod, jl_sym_t *s
{
jl_binding_t *bnd = NULL;
Value *bp = global_binding_pointer(ctx, mod, sym, &bnd, true, alloc);
jl_binding_partition_t *bpart = jl_get_binding_partition(bnd, ctx.max_world);
jl_binding_partition_t *bpart = jl_get_binding_partition_all(bnd, ctx.min_world, ctx.max_world);
if (bp == NULL)
return jl_cgval_t();
if (bpart) {
Expand Down Expand Up @@ -5854,7 +5866,7 @@ static Value *global_binding_pointer(jl_codectx_t &ctx, jl_module_t *m, jl_sym_t
jl_binding_t **pbnd, bool assign, bool alloc)
{
jl_binding_t *b = jl_get_module_binding(m, s, 1);
jl_binding_partition_t *bpart = jl_get_binding_partition(b, ctx.max_world);
jl_binding_partition_t *bpart = jl_get_binding_partition_all(b, ctx.min_world, ctx.max_world);
jl_ptr_kind_union_t pku = jl_atomic_load_relaxed(&bpart->restriction);
if (assign) {
if (jl_bkind_is_some_guard(decode_restriction_kind(pku)))
Expand All @@ -5865,11 +5877,11 @@ static Value *global_binding_pointer(jl_codectx_t &ctx, jl_module_t *m, jl_sym_t
if (jl_bkind_is_some_guard(decode_restriction_kind(pku))) {
// try to look this up now
b = jl_get_binding(m, s);
bpart = jl_get_binding_partition(b, ctx.max_world);
bpart = jl_get_binding_partition_all(b, ctx.min_world, ctx.max_world);
}
pku = jl_walk_binding_inplace(&b, &bpart, ctx.max_world);
pku = jl_walk_binding_inplace_all(&b, &bpart, ctx.min_world, ctx.max_world);
}
if (b == NULL) {
if (!b || !bpart) {
// var not found. switch to delayed lookup.
Constant *initnul = Constant::getNullValue(ctx.types().T_pjlvalue);
GlobalVariable *bindinggv = new GlobalVariable(*ctx.f->getParent(), ctx.types().T_pjlvalue,
Expand Down Expand Up @@ -6021,7 +6033,7 @@ static jl_cgval_t emit_isdefined(jl_codectx_t &ctx, jl_value_t *sym, int allow_i
name = (jl_sym_t*)sym;
}
jl_binding_t *bnd = allow_import ? jl_get_binding(modu, name) : jl_get_module_binding(modu, name, 0);
jl_binding_partition_t *bpart = jl_get_binding_partition(bnd, ctx.min_world);
jl_binding_partition_t *bpart = jl_get_binding_partition_all(bnd, ctx.min_world, ctx.max_world);
jl_ptr_kind_union_t pku = bpart ? jl_atomic_load_relaxed(&bpart->restriction) : encode_restriction(NULL, BINDING_KIND_GUARD);
if (decode_restriction_kind(pku) == BINDING_KIND_GLOBAL || jl_bkind_is_some_constant(decode_restriction_kind(pku))) {
if (jl_get_binding_value_if_const(bnd))
Expand Down
15 changes: 15 additions & 0 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -956,12 +956,14 @@ STATIC_INLINE int jl_bkind_is_some_guard(enum jl_partition_kind kind) JL_NOTSAFE
}

JL_DLLEXPORT jl_binding_partition_t *jl_get_binding_partition(jl_binding_t *b JL_PROPAGATES_ROOT, size_t world);
JL_DLLEXPORT jl_binding_partition_t *jl_get_binding_partition_all(jl_binding_t *b JL_PROPAGATES_ROOT, size_t min_world, size_t max_world);

EXTERN_INLINE_DECLARE uint8_t jl_bpart_get_kind(jl_binding_partition_t *bpart) JL_NOTSAFEPOINT {
return decode_restriction_kind(jl_atomic_load_relaxed(&bpart->restriction));
}

STATIC_INLINE jl_ptr_kind_union_t jl_walk_binding_inplace(jl_binding_t **bnd, jl_binding_partition_t **bpart, size_t world) JL_NOTSAFEPOINT;
STATIC_INLINE jl_ptr_kind_union_t jl_walk_binding_inplace_all(jl_binding_t **bnd, jl_binding_partition_t **bpart, size_t min_world, size_t max_world) JL_NOTSAFEPOINT;

#ifndef __clang_analyzer__
STATIC_INLINE jl_ptr_kind_union_t jl_walk_binding_inplace(jl_binding_t **bnd, jl_binding_partition_t **bpart, size_t world) JL_NOTSAFEPOINT
Expand All @@ -976,6 +978,19 @@ STATIC_INLINE jl_ptr_kind_union_t jl_walk_binding_inplace(jl_binding_t **bnd, jl
*bpart = jl_get_binding_partition(*bnd, world);
}
}

STATIC_INLINE jl_ptr_kind_union_t jl_walk_binding_inplace_all(jl_binding_t **bnd, jl_binding_partition_t **bpart, size_t min_world, size_t max_world) JL_NOTSAFEPOINT
{
while (1) {
if (!*bpart)
return encode_restriction(NULL, BINDING_KIND_GUARD);
jl_ptr_kind_union_t pku = jl_atomic_load_acquire(&(*bpart)->restriction);
if (!jl_bkind_is_some_import(decode_restriction_kind(pku)))
return pku;
*bnd = (jl_binding_t*)decode_restriction_value(pku);
*bpart = jl_get_binding_partition_all(*bnd, min_world, max_world);
}
}
#endif

STATIC_INLINE int is10digit(char c) JL_NOTSAFEPOINT
Expand Down
11 changes: 11 additions & 0 deletions src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,17 @@ jl_binding_partition_t *jl_get_binding_partition(jl_binding_t *b, size_t world)
}
}

jl_binding_partition_t *jl_get_binding_partition_all(jl_binding_t *b, size_t min_world, size_t max_world) {
if (!b)
return NULL;
jl_binding_partition_t *bpart = jl_get_binding_partition(b, min_world);
if (!bpart)
return NULL;
if (jl_atomic_load_relaxed(&bpart->max_world) < max_world)
return NULL;
return bpart;
}

JL_DLLEXPORT jl_module_t *jl_new_module_(jl_sym_t *name, jl_module_t *parent, uint8_t default_names)
{
jl_task_t *ct = jl_current_task;
Expand Down

0 comments on commit af68d7d

Please sign in to comment.