Skip to content

Commit

Permalink
Rework implementation of conversions in port maps. Issue #843
Browse files Browse the repository at this point in the history
  • Loading branch information
nickg committed Jan 26, 2024
1 parent 84bc518 commit b50158a
Show file tree
Hide file tree
Showing 20 changed files with 709 additions and 287 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
command uses to compile third-party libraries (#836).
- The prefix of an indexed or slice name now must be another name or
function call, as required by the LRM (#835).
- The implementation of conversions in port maps has been reworked and
fixes a number of long-standing issues (#843).

## Version 1.11.2 - 2024-01-04
- Fixed an incorrect length check in the equivalent process for
Expand Down
3 changes: 3 additions & 0 deletions src/jit/jit-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,9 @@ static void jit_emit_trace(diag_t *d, const loc_t *loc, object_t *enclosing,
case T_WAVEFORM:
diag_trace(d, loc, "Equivalent process");
break;
case T_TYPE_CONV:
diag_trace(d, loc, "Type conversion %s", type_pp(tree_type(tree)));
break;
default:
diag_trace(d, loc, "$$%s", istr(tree_ident(tree)));
break;
Expand Down
1 change: 1 addition & 0 deletions src/jit/jit-dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ const char *jit_exit_name(jit_exit_t exit)
"DRIVING_VALUE", "CLAIM_TLAB", "COVER_TOGGLE", "PROCESS_INIT",
"CLEAR_EVENT", "IMPLICIT_EVENT", "ENTER_STATE", "REFLECT_VALUE",
"REFLECT_SUBTYPE", "FUNCTION_TRIGGER", "ADD_TRIGGER", "TRANSFER_SIGNAL",
"PORT_CONVERSION", "CONVERT_IN", "CONVERT_OUT",
};
assert(exit < ARRAY_LEN(names));
return names[exit];
Expand Down
52 changes: 40 additions & 12 deletions src/jit/jit-exits.c
Original file line number Diff line number Diff line change
Expand Up @@ -578,19 +578,9 @@ void __nvc_do_exit(jit_exit_t which, jit_anchor_t *anchor, jit_scalar_t *args,
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;
uint32_t count = args[4].integer;

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);
x_map_signal(src_ss, src_offset, dst_ss, dst_offset, count);
}
break;

Expand Down Expand Up @@ -1007,6 +997,44 @@ void __nvc_do_exit(jit_exit_t which, jit_anchor_t *anchor, jit_scalar_t *args,
}
break;

case JIT_EXIT_PORT_CONVERSION:
{
jit_handle_t handle = args[0].integer;
void *context = args[1].pointer;

if (jit_has_runtime(thread->jit)) {
ffi_closure_t closure = { handle, context };
args[0].pointer = x_port_conversion(&closure);
}
else
args[0].pointer = NULL; // Called during constant folding
}
break;

case JIT_EXIT_CONVERT_IN:
{
void *conv = args[0].pointer;
sig_shared_t *shared = args[1].pointer;
int32_t offset = args[2].integer;
int32_t count = args[3].integer;

if (conv != NULL)
x_convert_in(conv, shared, offset, count);
}
break;

case JIT_EXIT_CONVERT_OUT:
{
void *conv = args[0].pointer;
sig_shared_t *shared = args[1].pointer;
int32_t offset = args[2].integer;
int32_t count = args[3].integer;

if (conv != NULL)
x_convert_out(conv, shared, offset, count);
}
break;

default:
fatal_trace("unhandled exit %s", jit_exit_name(which));
}
Expand Down
7 changes: 4 additions & 3 deletions src/jit/jit-exits.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ void x_report(const uint8_t *msg, int32_t msg_len, int8_t severity,
int64_t x_last_event(sig_shared_t *ss, uint32_t offset, int32_t count);
int64_t x_last_active(sig_shared_t *ss, uint32_t offset, int32_t count);
void x_map_signal(sig_shared_t *src_ss, uint32_t src_offset,
sig_shared_t *dst_ss, uint32_t dst_offset,
uint32_t src_count, uint32_t dst_count,
ffi_closure_t *closure);
sig_shared_t *dst_ss, uint32_t dst_offset, uint32_t count);
void x_map_const(sig_shared_t *ss, uint32_t offset,
const uint8_t *values, uint32_t count);
void x_push_scope(tree_t where, int32_t size);
Expand Down Expand Up @@ -96,5 +94,8 @@ void *x_reflect_subtype(void *context, tree_t where,
const jit_scalar_t *bounds);
void *x_function_trigger(const ffi_closure_t *closure);
void x_add_trigger(void *ptr);
void *x_port_conversion(const ffi_closure_t *closure);
void x_convert_in(void *ptr, sig_shared_t *ss, uint32_t offset, int32_t count);
void x_convert_out(void *ptr, sig_shared_t *ss, uint32_t offset, int32_t count);

#endif // _JIT_EXITS_H
75 changes: 55 additions & 20 deletions src/jit/jit-irgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -2791,31 +2791,17 @@ static void irgen_op_alias_signal(jit_irgen_t *g, int op)

static void irgen_op_map_signal(jit_irgen_t *g, int op)
{
jit_value_t src_ss = irgen_get_arg(g, op, 0);
jit_value_t src_off = jit_value_from_reg(jit_value_as_reg(src_ss) + 1);
jit_value_t dst_ss = irgen_get_arg(g, op, 1);
jit_value_t dst_off = jit_value_from_reg(jit_value_as_reg(dst_ss) + 1);
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, context;
if (vcode_count_args(op) == 5) {
closure = irgen_get_arg(g, op, 4);
context = jit_value_from_reg(jit_value_as_reg(closure) + 1);
}
else {
closure = jit_value_from_handle(JIT_HANDLE_INVALID);
context = jit_null_ptr();
}
jit_value_t src_ss = irgen_get_arg(g, op, 0);
jit_value_t src_off = jit_value_from_reg(jit_value_as_reg(src_ss) + 1);
jit_value_t dst_ss = irgen_get_arg(g, op, 1);
jit_value_t dst_off = jit_value_from_reg(jit_value_as_reg(dst_ss) + 1);
jit_value_t count = irgen_get_arg(g, op, 2);

j_send(g, 0, src_ss);
j_send(g, 1, src_off);
j_send(g, 2, dst_ss);
j_send(g, 3, dst_off);
j_send(g, 4, src_count);
j_send(g, 5, dst_count);
j_send(g, 6, closure);
j_send(g, 7, context);
j_send(g, 4, count);

macro_exit(g, JIT_EXIT_MAP_SIGNAL);
}
Expand Down Expand Up @@ -3471,6 +3457,46 @@ static void irgen_op_add_trigger(jit_irgen_t *g, int op)
macro_exit(g, JIT_EXIT_ADD_TRIGGER);
}

static void irgen_op_port_conversion(jit_irgen_t *g, int op)
{
jit_value_t closure = irgen_get_arg(g, op, 0);
jit_value_t context = jit_value_from_reg(jit_value_as_reg(closure) + 1);

j_send(g, 0, closure);
j_send(g, 1, context);
macro_exit(g, JIT_EXIT_PORT_CONVERSION);

g->map[vcode_get_result(op)] = j_recv(g, 0);
}

static void irgen_op_convert_in(jit_irgen_t *g, int op)
{
jit_value_t conv = irgen_get_arg(g, op, 0);
jit_value_t shared = irgen_get_arg(g, op, 1);
jit_value_t offset = jit_value_from_reg(jit_value_as_reg(shared) + 1);
jit_value_t count = irgen_get_arg(g, op, 2);

j_send(g, 0, conv);
j_send(g, 1, shared);
j_send(g, 2, offset);
j_send(g, 3, count);
macro_exit(g, JIT_EXIT_CONVERT_IN);
}

static void irgen_op_convert_out(jit_irgen_t *g, int op)
{
jit_value_t conv = irgen_get_arg(g, op, 0);
jit_value_t shared = irgen_get_arg(g, op, 1);
jit_value_t offset = jit_value_from_reg(jit_value_as_reg(shared) + 1);
jit_value_t count = irgen_get_arg(g, op, 2);

j_send(g, 0, conv);
j_send(g, 1, shared);
j_send(g, 2, offset);
j_send(g, 3, count);
macro_exit(g, JIT_EXIT_CONVERT_OUT);
}

static void irgen_block(jit_irgen_t *g, vcode_block_t block)
{
vcode_select_block(block);
Expand Down Expand Up @@ -3854,6 +3880,15 @@ static void irgen_block(jit_irgen_t *g, vcode_block_t block)
case VCODE_OP_ADD_TRIGGER:
irgen_op_add_trigger(g, i);
break;
case VCODE_OP_PORT_CONVERSION:
irgen_op_port_conversion(g, i);
break;
case VCODE_OP_CONVERT_IN:
irgen_op_convert_in(g, i);
break;
case VCODE_OP_CONVERT_OUT:
irgen_op_convert_out(g, i);
break;
default:
fatal_trace("cannot generate JIT IR for vcode op %s",
vcode_op_string(op));
Expand Down
3 changes: 3 additions & 0 deletions src/jit/jit-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ typedef enum {
JIT_EXIT_FUNCTION_TRIGGER,
JIT_EXIT_ADD_TRIGGER,
JIT_EXIT_TRANSFER_SIGNAL,
JIT_EXIT_PORT_CONVERSION,
JIT_EXIT_CONVERT_IN,
JIT_EXIT_CONVERT_OUT,
} jit_exit_t;

typedef uint16_t jit_reg_t;
Expand Down
Loading

0 comments on commit b50158a

Please sign in to comment.