diff options
author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-10-22 17:40:09 +0300 |
---|---|---|
committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-10-22 17:43:44 +0300 |
commit | 7f7b22674ed8e9633cd0e47662508c3641e9f967 (patch) | |
tree | 6e692c9ec8f6cb0672f626d5be54601ec23aef63 /src/compile/compile.c | |
parent | 60a53db87421667a268f60b58c5a02eebb289d6b (diff) | |
download | ejit-7f7b22674ed8e9633cd0e47662508c3641e9f967.tar.gz ejit-7f7b22674ed8e9633cd0e47662508c3641e9f967.zip |
use type-specific vectors instead of generic ones
+ An attempt at speeding up function calls in the interpreted mode
Diffstat (limited to 'src/compile/compile.c')
-rw-r--r-- | src/compile/compile.c | 223 |
1 files changed, 117 insertions, 106 deletions
diff --git a/src/compile/compile.c b/src/compile/compile.c index 929dfa1..804a29f 100644 --- a/src/compile/compile.c +++ b/src/compile/compile.c @@ -2,6 +2,23 @@ #include "../../deps/lightening/lightening/lightening.c" #include "../common.h" +#define VEC_TYPE jit_operand_t +#define VEC_NAME operands +#include "../vec.h" + +struct reloc_helper { + jit_reloc_t r; + size_t to; +}; + +#define VEC_TYPE struct reloc_helper +#define VEC_NAME relocs +#include "../vec.h" + +#define VEC_TYPE jit_addr_t +#define VEC_NAME addrs +#include "../vec.h" + static void *alloc_arena(size_t size) { return mmap(NULL, size, @@ -44,11 +61,6 @@ static jit_off_t stack_loc_f(struct ejit_func *f, size_t l) } -struct reloc_helper { - jit_reloc_t r; - size_t to; -}; - static jit_gpr_t getloc(struct ejit_func *f, jit_state_t *j, size_t l, size_t i) { (void)(f); @@ -131,9 +143,9 @@ static void putloc_d(struct ejit_func *f, jit_state_t *j, size_t l, jit_fpr_t r) jit_stxi_d(j, stack_loc_f(f, l), JIT_SP, r); } -static void compile_label(jit_state_t *j, size_t ii, struct vec *labels) +static void compile_label(jit_state_t *j, size_t ii, struct addrs *addrs) { - vect_at(jit_addr_t, *labels, ii) = jit_address(j); + *addrs_at(addrs, ii) = jit_address(j); } static void compile_movi(struct ejit_func *f, jit_state_t *j, @@ -1218,280 +1230,280 @@ static void compile_gtr_f(struct ejit_func *f, jit_state_t *j, } static void compile_bmci(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_bmci(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bmcr(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_bmcr(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bmsi(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_bmsi(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bmsr(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_bmsr(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_beqi(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_beqi(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_beqr(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_beqr(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_beqr_f(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_f(f, j, i.r1, 0); jit_fpr_t r2 = getloc_f(f, j, i.r2, 1); jit_reloc_t r = jit_beqr_f(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_beqr_d(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_d(f, j, i.r1, 0); jit_fpr_t r2 = getloc_d(f, j, i.r2, 1); jit_reloc_t r = jit_beqr_d(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bnei(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_bnei(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bner(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_bner(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bner_f(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_f(f, j, i.r1, 0); jit_fpr_t r2 = getloc_f(f, j, i.r2, 1); jit_reloc_t r = jit_bner_f(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bner_d(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_d(f, j, i.r1, 0); jit_fpr_t r2 = getloc_d(f, j, i.r2, 1); jit_reloc_t r = jit_bner_d(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bger(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_bger(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bger_u(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_bger_u(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgei(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_bgei(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgei_u(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_bgei_u(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bger_f(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_f(f, j, i.r1, 0); jit_fpr_t r2 = getloc_f(f, j, i.r2, 1); jit_reloc_t r = jit_bger_f(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bger_d(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_d(f, j, i.r1, 0); jit_fpr_t r2 = getloc_d(f, j, i.r2, 1); jit_reloc_t r = jit_bger_d(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgtr(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_bgtr(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgtr_u(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_gpr_t r2 = getloc(f, j, i.r2, 1); jit_reloc_t r = jit_bgtr_u(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgti(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_bgti(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgti_u(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_bgti_u(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgtr_f(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_f(f, j, i.r1, 0); jit_fpr_t r2 = getloc_f(f, j, i.r2, 1); jit_reloc_t r = jit_bgtr_f(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_bgtr_d(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_fpr_t r1 = getloc_d(f, j, i.r1, 0); jit_fpr_t r2 = getloc_d(f, j, i.r2, 1); jit_reloc_t r = jit_bgtr_d(j, r1, r2); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_blei(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_blei(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_blei_u(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_blei_u(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_blti(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_blti(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_blti_u(struct ejit_func *f, jit_state_t *j, - struct ejit_insn i, struct vec *relocs) + struct ejit_insn i, struct relocs *relocs) { jit_gpr_t r1 = getloc(f, j, i.r1, 0); jit_reloc_t r = jit_blti_u(j, r1, i.o); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_jmp(struct ejit_func *f, jit_state_t *j, struct ejit_insn i, - struct vec *relocs) + struct relocs *relocs) { (void)(f); jit_reloc_t r = jit_jmp(j); struct reloc_helper h = {.r = r, .to = i.r0}; - vect_append(struct reloc_helper, *relocs, &h); + relocs_append(relocs, h); } static void compile_retval(struct ejit_func *f, jit_state_t *j, @@ -1573,23 +1585,23 @@ static jit_off_t type_offset(struct ejit_insn i) type); } -static void fixup_operands(struct vec *operands, size_t fixup) +static void fixup_operands(struct operands *operands, size_t fixup) { foreach_vec(i, *operands) { - jit_operand_t op = vect_at(jit_operand_t, *operands, i); + jit_operand_t op = *operands_at(operands, i); if (op.kind != JIT_OPERAND_KIND_MEM) continue; op.loc.mem.offset += fixup; - vect_at(jit_operand_t, *operands, i) = op; + *operands_at(operands, i) = op; } } -static void compile_imm_call(jit_state_t *j, struct vec *src, struct vec *dst, +static void compile_imm_call(jit_state_t *j, struct operands *src, struct operands *dst, void *addr, size_t argc, jit_operand_t args[argc]) { /* each move is type + arg, so twofold */ - size_t movec = vec_len(src) / 2; + size_t movec = operands_len(src) / 2; size_t fixup = jit_align_stack(j, movec * sizeof(struct ejit_arg)); fixup_operands(src, fixup); /* note, do not fix up destination! */ @@ -1598,8 +1610,8 @@ static void compile_imm_call(jit_state_t *j, struct vec *src, struct vec *dst, jit_calli(j, addr, argc, args); jit_shrink_stack(j, fixup); - vec_reset(src); - vec_reset(dst); + operands_reset(src); + operands_reset(dst); } static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, @@ -1618,24 +1630,24 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, size_t stack = jit_align_stack(j, stack_size(f)); - struct vec src = vec_create(sizeof(jit_operand_t)); - struct vec dst = vec_create(sizeof(jit_operand_t)); + struct operands src = operands_create(); + struct operands dst = operands_create(); - struct vec relocs = vec_create(sizeof(struct reloc_helper)); - struct vec labels = vec_create(sizeof(jit_addr_t)); - vec_reserve(&labels, vec_len(&f->insns)); + struct relocs relocs = relocs_create(sizeof(struct reloc_helper)); + struct addrs addrs = addrs_create(); + addrs_reserve(&addrs, insns_len(&f->insns)); size_t label = 0; foreach_vec(ii, f->insns) { /* if we've hit a label, add it to our vector of label addresses */ - if (label < vec_len(&f->labels)) { - if (vect_at(size_t, f->labels, label) == ii) { - compile_label(j, ii, &labels); + if (label < labels_len(&f->labels)) { + if (*labels_at(&f->labels, label) == ii) { + compile_label(j, ii, &addrs); label++; } } - struct ejit_insn i = vect_at(struct ejit_insn, f->insns, ii); + struct ejit_insn i = *insns_at(&f->insns, ii); switch (i.op) { case MOVR: compile_movr(f, j, i); break; case MOVR_F: compile_movr_f(f, j, i); break; @@ -1832,8 +1844,8 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, JIT_SP, stack_loc(i.r2)); } - vec_append(&src, &type); - vec_append(&src, &arg); + operands_append(&src, type); + operands_append(&src, arg); jit_operand_t to[2] = { jit_operand_mem(JIT_OPERAND_ABI_WORD, JIT_SP, @@ -1842,8 +1854,8 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, arg_offset(i)) }; - vec_append(&dst, &to[0]); - vec_append(&dst, &to[1]); + operands_append(&dst, to[0]); + operands_append(&dst, to[1]); break; } @@ -1864,8 +1876,8 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, stack_loc_f(f, i.r2)); } - vec_append(&src, &type); - vec_append(&src, &arg); + operands_append(&src, type); + operands_append(&src, arg); jit_operand_t to[2] = { jit_operand_mem(JIT_OPERAND_ABI_WORD, JIT_SP, @@ -1874,15 +1886,15 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, arg_offset(i)) }; - vec_append(&dst, &to[0]); - vec_append(&dst, &to[1]); + operands_append(&dst, to[0]); + operands_append(&dst, to[1]); break; } case ESCAPEI: { jit_operand_t args[2] = { jit_operand_imm(JIT_OPERAND_ABI_WORD, - vec_len(&src) / 2), + operands_len(&src) / 2), jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_SP) }; compile_imm_call(j, &src, &dst, (void *)i.o, 2, args); @@ -1892,7 +1904,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, case ESCAPEI_F: { jit_operand_t args[2] = { jit_operand_imm(JIT_OPERAND_ABI_WORD, - vec_len(&src) / 2), + operands_len(&src) / 2), jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_SP) }; compile_imm_call(j, &src, &dst, (void *)i.o, 2, args); @@ -1903,7 +1915,7 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, jit_operand_t args[3] = { jit_operand_imm(JIT_OPERAND_ABI_POINTER, i.o), jit_operand_imm(JIT_OPERAND_ABI_WORD, - vec_len(&src) / 2), + operands_len(&src) / 2), jit_operand_gpr(JIT_OPERAND_ABI_POINTER, JIT_SP) }; compile_imm_call(j, &src, &dst, ejit_run_func, 3, args); @@ -1978,8 +1990,8 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, stack_loc_f(f, i.r2)); } - vec_append(&src, &from); - vec_append(&dst, &to); + operands_append(&src, from); + operands_append(&dst, to); break; } @@ -2003,17 +2015,17 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, stack_loc(i.r2)); } - vec_append(&src, &from); - vec_append(&dst, &to); + operands_append(&src, from); + operands_append(&dst, to); break; } case START: { /* parameters should be done by now */ - jit_move_operands(j, dst.buf, src.buf, vec_len(&src)); + jit_move_operands(j, dst.buf, src.buf, operands_len(&src)); /* reuse for arguments */ - vec_reset(&dst); - vec_reset(&src); + operands_reset(&dst); + operands_reset(&src); break; } @@ -2022,19 +2034,18 @@ static size_t compile_fn_body(struct ejit_func *f, jit_state_t *j, void *arena, } foreach_vec(ri, relocs) { - struct reloc_helper h = vect_at(struct reloc_helper, relocs, - ri); - jit_addr_t a = vect_at(jit_addr_t, labels, h.to); + struct reloc_helper h = *relocs_at(&relocs, ri); + jit_addr_t a = *addrs_at(&addrs, h.to); jit_reloc_t r = h.r; assert(a); jit_patch_there(j, r, a); } - vec_destroy(&src); - vec_destroy(&dst); - vec_destroy(&relocs); - vec_destroy(&labels); + operands_destroy(&src); + operands_destroy(&dst); + relocs_destroy(&relocs); + addrs_destroy(&addrs); if (jit_end(j, &size)) return 0; |