From 2249ff58592581e8971c680dd581a88c68960623 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 23 Oct 2022 14:24:56 +0100 Subject: [PATCH] Add JIT support for guarded signals --- src/jit/jit-dump.c | 6 +++- src/jit/jit-exits.c | 41 +++++++++++++++++++++++++ src/jit/jit-irgen.c | 75 +++++++++++++++++++++++++++++++++++++++++++-- src/jit/jit-priv.h | 3 ++ 4 files changed, 122 insertions(+), 3 deletions(-) diff --git a/src/jit/jit-dump.c b/src/jit/jit-dump.c index 44b66ef5..07be899e 100644 --- a/src/jit/jit-dump.c +++ b/src/jit/jit-dump.c @@ -25,6 +25,8 @@ #include #include +LCOV_EXCL_START + typedef struct { ihash_t *labels; int next_label; @@ -68,7 +70,7 @@ const char *jit_exit_name(jit_exit_t exit) "CANON_VALUE", "DEBUG_OUT", "ALIAS_SIGNAL", "MAP_SIGNAL", "MAP_CONST", "RESOLVE_SIGNAL", "LAST_EVENT", "LAST_ACTIVE", "DISCONNECT", "ELAB_ORDER_FAIL", "FORCE", "RELEASE", "PUSH_SCOPE", - "POP_SCOPE", + "POP_SCOPE", "IMPLICIT_SIGNAL", "DRIVING", "DRIVING_VALUE", }; assert(exit < ARRAY_LEN(names)); return names[exit]; @@ -368,3 +370,5 @@ void jit_hexdump(const unsigned char *data, size_t sz, int blocksz, printf("|\n"); } } + +LCOV_EXCL_STOP diff --git a/src/jit/jit-exits.c b/src/jit/jit-exits.c index 706c8eb8..4ea17910 100644 --- a/src/jit/jit-exits.c +++ b/src/jit/jit-exits.c @@ -576,6 +576,27 @@ void __nvc_do_exit(jit_exit_t which, jit_anchor_t *anchor, jit_scalar_t *args) } break; + case JIT_EXIT_IMPLICIT_SIGNAL: + { + int32_t count = args[0].integer; + int32_t size = args[1].integer; + tree_t where = args[2].pointer; + int32_t kind = args[3].integer; + jit_handle_t handle = args[4].integer; + void *context = args[5].pointer; + + sig_shared_t *ss; + if (!jit_has_runtime(thread->jit)) + ss = NULL; // Called during constant folding + else { + ffi_closure_t closure = { handle, context }; + ss = x_implicit_signal(count, size, where, kind, &closure); + } + + args[0].pointer = ss; + } + break; + case JIT_EXIT_RESOLVE_SIGNAL: { if (!jit_has_runtime(thread->jit)) @@ -1001,6 +1022,26 @@ void __nvc_do_exit(jit_exit_t which, jit_anchor_t *anchor, jit_scalar_t *args) } break; + case JIT_EXIT_DRIVING: + { + sig_shared_t *shared = args[0].pointer; + int32_t offset = args[1].integer; + int32_t count = args[2].integer; + + args[0].integer = x_driving(shared, offset, count); + } + break; + + case JIT_EXIT_DRIVING_VALUE: + { + sig_shared_t *shared = args[0].pointer; + int32_t offset = args[1].integer; + int32_t count = args[2].integer; + + args[0].pointer = x_driving_value(shared, offset, count); + } + break; + default: fatal_trace("unhandled exit %s", jit_exit_name(which)); } diff --git a/src/jit/jit-irgen.c b/src/jit/jit-irgen.c index 9b8c3f49..70f1f2cf 100644 --- a/src/jit/jit-irgen.c +++ b/src/jit/jit-irgen.c @@ -2468,6 +2468,31 @@ static void irgen_op_init_signal(jit_irgen_t *g, int op) j_mov(g, next, jit_value_from_int64(0)); } +static void irgen_op_implicit_signal(jit_irgen_t *g, int op) +{ + jit_value_t count = irgen_get_arg(g, op, 0); + jit_value_t size = irgen_get_arg(g, op, 1); + jit_value_t locus = irgen_get_arg(g, op, 2); + jit_value_t kind = irgen_get_arg(g, op, 3); + jit_value_t closure = irgen_get_arg(g, op, 4); + jit_value_t context = jit_value_from_reg(jit_value_as_reg(closure) + 1); + + j_send(g, 0, count); + j_send(g, 1, size); + j_send(g, 2, locus); + j_send(g, 3, kind); + j_send(g, 4, closure); + j_send(g, 5, context); + + macro_exit(g, JIT_EXIT_IMPLICIT_SIGNAL); + + g->map[vcode_get_result(op)] = j_recv(g, 0); + + // Offset into signal must be next sequential register + jit_reg_t next = irgen_alloc_reg(g); + j_mov(g, next, jit_value_from_int64(0)); +} + static void irgen_op_alias_signal(jit_irgen_t *g, int op) { jit_value_t shared = irgen_get_arg(g, op, 0); @@ -2872,13 +2897,15 @@ static void irgen_op_sched_static(jit_irgen_t *g, int op) jit_value_t offset = jit_value_from_reg(jit_value_as_reg(shared) + 1); jit_value_t count = irgen_get_arg(g, op, 1); - assert(vcode_count_args(op) == 2); // TODO: guarded signals + jit_value_t wake = jit_null_ptr(); + if (vcode_count_args(op) > 2) + wake = irgen_get_arg(g, op, 2); j_send(g, 0, shared); j_send(g, 1, offset); j_send(g, 2, count); j_send(g, 3, jit_value_from_int64(true)); - j_send(g, 4, jit_null_ptr()); + j_send(g, 4, wake); macro_exit(g, JIT_EXIT_SCHED_EVENT); } @@ -3021,6 +3048,41 @@ static void irgen_op_last_active(jit_irgen_t *g, int op) g->map[vcode_get_result(op)] = j_recv(g, 0); } +static void irgen_op_driving(jit_irgen_t *g, int op) +{ + jit_value_t shared = irgen_get_arg(g, op, 0); + jit_value_t offset = jit_value_from_reg(jit_value_as_reg(shared) + 1); + jit_value_t count = irgen_get_arg(g, op, 1); + + j_send(g, 0, shared); + j_send(g, 1, offset); + j_send(g, 2, count); + + macro_exit(g, JIT_EXIT_DRIVING); + + g->map[vcode_get_result(op)] = j_recv(g, 0); +} + +static void irgen_op_driving_value(jit_irgen_t *g, int op) +{ + jit_value_t shared = irgen_get_arg(g, op, 0); + jit_value_t offset = jit_value_from_reg(jit_value_as_reg(shared) + 1); + + jit_value_t count; + if (vcode_count_args(op) > 1) + count = irgen_get_arg(g, op, 1); + else + count = jit_value_from_int64(1); + + j_send(g, 0, shared); + j_send(g, 1, offset); + j_send(g, 2, count); + + macro_exit(g, JIT_EXIT_DRIVING_VALUE); + + g->map[vcode_get_result(op)] = j_recv(g, 0); +} + static void irgen_block(jit_irgen_t *g, vcode_block_t block) { vcode_select_block(block); @@ -3254,6 +3316,9 @@ static void irgen_block(jit_irgen_t *g, vcode_block_t block) case VCODE_OP_INIT_SIGNAL: irgen_op_init_signal(g, i); break; + case VCODE_OP_IMPLICIT_SIGNAL: + irgen_op_implicit_signal(g, i); + break; case VCODE_OP_ALIAS_SIGNAL: irgen_op_alias_signal(g, i); break; @@ -3359,6 +3424,12 @@ static void irgen_block(jit_irgen_t *g, vcode_block_t block) case VCODE_OP_LAST_ACTIVE: irgen_op_last_active(g, i); break; + case VCODE_OP_DRIVING: + irgen_op_driving(g, i); + break; + case VCODE_OP_DRIVING_VALUE: + irgen_op_driving_value(g, i); + break; default: fatal("cannot generate JIT IR for vcode op %s", vcode_op_string(op)); } diff --git a/src/jit/jit-priv.h b/src/jit/jit-priv.h index 7d7d33fa..c67cdcf1 100644 --- a/src/jit/jit-priv.h +++ b/src/jit/jit-priv.h @@ -141,6 +141,9 @@ typedef enum { JIT_EXIT_RELEASE, JIT_EXIT_PUSH_SCOPE, JIT_EXIT_POP_SCOPE, + JIT_EXIT_IMPLICIT_SIGNAL, + JIT_EXIT_DRIVING, + JIT_EXIT_DRIVING_VALUE, } jit_exit_t; typedef uint16_t jit_reg_t; -- 2.39.2