From 82fc876f9aaaf6de89248338b19c15093aeb481a Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 27 Nov 2022 16:52:22 +0000 Subject: [PATCH] Pass FFI spec to jit_register --- src/jit/jit-core.c | 9 ++++---- src/jit/jit-exits.c | 9 ++++---- src/jit/jit-llvm.c | 56 +++++++++++++++++++++++++++++++++++++++++++-- src/jit/jit-priv.h | 5 ++-- 4 files changed, 67 insertions(+), 12 deletions(-) diff --git a/src/jit/jit-core.c b/src/jit/jit-core.c index 16f0460b..1ba79eb8 100644 --- a/src/jit/jit-core.c +++ b/src/jit/jit-core.c @@ -243,16 +243,17 @@ jit_handle_t jit_compile(jit_t *j, ident_t name) return handle; } -void jit_register(jit_t *j, const char *name, jit_entry_fn_t fn, - const uint8_t *debug, size_t bufsz, object_t *obj) +void jit_register(jit_t *j, ident_t name, jit_entry_fn_t fn, + const uint8_t *debug, size_t bufsz, object_t *obj, + ffi_spec_t spec) { jit_func_t *f = hash_get(j->index, name); if (f != NULL) - fatal_trace("attempt to register existing function %s", name); + fatal_trace("attempt to register existing function %s", istr(name)); f = xcalloc(sizeof(jit_func_t)); - f->name = ident_new(name); + f->name = name; f->unit = vcode_find_unit(f->name); f->jit = j; f->handle = j->funcs.count; diff --git a/src/jit/jit-exits.c b/src/jit/jit-exits.c index 4d9db425..29c41979 100644 --- a/src/jit/jit-exits.c +++ b/src/jit/jit-exits.c @@ -1445,7 +1445,7 @@ jit_handle_t __nvc_get_handle(const char *func, ffi_spec_t spec) if (handle == JIT_HANDLE_INVALID) fatal_trace("missing function %s", func); - jit_get_func(j, handle)->spec = spec; + jit_get_func(j, handle)->spec = spec; // XXXX: delete me return handle; } @@ -1476,12 +1476,13 @@ void __nvc_setup_toggle_cb(sig_shared_t *ss, int32_t* toggle_mask) DLLEXPORT void __nvc_register(const char *name, jit_entry_fn_t fn, const uint8_t *debug, - int32_t bufsz, object_t *obj) + int32_t bufsz, object_t *obj, ffi_spec_t spec) { - printf("register! name=%s fn=%p bufsz=%d obj=%p\n", name, fn, bufsz, obj); + printf("register! name=%s fn=%p bufsz=%d obj=%p spec=%lx\n", + name, fn, bufsz, obj, spec); jit_t *j = jit_thread_local()->jit; - jit_register(j, name, fn, debug, bufsz, obj); + jit_register(j, ident_new(name), fn, debug, bufsz, obj, spec); } DLLEXPORT diff --git a/src/jit/jit-llvm.c b/src/jit/jit-llvm.c index b083a5eb..02cdc5f9 100644 --- a/src/jit/jit-llvm.c +++ b/src/jit/jit-llvm.c @@ -114,6 +114,7 @@ typedef enum { LLVM_GET_FOREIGN, LLVM_GET_TREE, LLVM_GET_OBJECT, + LLVM_GET_HANDLE, LLVM_LAST_FN, } llvm_fn_t; @@ -614,6 +615,7 @@ static LLVMValueRef llvm_get_fn(llvm_obj_t *obj, llvm_fn_t which) obj->types[LLVM_PTR], obj->types[LLVM_INT32], obj->types[LLVM_PTR], + obj->types[LLVM_INT64], }; obj->fntypes[which] = LLVMFunctionType(obj->types[LLVM_VOID], args, ARRAY_LEN(args), false); @@ -630,6 +632,18 @@ static LLVMValueRef llvm_get_fn(llvm_obj_t *obj, llvm_fn_t which) } break; + case LLVM_GET_HANDLE: + { + LLVMTypeRef args[] = { + obj->types[LLVM_PTR], + obj->types[LLVM_INT64] + }; + obj->fntypes[which] = LLVMFunctionType(obj->types[LLVM_INT32], args, + ARRAY_LEN(args), false); + fn = llvm_add_fn(obj, "__nvc_get_handle", obj->fntypes[which]); + } + break; + case LLVM_GET_FOREIGN: { LLVMTypeRef args[] = { @@ -812,6 +826,39 @@ static LLVMValueRef cgen_rematerialise_ffi(llvm_obj_t *obj, jit_foreign_t *ff) return LLVMBuildLoad2(obj->builder, obj->types[LLVM_PTR], global, ""); } +static LLVMValueRef cgen_rematerialise_handle(llvm_obj_t *obj, + cgen_block_t *cgb, + jit_handle_t handle) +{ + ident_t name = jit_get_name(cgb->func->source->jit, handle); + + LOCAL_TEXT_BUF tb = tb_new(); + tb_istr(tb, name); + tb_cat(tb, ".handle"); + + LLVMValueRef global = LLVMGetNamedGlobal(obj->module, tb_get(tb)); + if (global == NULL) { + global = LLVMAddGlobal(obj->module, obj->types[LLVM_INT32], tb_get(tb)); + LLVMSetUnnamedAddr(global, true); + LLVMSetLinkage(global, LLVMPrivateLinkage); + LLVMSetInitializer(global, llvm_int32(obj, JIT_HANDLE_INVALID)); + + LLVMBasicBlockRef old_bb = cgen_add_ctor(obj, 1); + + LLVMValueRef args[] = { + llvm_const_string(obj, istr(name)), + llvm_int64(obj, jit_get_func(cgb->func->source->jit, handle)->spec), + }; + LLVMValueRef init = + llvm_call_fn(obj, LLVM_GET_HANDLE, args, ARRAY_LEN(args)); + LLVMBuildStore(obj->builder, init, global); + + LLVMPositionBuilderAtEnd(obj->builder, old_bb); + } + + return LLVMBuildLoad2(obj->builder, obj->types[LLVM_INT32], global, ""); +} + static LLVMValueRef cgen_get_value(llvm_obj_t *obj, cgen_block_t *cgb, jit_value_t value) { @@ -857,8 +904,12 @@ static LLVMValueRef cgen_get_value(llvm_obj_t *obj, cgen_block_t *cgb, return ptr; } case JIT_VALUE_EXIT: - case JIT_VALUE_HANDLE: return llvm_int32(obj, value.exit); + case JIT_VALUE_HANDLE: + if (cgb->func->cpool != NULL) + return cgen_rematerialise_handle(obj, cgb, value.handle); + else + return llvm_int32(obj, value.handle); case JIT_ADDR_ABS: assert(obj->ctor == NULL || value.int64 == 0); return llvm_ptr(obj, (void *)(intptr_t)value.int64); @@ -1875,7 +1926,8 @@ static void cgen_function(llvm_obj_t *obj, cgen_func_t *func) PTR(func->llvmfn), PTR(cgen_debug_irbuf(obj, func->source)), llvm_int32(obj, func->source->nirs), - cgen_rematerialise_object(obj, func->source->object) + cgen_rematerialise_object(obj, func->source->object), + llvm_int64(obj, func->source->spec), }; llvm_call_fn(obj, LLVM_REGISTER, args, ARRAY_LEN(args)); diff --git a/src/jit/jit-priv.h b/src/jit/jit-priv.h index 293d06b8..5a9dc089 100644 --- a/src/jit/jit-priv.h +++ b/src/jit/jit-priv.h @@ -307,8 +307,9 @@ bool jit_has_runtime(jit_t *j); int jit_backedge_limit(jit_t *j); void jit_tier_up(jit_func_t *f); jit_thread_local_t *jit_thread_local(void); -void jit_register(jit_t *j, const char *name, jit_entry_fn_t fn, - const uint8_t *debug, size_t bufsz, object_t *obj); +void jit_register(jit_t *j, ident_t name, jit_entry_fn_t fn, + const uint8_t *debug, size_t bufsz, object_t *obj, + ffi_spec_t spec); jit_cfg_t *jit_get_cfg(jit_func_t *f); void jit_free_cfg(jit_func_t *f); -- 2.39.2