diff --git a/src/alloc.c b/src/alloc.c index 913982d236e74..915a660ef65bf 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -342,6 +342,7 @@ jl_lambda_info_t *jl_new_lambda_info(jl_value_t *ast, jl_svec_t *sparams) li->roots = NULL; li->functionObject = NULL; li->specFunctionObject = NULL; + li->specFunctionPtr = NULL; li->cFunctionList = NULL; li->functionID = 0; li->specFunctionID = 0; diff --git a/src/codegen.cpp b/src/codegen.cpp index 4575080f37aa7..082a0cb07bf82 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -638,6 +638,7 @@ static Function *to_function(jl_lambda_info_t *li) JL_CATCH { li->functionObject = NULL; li->specFunctionObject = NULL; + li->specFunctionPtr = NULL; li->cFunctionList = NULL; nested_compile = last_n_c; if (old != NULL) { @@ -773,9 +774,9 @@ extern "C" void jl_generate_fptr(jl_function_t *f) if (li->specFunctionObject != NULL) { #ifdef USE_MCJIT - (void)jl_ExecutionEngine->getFunctionAddress(((Function*)li->specFunctionObject)->getName()); + li->specFunctionPtr = (void*)(intptr_t)jl_ExecutionEngine->getFunctionAddress(((Function*)li->specFunctionObject)->getName()); #else - (void)jl_ExecutionEngine->getPointerToFunction((Function*)li->specFunctionObject); + li->specFunctionPtr = jl_ExecutionEngine->getPointerToFunction((Function*)li->specFunctionObject); #endif if (!imaging_mode) ((Function*)li->specFunctionObject)->deleteBody(); @@ -3745,7 +3746,9 @@ static Function *gen_jlcall_wrapper(jl_lambda_info_t *lam, jl_expr_t *ast, Funct funcName.str(), f->getParent()); addComdat(w); Function::arg_iterator AI = w->arg_begin(); - AI++; //const Argument &fArg = *AI++; + // const Argument &fArg = *AI++; + // AI++; + Value *fArg = AI++; Value *argArray = AI++; //const Argument &argCount = *AI++; BasicBlock *b0 = BasicBlock::Create(jl_LLVMContext, "top", w); @@ -3780,7 +3783,22 @@ static Function *gen_jlcall_wrapper(jl_lambda_info_t *lam, jl_expr_t *ast, Funct } // TODO: consider pulling the function pointer out of fArg so these // wrappers can be reused for different functions of the same type. - Value *r = builder.CreateCall(prepare_call(f), ArrayRef(&args[0], nfargs)); + Value *theLam = emit_nthptr_recast( + fArg, + (ssize_t)(offsetof(jl_function_t, linfo)/sizeof(void*)), + tbaa_value, + julia_type_to_llvm((jl_value_t*)jl_lambda_info_type)); + + FunctionType *ftype = f->getFunctionType(); + Type *fptrtype = PointerType::get(PointerType::get(ftype, 0), 0); + + Value *theFptr = emit_nthptr_recast( + theLam, + (ssize_t)(offsetof(jl_lambda_info_t, specFunctionPtr)/sizeof(void*)), + tbaa_func, + fptrtype); + Value *r = builder.CreateCall(prepare_call(theFptr), + ArrayRef(&args[0], nfargs)); if (r->getType() != jl_pvalue_llvmt) { r = boxed(r, &ctx, jl_ast_rettype(lam, (jl_value_t*)ast)); } @@ -4755,14 +4773,16 @@ extern "C" void jl_fptr_to_llvm(void *fptr, jl_lambda_info_t *lam, int specsig) Type *rt = (jlrettype == (jl_value_t*)jl_void_type ? T_void : julia_type_to_llvm(jlrettype)); Function *f = Function::Create(FunctionType::get(rt, fsig, false), Function::ExternalLinkage, funcName, #ifdef USE_MCJIT - shadow_module); + shadow_module #else - jl_Module); + jl_Module #endif + ); - if (lam->specFunctionObject == NULL) { - lam->specFunctionObject = (void*)f; - lam->specFunctionID = jl_assign_functionID(f); + if (lam->specFunctionObject == NULL) { + lam->specFunctionObject = (void*)f; + lam->specFunctionID = jl_assign_functionID(f); + lam->specFunctionPtr = fptr; } add_named_global(f, (void*)fptr); } diff --git a/src/dump.c b/src/dump.c index ed7cd90d6dba2..8a9b8dfa92cbd 100644 --- a/src/dump.c +++ b/src/dump.c @@ -1205,6 +1205,7 @@ static jl_value_t *jl_deserialize_value_(ios_t *s, jl_value_t *vtag, jl_value_t li->functionObject = NULL; li->cFunctionList = NULL; li->specFunctionObject = NULL; + li->specFunctionPtr = NULL; li->inInference = 0; li->inCompile = 0; li->unspecialized = (jl_function_t*)jl_deserialize_value(s, (jl_value_t**)&li->unspecialized); diff --git a/src/julia.h b/src/julia.h index a8dcba4752fbb..614d13e8b5d9d 100644 --- a/src/julia.h +++ b/src/julia.h @@ -222,6 +222,7 @@ typedef struct _jl_lambda_info_t { // specialized llvm Function (common core for the other two) void *specFunctionObject; + void *specFunctionPtr; int32_t functionID; // index that this function will have in the codegen table int32_t specFunctionID; // index that this specFunction will have in the codegen table } jl_lambda_info_t;