From efeb85254efb3879bb2b893529bccb13244dcf51 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sat, 22 Oct 2022 14:16:12 +0100 Subject: [PATCH] Fix composite resolution function handling in interpreter --- src/jit/jit-core.c | 4 ++++ src/jit/jit-dump.c | 3 ++- src/jit/jit-exits.c | 42 +++++++++++++++++++++++++++++++++++++++++ src/jit/jit-exits.h | 2 +- src/jit/jit-interp.c | 21 ++------------------- src/jit/jit-irgen.c | 45 +++++++++++++++++++++++++++++++++----------- src/jit/jit-priv.h | 2 ++ src/rt/model.c | 3 ++- 8 files changed, 89 insertions(+), 33 deletions(-) diff --git a/src/jit/jit-core.c b/src/jit/jit-core.c index fcf0312a..5b8abfe2 100644 --- a/src/jit/jit-core.c +++ b/src/jit/jit-core.c @@ -577,6 +577,10 @@ bool jit_try_call_packed(jit_t *j, jit_handle_t handle, jit_scalar_t context, void *input, size_t insz, void *output, size_t outsz) { jit_func_t *f = jit_get_func(j, handle); + + if (f->symbol == NULL && f->irbuf == NULL) + jit_irgen(f); // Ensure FFI spec is set + assert(f->spec != 0); ffi_type_t atype = (f->spec >> 8) & 0xf; diff --git a/src/jit/jit-dump.c b/src/jit/jit-dump.c index 0368031b..44b66ef5 100644 --- a/src/jit/jit-dump.c +++ b/src/jit/jit-dump.c @@ -67,7 +67,8 @@ const char *jit_exit_name(jit_exit_t exit) "FILE_READ", "FILE_WRITE", "ENDFILE", "STRCONVI", "STRCONVR", "CANON_VALUE", "DEBUG_OUT", "ALIAS_SIGNAL", "MAP_SIGNAL", "MAP_CONST", "RESOLVE_SIGNAL", "LAST_EVENT", "LAST_ACTIVE", - "DISCONNECT", "ELAB_ORDER_FAIL", "FORCE", "RELEASE" + "DISCONNECT", "ELAB_ORDER_FAIL", "FORCE", "RELEASE", "PUSH_SCOPE", + "POP_SCOPE", }; assert(exit < ARRAY_LEN(names)); return names[exit]; diff --git a/src/jit/jit-exits.c b/src/jit/jit-exits.c index 995376ad..2e1ce37b 100644 --- a/src/jit/jit-exits.c +++ b/src/jit/jit-exits.c @@ -520,6 +520,28 @@ DLLEXPORT void __nvc_do_exit(jit_exit_t which, jit_scalar_t *args) { switch (which) { + case JIT_EXIT_MAP_SIGNAL: + { + sig_shared_t *src_ss = args[0].pointer; + uint32_t src_offset = args[1].integer; + sig_shared_t *dst_ss = args[2].pointer; + uint32_t dst_offset = args[3].integer; + uint32_t src_count = args[4].integer; + uint32_t dst_count = args[5].integer; + jit_handle_t handle = args[6].integer; + void *context = args[7].pointer; + + if (handle != JIT_HANDLE_INVALID) { + ffi_closure_t closure = { handle, context }; + x_map_signal(src_ss, src_offset, dst_ss, dst_offset, src_count, + dst_count, &closure); + } + else + x_map_signal(src_ss, src_offset, dst_ss, dst_offset, src_count, + dst_count, NULL); + } + break; + case JIT_EXIT_INT_TO_STRING: { int64_t value = args[0].integer; @@ -580,6 +602,26 @@ void __nvc_do_exit(jit_exit_t which, jit_scalar_t *args) } break; + case JIT_EXIT_PUSH_SCOPE: + { + if (!jit_has_runtime(jit_for_thread())) + return; // Called during constant folding + + tree_t where = args[0].pointer; + int32_t size = args[1].integer; + + x_push_scope(where, size); + } + break; + + case JIT_EXIT_POP_SCOPE: + { + if (!jit_has_runtime(jit_for_thread())) + return; // Called during constant folding + + x_pop_scope(); + } + break; default: fatal_trace("unhandled exit %s", jit_exit_name(which)); } diff --git a/src/jit/jit-exits.h b/src/jit/jit-exits.h index f1b26462..92593ed9 100644 --- a/src/jit/jit-exits.h +++ b/src/jit/jit-exits.h @@ -89,7 +89,7 @@ void x_force(sig_shared_t *ss, uint32_t offset, int32_t count, void *values); void x_release(sig_shared_t *ss, uint32_t offset, int32_t count); void x_resolve_signal(sig_shared_t *ss, rt_resolution_t *resolution); void x_resolve_signal2(sig_shared_t *ss, jit_handle_t handle, void *context, - int32_t ileft, int32_t nlits); + int32_t ileft, int32_t nlits, int32_t flags); void x_elab_order_fail(tree_t where); void x_unreachable(tree_t where); void *x_mspace_alloc(uint32_t size, uint32_t nelems); diff --git a/src/jit/jit-interp.c b/src/jit/jit-interp.c index 787f093a..14ccf834 100644 --- a/src/jit/jit-interp.c +++ b/src/jit/jit-interp.c @@ -1025,20 +1025,6 @@ static void interp_alias_signal(jit_interp_t *state) x_alias_signal(ss, where); } -static void interp_map_signal(jit_interp_t *state) -{ - sig_shared_t *src_ss = state->args[0].pointer; - uint32_t src_offset = state->args[1].integer; - sig_shared_t *dst_ss = state->args[2].pointer; - uint32_t dst_offset = state->args[3].integer; - uint32_t src_count = state->args[4].integer; - uint32_t dst_count = state->args[5].integer; - ffi_closure_t *closure = state->args[6].pointer; - - x_map_signal(src_ss, src_offset, dst_ss, dst_offset, src_count, - dst_count, closure); -} - static void interp_map_const(jit_interp_t *state) { sig_shared_t *dst_ss = state->args[0].pointer; @@ -1062,8 +1048,9 @@ static void interp_resolve_signal(jit_interp_t *state) void *context = state->args[2].pointer; int32_t ileft = state->args[3].integer; int32_t nlits = state->args[4].integer; + int32_t flags = state->args[5].integer; - x_resolve_signal2(shared, handle, context, ileft, nlits); + x_resolve_signal2(shared, handle, context, ileft, nlits, flags); } static void interp_last_event(jit_interp_t *state) @@ -1205,10 +1192,6 @@ static void interp_exit(jit_interp_t *state, jit_ir_t *ir) interp_alias_signal(state); break; - case JIT_EXIT_MAP_SIGNAL: - interp_map_signal(state); - break; - case JIT_EXIT_MAP_CONST: interp_map_const(state); break; diff --git a/src/jit/jit-irgen.c b/src/jit/jit-irgen.c index 5e96b756..2e2ed7ad 100644 --- a/src/jit/jit-irgen.c +++ b/src/jit/jit-irgen.c @@ -620,8 +620,8 @@ static int irgen_slots_for_type(vcode_type_t vtype) // Function pointer, context return 2; case VCODE_TYPE_RESOLUTION: - // Closure slots plus left and nlits (this is silly) - return 4; + // Closure slots plus left, nlits, and flags (this is silly) + return 5; default: // Passed by pointer or fits in 64-bit register return 1; @@ -2420,7 +2420,17 @@ static void irgen_op_resolution_wrapper(jit_irgen_t *g, int op) jit_reg_t nlits = irgen_alloc_reg(g); j_mov(g, nlits, irgen_get_arg(g, op, 2)); - g->map[vcode_get_result(op)] = jit_value_from_reg(base); + vcode_reg_t result = vcode_get_result(op); + vcode_type_t type = vtype_base(vcode_reg_type(result)); + + uint32_t flagbits = 0; + if (vtype_kind(type) == VCODE_TYPE_POINTER) + flagbits |= R_COMPOSITE; + + jit_reg_t flags = irgen_alloc_reg(g); + j_mov(g, flags, jit_value_from_int64(flagbits)); + + g->map[result] = jit_value_from_reg(base); } static void irgen_op_init_signal(jit_irgen_t *g, int op) @@ -2476,11 +2486,15 @@ static void irgen_op_map_signal(jit_irgen_t *g, int op) jit_value_t src_count = irgen_get_arg(g, op, 2); jit_value_t dst_count = irgen_get_arg(g, op, 3); - jit_value_t closure; - if (vcode_count_args(op) == 5) + jit_value_t closure, context; + if (vcode_count_args(op) == 5) { closure = irgen_get_arg(g, op, 4); - else - closure = jit_null_ptr(); + context = jit_value_from_reg(jit_value_as_reg(closure) + 1); + } + else { + closure = jit_value_from_handle(JIT_HANDLE_INVALID); + context = jit_null_ptr(); + } j_send(g, 0, src_ss); j_send(g, 1, src_off); @@ -2489,6 +2503,7 @@ static void irgen_op_map_signal(jit_irgen_t *g, int op) j_send(g, 4, src_count); j_send(g, 5, dst_count); j_send(g, 6, closure); + j_send(g, 7, context); macro_exit(g, JIT_EXIT_MAP_SIGNAL); } @@ -2517,14 +2532,16 @@ static void irgen_op_resolve_signal(jit_irgen_t *g, int op) jit_value_t resfn = irgen_get_arg(g, op, 1); jit_reg_t base = jit_value_as_reg(resfn); jit_value_t context = jit_value_from_reg(base + 1); - jit_value_t ileft = jit_value_from_reg(base + 3); - jit_value_t nlits = jit_value_from_reg(base + 4); + jit_value_t ileft = jit_value_from_reg(base + 2); + jit_value_t nlits = jit_value_from_reg(base + 3); + jit_value_t flags = jit_value_from_reg(base + 4); j_send(g, 0, shared); j_send(g, 1, resfn); j_send(g, 2, context); j_send(g, 3, ileft); j_send(g, 4, nlits); + j_send(g, 5, flags); macro_exit(g, JIT_EXIT_RESOLVE_SIGNAL); } @@ -2702,12 +2719,18 @@ static void irgen_op_endfile(jit_irgen_t *g, int op) static void irgen_op_push_scope(jit_irgen_t *g, int op) { - // No-op + jit_value_t locus = irgen_get_arg(g, op, 0); + j_send(g, 0, locus); + + const int size = irgen_size_bytes(vcode_get_type(op)); + j_send(g, 1, jit_value_from_int64(size)); + + macro_exit(g, JIT_EXIT_PUSH_SCOPE); } static void irgen_op_pop_scope(jit_irgen_t *g, int op) { - // No-op + macro_exit(g, JIT_EXIT_POP_SCOPE); } static void irgen_op_drive_signal(jit_irgen_t *g, int op) diff --git a/src/jit/jit-priv.h b/src/jit/jit-priv.h index 790e81d5..5d445440 100644 --- a/src/jit/jit-priv.h +++ b/src/jit/jit-priv.h @@ -136,6 +136,8 @@ typedef enum { JIT_EXIT_ELAB_ORDER_FAIL, JIT_EXIT_FORCE, JIT_EXIT_RELEASE, + JIT_EXIT_PUSH_SCOPE, + JIT_EXIT_POP_SCOPE, } jit_exit_t; typedef uint16_t jit_reg_t; diff --git a/src/rt/model.c b/src/rt/model.c index ecc699a1..ee79d611 100644 --- a/src/rt/model.c +++ b/src/rt/model.c @@ -3248,7 +3248,7 @@ void x_resolve_signal(sig_shared_t *ss, rt_resolution_t *resolution) } void x_resolve_signal2(sig_shared_t *ss, jit_handle_t handle, void *context, - int32_t ileft, int32_t nlits) + int32_t ileft, int32_t nlits, int32_t flags) { rt_resolution_t resolution = { .closure = { @@ -3257,6 +3257,7 @@ void x_resolve_signal2(sig_shared_t *ss, jit_handle_t handle, void *context, }, .ileft = ileft, .nlits = nlits, + .flags = flags, }; x_resolve_signal(ss, &resolution); -- 2.39.2