Skip to content

Commit

Permalink
Try to generate reusable jlcall wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyichao committed May 27, 2015
1 parent cfbd68c commit 80f3bbe
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
37 changes: 28 additions & 9 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -3780,7 +3783,21 @@ 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<Value*>(&args[0], nfargs));
Value *theLam = emit_nthptr(
fArg,
(ssize_t)(offsetof(jl_function_t, linfo)/sizeof(void*)),
tbaa_value);

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<Value*>(&args[0], nfargs));
if (r->getType() != jl_pvalue_llvmt) {
r = boxed(r, &ctx, jl_ast_rettype(lam, (jl_value_t*)ast));
}
Expand Down Expand Up @@ -4755,14 +4772,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);
}
Expand Down
1 change: 1 addition & 0 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 80f3bbe

Please sign in to comment.