aboutsummaryrefslogtreecommitdiffstats
path: root/core/module-jit.c
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-10-05 08:41:45 +0100
committereunhhu <[email protected]>2026-10-05 08:41:45 +0100
commit1ef9dd24773058f766ad80ffc7a59295fc44c92d (patch)
tree1fd00811ed87ff2976b1698d0dbed4873b44adc3 /core/module-jit.c
parentc1d1fdde86832f8c8528135975b660b00f1a3678 (diff)
downloadpure-1ef9dd24773058f766ad80ffc7a59295fc44c92d.tar.gz
pure-1ef9dd24773058f766ad80ffc7a59295fc44c92d.zip
Compile only blocks with a loop, keep no code for a module without one, set a frame's fields one by one, and inline group_of (021)
- Compiled code paid only where blocks repeat; a block run once (a view's cell, a fold's item, most handlers) ran slower through the code's entry and its calls of step: the bank's table queries took 16-24% more instructions. Now only a block with an EACH or a LOOP is compiled, and a module with none keeps no compiled code. - run() set its whole frame each time (the compiled code's run among it); now its fields one by one. - group_of is inlined into its pass: after the executor's refactor it was a call per row (per_branch +4-5% instructions; now +1.1-1.3%).
Diffstat (limited to 'core/module-jit.c')
-rw-r--r--core/module-jit.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/core/module-jit.c b/core/module-jit.c
index 8e50eb0..49c763f 100644
--- a/core/module-jit.c
+++ b/core/module-jit.c
@@ -730,8 +730,18 @@ static bool compile_block(const PureModule *m, PureBlock block, unsigned end_hei
typedef struct { PureBlock block; unsigned leaves; size_t entry; } Made;
-/* A block to make, leaving leaves values on the stack. */
-static bool want(PureBlock block, unsigned leaves, Made **made, size_t *count, size_t *room) {
+/* Whether a block has a loop: compiled code pays where blocks repeat; a
+ * short block runs once (a view's cell, a fold's item, most handlers) as
+ * fast in the executor, without the code's entry and its calls of step. */
+static bool loops_in(const PureModule *m, PureBlock block) {
+ for (uint32_t pc = block.start; pc < block.start + block.length; ++pc)
+ if (m->code[pc].op == PURE_OP_EACH || m->code[pc].op == PURE_OP_LOOP) return true;
+ return false;
+}
+
+/* A block to make (one with a loop), leaving leaves values on the stack. */
+static bool want(const PureModule *m, PureBlock block, unsigned leaves, Made **made, size_t *count, size_t *room) {
+ if (!loops_in(m, block)) return true;
for (size_t i = 0; i < *count; ++i)
if ((*made)[i].block.start == block.start && (*made)[i].block.length == block.length) return true;
if (!grow_array((void **)made, room, *count + 1, sizeof(**made))) return false;
@@ -746,17 +756,21 @@ struct PureJit *pure_jit_make(const PureModule *m) {
size_t count = 0, room = 0;
bool ok = true;
/* The handlers' and the views' code, then the folds' blocks in what is made (they run as blocks of their own). */
- for (uint32_t h = 0; ok && h < m->handlers; ++h) ok = want(m->handler[h].code, 0, &made, &count, &room);
+ for (uint32_t h = 0; ok && h < m->handlers; ++h) ok = want(m, m->handler[h].code, 0, &made, &count, &room);
for (uint32_t v = 0; ok && v < m->views; ++v)
- if (m->view_code[v].length) ok = want(m->view_code[v], 1, &made, &count, &room);
+ if (m->view_code[v].length) ok = want(m, m->view_code[v], 1, &made, &count, &room);
for (size_t i = 0; ok && i < count; ++i)
for (uint32_t pc = made[i].block.start; ok && pc < made[i].block.start + made[i].block.length; ++pc) {
const PureOp *op = &m->code[pc];
unsigned how = op->arg & PURE_FOLD_KIND; /* count and first leave a bool; the others a value and a bool */
if (op->op == PURE_OP_FOLD)
- ok = want((PureBlock){pc + 1, op->arg >> 16}, how == PURE_FOLD_COUNT || how == PURE_FOLD_FIRST ? 1 : 2, &made, &count,
- &room);
+ ok = want(m, (PureBlock){pc + 1, op->arg >> 16}, how == PURE_FOLD_COUNT || how == PURE_FOLD_FIRST ? 1 : 2, &made,
+ &count, &room);
}
+ if (ok && !count) { /* nothing worth it: run() then looks for no code at all */
+ free(made);
+ return NULL;
+ }
Emit e = {0};
for (size_t i = 0; ok && i < count; ++i) ok = compile_block(m, made[i].block, made[i].leaves, &e, &made[i].entry);
ok = ok && resolve(&e);