Skip to content

Commit

Permalink
Merge pull request #12668 from JuliaLang/jn/pre_cfunction
Browse files Browse the repository at this point in the history
precompile cfunction calls. fixes #12256
  • Loading branch information
vtjnash committed Aug 18, 2015
2 parents 77bef6e + 969ed72 commit 4d72065
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 15 deletions.
39 changes: 39 additions & 0 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1172,6 +1172,7 @@ static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
if (fptr == (void *) &jl_is_leaf_type ||
((f_lib==NULL || (intptr_t)f_lib==2)
&& f_name && !strcmp(f_name, "jl_is_leaf_type"))) {
assert(nargt == 1);
jl_value_t *arg = args[4];
jl_value_t *ty = expr_type(arg, ctx);
if (jl_is_type_type(ty) && !jl_is_typevar(jl_tparam0(ty))) {
Expand All @@ -1180,6 +1181,44 @@ static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
return ConstantInt::get(T_int32, isleaf);
}
}
if (fptr == (void*)&jl_function_ptr ||
((f_lib==NULL || (intptr_t)f_lib==2)
&& f_name && !strcmp(f_name, "jl_function_ptr"))) {
assert(nargt == 3);
jl_value_t *f = static_eval(args[4], ctx, false, false);
jl_value_t *frt = expr_type(args[6], ctx);
if (f && jl_is_function(f) &&
(jl_is_type_type((jl_value_t*)frt) && !jl_has_typevars(jl_tparam0(frt)))) {
jl_value_t *fargt = static_eval(args[8], ctx, true, true);
if (fargt) {
if (jl_is_tuple(fargt)) {
// TODO: maybe deprecation warning, better checking
fargt = (jl_value_t*)jl_apply_tuple_type_v((jl_value_t**)jl_data_ptr(fargt), jl_nfields(fargt));
}
}
else {
fargt = expr_type(args[8], ctx);
if (jl_is_type_type((jl_value_t*)fargt))
fargt = jl_tparam0(fargt);
}
if (jl_is_tuple_type(fargt) && jl_is_leaf_type(fargt)) {
frt = jl_tparam0(frt);
JL_TRY {
Value *llvmf = prepare_call(
jl_cfunction_object((jl_function_t*)f, frt, (jl_tupletype_t*)fargt));
// make sure to emit any side-effects that may have been part of the original expression
emit_expr(args[4], ctx);
emit_expr(args[6], ctx);
emit_expr(args[8], ctx);
JL_GC_POP();
return mark_or_box_ccall_result(builder.CreateBitCast(llvmf, lrt),
args[2], rt, static_rt, ctx);
}
JL_CATCH {
}
}
}
}

// save place before arguments, for possible insertion of temp arg
// area saving code.
Expand Down
52 changes: 37 additions & 15 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -895,17 +895,6 @@ void *jl_function_ptr(jl_function_t *f, jl_value_t *rt, jl_value_t *argt)
assert(llvmf);
JL_GC_POP();
#ifdef USE_MCJIT
if (imaging_mode) {
// Copy the function out of the shadow module, unless this was done before
void *addr = (void*)(intptr_t)jl_ExecutionEngine->getFunctionAddress(llvmf->getName());
if (addr != nullptr) {
return addr;
}
Module *m = new Module("julia", jl_LLVMContext);
jl_setup_module(m, true);
FunctionMover mover(m, shadow_module);
llvmf = mover.CloneFunction(llvmf);
}
return (void*)(intptr_t)jl_ExecutionEngine->getFunctionAddress(llvmf->getName());
#else
return jl_ExecutionEngine->getPointerToFunction(llvmf);
Expand Down Expand Up @@ -3576,9 +3565,22 @@ static Function *gen_cfun_wrapper(jl_function_t *ff, jl_value_t *jlrettype, jl_t
if (fargt.size() != fargt_sig.size())
jl_error("va_arg syntax not allowed for cfunction argument list");

jl_compile(ff);
if (!lam->functionObject) {
jl_errorf("error compiling %s while creating cfunction", lam->name->name);
}

std::stringstream funcName;
funcName << "jlcapi_" << lam->name->name << "_" << globalUnique++;

// Backup the info for the nested compile
JL_SIGATOMIC_BEGIN(); // no errors expected beyond this point
BasicBlock *old = nested_compile ? builder.GetInsertBlock() : NULL;
DebugLoc olddl = builder.getCurrentDebugLocation();
bool last_n_c = nested_compile;
nested_compile = true;
jl_gc_inhibit_finalizers(nested_compile); // no allocations expected between the top of this function (when last scanned lam->cFunctionList) and here, which might have triggered running julia code

// Create the Function stub
Module *m;
#ifdef USE_MCJIT
Expand Down Expand Up @@ -3618,7 +3620,6 @@ static Function *gen_cfun_wrapper(jl_function_t *ff, jl_value_t *jlrettype, jl_t
lam->cFunctionList = list2;

// See whether this function is specsig or jlcall
jl_compile(ff);
bool specsig;
Function *theFptr;
if (lam->specFunctionObject != NULL) {
Expand All @@ -3628,10 +3629,8 @@ static Function *gen_cfun_wrapper(jl_function_t *ff, jl_value_t *jlrettype, jl_t
else {
theFptr = (Function*)lam->functionObject;
specsig = false;
if (!theFptr) {
jl_errorf("error compiling %s while creating cfunction", lam->name->name);
}
}
assert(theFptr);

// Alright, let's do this!
// let's first emit the arguments
Expand Down Expand Up @@ -3753,6 +3752,29 @@ static Function *gen_cfun_wrapper(jl_function_t *ff, jl_value_t *jlrettype, jl_t
}
#endif

#ifdef USE_MCJIT
if (imaging_mode) {
// Copy the function out of the shadow module
Module *m = new Module("julia", jl_LLVMContext);
jl_setup_module(m, true);
FunctionMover mover(m, shadow_module);
Function *clone = mover.CloneFunction(cw);
FPM->run(*clone);
}
else {
FPM->run(*cw);
}
#endif

// Restore the previous compile context
if (old != NULL) {
builder.SetInsertPoint(old);
builder.SetCurrentDebugLocation(olddl);
}
nested_compile = last_n_c;
jl_gc_inhibit_finalizers(nested_compile);
JL_SIGATOMIC_END();

return cw;
}

Expand Down

0 comments on commit 4d72065

Please sign in to comment.