Skip to content

Commit 44fecb1

Browse files
authored
staticdata: remove reinit_ccallable (#56987)
This commit removes `jl_reinit_ccallable` whose purpose is unclear. Specifically, the function re-adds C-callable functions to the execution engine during the loading of sysimages/pkgimages, but the consensus is that the function is largely unnecessary because `ccall` can find symbols via `dlsym`. The function's only apparent use case is a contrived `llvmcall` example, only because we currently don't add the sysimage symbols to the JIT, but we could do anyway. `llvmcall` has always been experimental, and if it is truly needed, the functionality for finding the symbols should be properly implemented later.
1 parent 7f8ca29 commit 44fecb1

11 files changed

+65
-273
lines changed

src/aotcompile.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ void *jl_emit_native_impl(jl_array_t *codeinfos, LLVMOrcThreadSafeModuleRef llvm
786786
else {
787787
jl_value_t *sig = jl_array_ptr_ref(codeinfos, ++i);
788788
assert(jl_is_type(item) && jl_is_type(sig));
789-
jl_compile_extern_c(wrap(&clone), &params, NULL, item, sig);
789+
jl_generate_ccallable(clone.getModuleUnlocked(), nullptr, item, sig, params);
790790
}
791791
}
792792
// finally, make sure all referenced methods get fixed up, particularly if the user declined to compile them

src/codegen-stubs.c

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ JL_DLLEXPORT void jl_get_llvm_gvs_fallback(void *native_code, arraylist_t *gvs)
1717
JL_DLLEXPORT void jl_get_llvm_external_fns_fallback(void *native_code, arraylist_t *gvs) UNAVAILABLE
1818
JL_DLLEXPORT void jl_get_llvm_mis_fallback(void *native_code, arraylist_t* MIs) UNAVAILABLE
1919

20-
JL_DLLEXPORT void jl_extern_c_fallback(jl_function_t *f, jl_value_t *rt, jl_value_t *argt, char *name) UNAVAILABLE
2120
JL_DLLEXPORT jl_value_t *jl_dump_method_asm_fallback(jl_method_instance_t *linfo, size_t world,
2221
char emit_mc, char getwrapper, const char* asm_variant, const char *debuginfo, char binary) UNAVAILABLE
2322
JL_DLLEXPORT jl_value_t *jl_dump_function_ir_fallback(jl_llvmf_dump_t *dump, char strip_ir_metadata, char dump_module, const char *debuginfo) UNAVAILABLE

src/gf.c

+38
Original file line numberDiff line numberDiff line change
@@ -4585,6 +4585,44 @@ JL_DLLEXPORT void jl_typeinf_timing_end(uint64_t start, int is_recompile)
45854585
}
45864586
}
45874587

4588+
// declare a C-callable entry point; called during code loading from the toplevel
4589+
JL_DLLEXPORT void jl_extern_c(jl_value_t *declrt, jl_tupletype_t *sigt)
4590+
{
4591+
// validate arguments. try to do as many checks as possible here to avoid
4592+
// throwing errors later during codegen.
4593+
JL_TYPECHK(@ccallable, type, declrt);
4594+
if (!jl_is_tuple_type(sigt))
4595+
jl_type_error("@ccallable", (jl_value_t*)jl_anytuple_type_type, (jl_value_t*)sigt);
4596+
// check that f is a guaranteed singleton type
4597+
jl_datatype_t *ft = (jl_datatype_t*)jl_tparam0(sigt);
4598+
if (!jl_is_datatype(ft) || !jl_is_datatype_singleton(ft))
4599+
jl_error("@ccallable: function object must be a singleton");
4600+
4601+
// compute / validate return type
4602+
if (!jl_is_concrete_type(declrt) || jl_is_kind(declrt))
4603+
jl_error("@ccallable: return type must be concrete and correspond to a C type");
4604+
if (!jl_type_mappable_to_c(declrt))
4605+
jl_error("@ccallable: return type doesn't correspond to a C type");
4606+
4607+
// validate method signature
4608+
size_t i, nargs = jl_nparams(sigt);
4609+
for (i = 1; i < nargs; i++) {
4610+
jl_value_t *ati = jl_tparam(sigt, i);
4611+
if (!jl_is_concrete_type(ati) || jl_is_kind(ati) || !jl_type_mappable_to_c(ati))
4612+
jl_error("@ccallable: argument types must be concrete");
4613+
}
4614+
4615+
// save a record of this so that the alias is generated when we write an object file
4616+
jl_method_t *meth = (jl_method_t*)jl_methtable_lookup(ft->name->mt, (jl_value_t*)sigt, jl_atomic_load_acquire(&jl_world_counter));
4617+
if (!jl_is_method(meth))
4618+
jl_error("@ccallable: could not find requested method");
4619+
JL_GC_PUSH1(&meth);
4620+
meth->ccallable = jl_svec2(declrt, (jl_value_t*)sigt);
4621+
jl_gc_wb(meth, meth->ccallable);
4622+
JL_GC_POP();
4623+
}
4624+
4625+
45884626
#ifdef __cplusplus
45894627
}
45904628
#endif

src/jitlayers.cpp

-134
Original file line numberDiff line numberDiff line change
@@ -805,140 +805,6 @@ void jl_emit_codeinst_to_jit_impl(
805805
}
806806

807807

808-
const char *jl_generate_ccallable(Module *llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t &params);
809-
810-
// compile a C-callable alias
811-
extern "C" JL_DLLEXPORT_CODEGEN
812-
int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void *sysimg, jl_value_t *declrt, jl_value_t *sigt)
813-
{
814-
auto ct = jl_current_task;
815-
bool timed = (ct->reentrant_timing & 1) == 0;
816-
if (timed)
817-
ct->reentrant_timing |= 1;
818-
uint64_t compiler_start_time = 0;
819-
uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed(&jl_measure_compile_time_enabled);
820-
if (measure_compile_time_enabled)
821-
compiler_start_time = jl_hrtime();
822-
jl_codegen_params_t *pparams = (jl_codegen_params_t*)p;
823-
DataLayout DL = pparams ? pparams->DL : jl_ExecutionEngine->getDataLayout();
824-
Triple TargetTriple = pparams ? pparams->TargetTriple : jl_ExecutionEngine->getTargetTriple();
825-
orc::ThreadSafeContext ctx;
826-
auto into = unwrap(llvmmod);
827-
orc::ThreadSafeModule backing;
828-
bool success = true;
829-
const char *name = "";
830-
if (into == NULL) {
831-
ctx = pparams ? pparams->tsctx : jl_ExecutionEngine->makeContext();
832-
backing = jl_create_ts_module("cextern", ctx, DL, TargetTriple);
833-
into = &backing;
834-
}
835-
{ // params scope
836-
jl_codegen_params_t params(into->getContext(), DL, TargetTriple);
837-
if (pparams == NULL) {
838-
params.cache = p == NULL;
839-
params.imaging_mode = 0;
840-
params.tsctx.getContext()->setDiscardValueNames(true);
841-
pparams = &params;
842-
}
843-
Module &M = *into->getModuleUnlocked();
844-
assert(pparams->tsctx.getContext() == &M.getContext());
845-
name = jl_generate_ccallable(&M, sysimg, declrt, sigt, *pparams);
846-
if (!sysimg && !p) {
847-
{ // drop lock to keep analyzer happy (since it doesn't know we have the only reference to it)
848-
auto release = std::move(params.tsctx_lock);
849-
}
850-
{ // lock scope
851-
jl_unique_gcsafe_lock lock(extern_c_lock);
852-
if (jl_ExecutionEngine->getGlobalValueAddress(name))
853-
success = false;
854-
}
855-
params.tsctx_lock = params.tsctx.getLock(); // re-acquire lock
856-
if (success && params.cache) {
857-
size_t newest_world = jl_atomic_load_acquire(&jl_world_counter);
858-
for (auto &it : params.workqueue) { // really just zero or one, and just the ABI not the rest of the metadata
859-
jl_code_instance_t *codeinst = it.first;
860-
JL_GC_PROMISE_ROOTED(codeinst);
861-
jl_code_instance_t *newest_ci = jl_type_infer(jl_get_ci_mi(codeinst), newest_world, SOURCE_MODE_ABI);
862-
if (newest_ci) {
863-
if (jl_egal(codeinst->rettype, newest_ci->rettype))
864-
it.first = codeinst;
865-
jl_compile_codeinst_now(newest_ci);
866-
}
867-
}
868-
jl_analyze_workqueue(nullptr, params, true);
869-
assert(params.workqueue.empty());
870-
finish_params(&M, params, sharedmodules);
871-
}
872-
}
873-
pparams = nullptr;
874-
}
875-
if (!sysimg && success && llvmmod == NULL) {
876-
{ // lock scope
877-
jl_unique_gcsafe_lock lock(extern_c_lock);
878-
if (!jl_ExecutionEngine->getGlobalValueAddress(name)) {
879-
{
880-
auto Lock = backing.getContext().getLock();
881-
jl_ExecutionEngine->optimizeDLSyms(*backing.getModuleUnlocked()); // safepoint
882-
}
883-
jl_ExecutionEngine->addModule(std::move(backing));
884-
success = jl_ExecutionEngine->getGlobalValueAddress(name);
885-
assert(success);
886-
}
887-
}
888-
}
889-
if (timed) {
890-
if (measure_compile_time_enabled) {
891-
auto end = jl_hrtime();
892-
jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, end - compiler_start_time);
893-
}
894-
ct->reentrant_timing &= ~1ull;
895-
}
896-
return success;
897-
}
898-
899-
// declare a C-callable entry point; called during code loading from the toplevel
900-
extern "C" JL_DLLEXPORT_CODEGEN
901-
void jl_extern_c_impl(jl_value_t *declrt, jl_tupletype_t *sigt)
902-
{
903-
// validate arguments. try to do as many checks as possible here to avoid
904-
// throwing errors later during codegen.
905-
JL_TYPECHK(@ccallable, type, declrt);
906-
if (!jl_is_tuple_type(sigt))
907-
jl_type_error("@ccallable", (jl_value_t*)jl_anytuple_type_type, (jl_value_t*)sigt);
908-
// check that f is a guaranteed singleton type
909-
jl_datatype_t *ft = (jl_datatype_t*)jl_tparam0(sigt);
910-
if (!jl_is_datatype(ft) || !jl_is_datatype_singleton(ft))
911-
jl_error("@ccallable: function object must be a singleton");
912-
913-
// compute / validate return type
914-
if (!jl_is_concrete_type(declrt) || jl_is_kind(declrt))
915-
jl_error("@ccallable: return type must be concrete and correspond to a C type");
916-
if (!jl_type_mappable_to_c(declrt))
917-
jl_error("@ccallable: return type doesn't correspond to a C type");
918-
919-
// validate method signature
920-
size_t i, nargs = jl_nparams(sigt);
921-
for (i = 1; i < nargs; i++) {
922-
jl_value_t *ati = jl_tparam(sigt, i);
923-
if (!jl_is_concrete_type(ati) || jl_is_kind(ati) || !jl_type_mappable_to_c(ati))
924-
jl_error("@ccallable: argument types must be concrete");
925-
}
926-
927-
// save a record of this so that the alias is generated when we write an object file
928-
jl_method_t *meth = (jl_method_t*)jl_methtable_lookup(ft->name->mt, (jl_value_t*)sigt, jl_atomic_load_acquire(&jl_world_counter));
929-
if (!jl_is_method(meth))
930-
jl_error("@ccallable: could not find requested method");
931-
JL_GC_PUSH1(&meth);
932-
meth->ccallable = jl_svec2(declrt, (jl_value_t*)sigt);
933-
jl_gc_wb(meth, meth->ccallable);
934-
JL_GC_POP();
935-
936-
// create the alias in the current runtime environment
937-
int success = jl_compile_extern_c(NULL, NULL, NULL, declrt, (jl_value_t*)sigt);
938-
if (!success)
939-
jl_error("@ccallable was already defined for this method name");
940-
}
941-
942808
extern "C" JL_DLLEXPORT_CODEGEN
943809
int jl_compile_codeinst_impl(jl_code_instance_t *ci)
944810
{

src/jitlayers.h

+2
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ struct jl_codegen_params_t {
284284
~jl_codegen_params_t() JL_NOTSAFEPOINT JL_NOTSAFEPOINT_LEAVE = default;
285285
};
286286

287+
const char *jl_generate_ccallable(Module *llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t &params);
288+
287289
jl_llvm_functions_t jl_emit_code(
288290
orc::ThreadSafeModule &M,
289291
jl_method_instance_t *mi,

src/jl_exported_funcs.inc

-2
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,6 @@
515515
YY(jl_dump_function_ir) \
516516
YY(jl_dump_method_asm) \
517517
YY(jl_emit_codeinst_to_jit) \
518-
YY(jl_extern_c) \
519518
YY(jl_get_llvmf_defn) \
520519
YY(jl_get_llvm_function) \
521520
YY(jl_get_llvm_module) \
@@ -532,7 +531,6 @@
532531
YY(jl_register_fptrs) \
533532
YY(jl_generate_fptr_for_unspecialized) \
534533
YY(jl_compile_codeinst) \
535-
YY(jl_compile_extern_c) \
536534
YY(jl_teardown_codegen) \
537535
YY(jl_jit_total_bytes) \
538536
YY(jl_create_native) \

src/julia.h

-1
Original file line numberDiff line numberDiff line change
@@ -2201,7 +2201,6 @@ typedef enum {
22012201
// A loaded, but unparsed .ji or .so image file
22022202
typedef struct {
22032203
jl_image_kind_t kind;
2204-
void *handle;
22052204
const void *pointers; // jl_image_pointers_t *
22062205
const char *data;
22072206
size_t size;

src/julia_internal.h

-1
Original file line numberDiff line numberDiff line change
@@ -1991,7 +1991,6 @@ JL_DLLEXPORT uint32_t jl_crc32c(uint32_t crc, const char *buf, size_t len);
19911991

19921992
JL_DLLIMPORT void jl_generate_fptr_for_unspecialized(jl_code_instance_t *unspec);
19931993
JL_DLLIMPORT int jl_compile_codeinst(jl_code_instance_t *unspec);
1994-
JL_DLLIMPORT int jl_compile_extern_c(LLVMOrcThreadSafeModuleRef llvmmod, void *params, void *sysimg, jl_value_t *declrt, jl_value_t *sigt);
19951994
JL_DLLIMPORT void jl_emit_codeinst_to_jit(jl_code_instance_t *codeinst, jl_code_info_t *src);
19961995

19971996
typedef struct {

0 commit comments

Comments
 (0)