Skip to content

Commit 22d2ee5

Browse files
committed
Optimize jl_get_world_counter ccall
This is useful for hot loops that perform an `invoke_latest`-like operation, such as what the upcoming TypedCallable will do.
1 parent c388382 commit 22d2ee5

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

src/ccall.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ TRANSFORMED_CCALL_STAT(jl_gc_safepoint);
2323
TRANSFORMED_CCALL_STAT(jl_get_ptls_states);
2424
TRANSFORMED_CCALL_STAT(jl_threadid);
2525
TRANSFORMED_CCALL_STAT(jl_get_tls_world_age);
26+
TRANSFORMED_CCALL_STAT(jl_get_world_counter);
2627
TRANSFORMED_CCALL_STAT(jl_gc_enable_disable_finalizers_internal);
2728
TRANSFORMED_CCALL_STAT(jl_get_current_task);
2829
TRANSFORMED_CCALL_STAT(jl_set_next_task);
@@ -1706,6 +1707,30 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
17061707
return mark_or_box_ccall_result(ctx, world_age, retboxed, rt, unionall, static_rt);
17071708
}
17081709
}
1710+
else if (is_libjulia_func(jl_get_world_counter)) {
1711+
++CCALL_STAT(jl_get_world_counter);
1712+
assert(lrt == ctx.types().T_size);
1713+
assert(!isVa && !llvmcall && nccallargs == 0);
1714+
JL_GC_POP();
1715+
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const);
1716+
1717+
// jl_task_t *ct = jl_current_task;
1718+
// if (ct->ptls->in_pure_callback)
1719+
// return ~(size_t)0;
1720+
// return jl_atomic_load_acquire(&jl_world_counter);
1721+
Type *T_int16 = getInt16Ty(ctx.builder.getContext());
1722+
Value *offset = ConstantInt::get(ctx.types().T_size, offsetof(jl_tls_states_t, in_pure_callback) / sizeof(int16_t));
1723+
Value *field_ptr = ctx.builder.CreateInBoundsGEP(T_int16, get_current_ptls(ctx), offset);
1724+
Instruction *in_pure_callback = ai.decorateInst(ctx.builder.CreateAlignedLoad(T_int16,
1725+
field_ptr, Align(sizeof(int16_t)), "in_pure_callback"));
1726+
Value *cond = ctx.builder.CreateICmpEQ(in_pure_callback, ConstantInt::get(T_int16, 0));
1727+
1728+
Value *world_counter = ctx.builder.CreateAlignedLoad(ctx.types().T_size,
1729+
prepare_global_in(jl_Module, jlgetworld_global), ctx.types().alignof_ptr);
1730+
cast<LoadInst>(world_counter)->setOrdering(AtomicOrdering::Acquire);
1731+
Value *ret = ctx.builder.CreateSelect(cond, world_counter, ConstantInt::get(ctx.types().T_size, ~(size_t)0));
1732+
return mark_or_box_ccall_result(ctx, ret, retboxed, rt, unionall, static_rt);
1733+
}
17091734
else if (is_libjulia_func(jl_gc_disable_finalizers_internal)
17101735
#ifdef NDEBUG
17111736
|| is_libjulia_func(jl_gc_enable_finalizers_internal)

0 commit comments

Comments
 (0)