Skip to content

Commit

Permalink
Optimize jl_tls_world_age ccall
Browse files Browse the repository at this point in the history
  • Loading branch information
gbaraldi authored and topolarity committed Jun 11, 2024
1 parent 3fc3577 commit 70e96fe
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 12 deletions.
15 changes: 15 additions & 0 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ TRANSFORMED_CCALL_STAT(jl_cpu_wake);
TRANSFORMED_CCALL_STAT(jl_gc_safepoint);
TRANSFORMED_CCALL_STAT(jl_get_ptls_states);
TRANSFORMED_CCALL_STAT(jl_threadid);
TRANSFORMED_CCALL_STAT(jl_get_tls_world_age);
TRANSFORMED_CCALL_STAT(jl_gc_enable_disable_finalizers_internal);
TRANSFORMED_CCALL_STAT(jl_get_current_task);
TRANSFORMED_CCALL_STAT(jl_set_next_task);
Expand Down Expand Up @@ -1690,6 +1691,20 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
ai.decorateInst(tid);
return mark_or_box_ccall_result(ctx, tid, retboxed, rt, unionall, static_rt);
}
else if (is_libjulia_func(jl_get_tls_world_age)) {
bool toplevel = !(ctx.linfo && jl_is_method(ctx.linfo->def.method));
if (!toplevel) { // top level code does not see a stable world age during execution
++CCALL_STAT(jl_get_tls_world_age);
assert(lrt == ctx.types().T_size);
assert(!isVa && !llvmcall && nccallargs == 0);
JL_GC_POP();
Instruction *world_age = cast<Instruction>(ctx.world_age_at_entry);
setName(ctx.emission_context, world_age, "task_world_age");
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_gcframe);
ai.decorateInst(world_age);
return mark_or_box_ccall_result(ctx, world_age, retboxed, rt, unionall, static_rt);
}
}
else if (is_libjulia_func(jl_gc_disable_finalizers_internal)
#ifdef NDEBUG
|| is_libjulia_func(jl_gc_enable_finalizers_internal)
Expand Down
26 changes: 14 additions & 12 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1978,6 +1978,7 @@ class jl_codectx_t {

Value *pgcstack = NULL;
Instruction *topalloca = NULL;
Value *world_age_at_entry = NULL; // Not valid to use in toplevel code

bool use_cache = false;
bool external_linkage = false;
Expand Down Expand Up @@ -2106,7 +2107,7 @@ static jl_cgval_t emit_sparam(jl_codectx_t &ctx, size_t i);
static Value *emit_condition(jl_codectx_t &ctx, const jl_cgval_t &condV, const Twine &msg);
static Value *get_current_task(jl_codectx_t &ctx);
static Value *get_current_ptls(jl_codectx_t &ctx);
static Value *get_last_age_field(jl_codectx_t &ctx);
static Value *get_tls_world_age_field(jl_codectx_t &ctx);
static void CreateTrap(IRBuilder<> &irbuilder, bool create_new_block = true);
static CallInst *emit_jlcall(jl_codectx_t &ctx, FunctionCallee theFptr, Value *theF,
ArrayRef<jl_cgval_t> args, size_t nargs, JuliaFunction<> *trampoline);
Expand Down Expand Up @@ -6560,7 +6561,9 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaidx_
if (F) {
jl_cgval_t jlcall_ptr = mark_julia_type(ctx, F, false, jl_voidpointer_type);
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_gcframe);
Instruction *I = ctx.builder.CreateAlignedLoad(ctx.types().T_size, get_last_age_field(ctx), ctx.types().alignof_ptr);
bool not_toplevel = (ctx.linfo && jl_is_method(ctx.linfo->def.method));
Instruction *I = not_toplevel ? cast<Instruction>(ctx.world_age_at_entry) :
ctx.builder.CreateAlignedLoad(ctx.types().T_size, get_tls_world_age_field(ctx), ctx.types().alignof_ptr);
jl_cgval_t world_age = mark_julia_type(ctx, ai.decorateInst(I), false, jl_long_type);
jl_cgval_t fptr;
if (specF)
Expand Down Expand Up @@ -6715,7 +6718,7 @@ static Value *get_current_ptls(jl_codectx_t &ctx)
}

// Get the address of the world age of the current task
static Value *get_last_age_field(jl_codectx_t &ctx)
static Value *get_tls_world_age_field(jl_codectx_t &ctx)
{
Value *ct = get_current_task(ctx, ctx.types().T_size->getPointerTo());
return ctx.builder.CreateInBoundsGEP(
Expand Down Expand Up @@ -7041,11 +7044,11 @@ static Function* gen_cfun_wrapper(
ctx.builder.SetCurrentDebugLocation(noDbg);
allocate_gc_frame(ctx, b0, true);

Value *world_age_field = get_last_age_field(ctx);
auto world_age_field = get_tls_world_age_field(ctx);
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_gcframe);
Value *last_age = ai.decorateInst(
ctx.builder.CreateAlignedLoad(ctx.types().T_size, world_age_field, ctx.types().alignof_ptr));

ctx.world_age_at_entry = last_age;
Value *world_v = ctx.builder.CreateAlignedLoad(ctx.types().T_size,
prepare_global_in(jl_Module, jlgetworld_global), ctx.types().alignof_ptr);
cast<LoadInst>(world_v)->setOrdering(AtomicOrdering::Acquire);
Expand Down Expand Up @@ -8494,12 +8497,11 @@ static jl_llvm_functions_t
// step 6. set up GC frame
allocate_gc_frame(ctx, b0);
Value *last_age = NULL;
Value *world_age_field = get_last_age_field(ctx);
if (toplevel || ctx.is_opaque_closure) {
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_gcframe);
last_age = ai.decorateInst(ctx.builder.CreateAlignedLoad(
ctx.types().T_size, world_age_field, ctx.types().alignof_ptr));
}
auto world_age_field = get_tls_world_age_field(ctx);
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_gcframe);
last_age = ai.decorateInst(ctx.builder.CreateAlignedLoad(
ctx.types().T_size, world_age_field, ctx.types().alignof_ptr));
ctx.world_age_at_entry = last_age; // Load world age for use in get_tls_world_age

// step 7. allocate local variables slots
// must be in the first basic block for the llvm mem2reg pass to work
Expand Down Expand Up @@ -8746,6 +8748,7 @@ static jl_llvm_functions_t

jl_cgval_t closure_world = typed_load(ctx, worldaddr, NULL, (jl_value_t*)jl_long_type,
nullptr, nullptr, false, AtomicOrdering::NotAtomic, false, ctx.types().alignof_ptr.value());
ctx.world_age_at_entry = closure_world.V; // The tls world in a OC is the world of the closure
emit_unbox_store(ctx, closure_world, world_age_field, ctx.tbaa().tbaa_gcframe, ctx.types().alignof_ptr.value());

// Load closure env
Expand Down Expand Up @@ -8808,7 +8811,6 @@ static jl_llvm_functions_t
}
}
}

// step 9. allocate rest argument
CallInst *restTuple = NULL;
if (va && ctx.vaSlot != -1) {
Expand Down
1 change: 1 addition & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1809,6 +1809,7 @@ JL_DLLEXPORT jl_method_t *jl_method_def(jl_svec_t *argdata, jl_methtable_t *mt,
JL_DLLEXPORT jl_code_info_t *jl_code_for_staged(jl_method_instance_t *linfo, size_t world, jl_code_instance_t **cache);
JL_DLLEXPORT jl_code_info_t *jl_copy_code_info(jl_code_info_t *src);
JL_DLLEXPORT size_t jl_get_world_counter(void) JL_NOTSAFEPOINT;
JL_DLLEXPORT size_t jl_get_tls_world_age(void) JL_NOTSAFEPOINT;
JL_DLLEXPORT jl_value_t *jl_box_bool(int8_t x) JL_NOTSAFEPOINT;
JL_DLLEXPORT jl_value_t *jl_box_int8(int8_t x) JL_NOTSAFEPOINT;
JL_DLLEXPORT jl_value_t *jl_box_uint8(uint8_t x) JL_NOTSAFEPOINT;
Expand Down

0 comments on commit 70e96fe

Please sign in to comment.