From 25e8e4ce5af8ef74a3d947c3f4b472597266f540 Mon Sep 17 00:00:00 2001 From: "kr.angelov" Date: Thu, 25 Sep 2014 10:35:06 +0000 Subject: [PATCH] now a complete JIT compiler and ByteCode compiler for the def rules in the abstract syntax. there might be some bugs yet to be found, meta variables and computation under lambda is only partially supported --- src/runtime/c/gu/mem.c | 3 +- src/runtime/c/gu/seq.c | 6 - src/runtime/c/gu/seq.h | 3 - src/runtime/c/pgf/data.h | 34 +- src/runtime/c/pgf/evaluator.c | 435 +++++------- src/runtime/c/pgf/evaluator.h | 91 ++- src/runtime/c/pgf/jit.c | 773 ++++++++++++++------- src/runtime/c/pgf/lightning/core-common.h | 8 +- src/runtime/c/pgf/lightning/i386/core-32.h | 12 +- src/runtime/c/pgf/lightning/i386/core-64.h | 9 +- src/runtime/c/pgf/reader.c | 4 +- src/runtime/c/pgf/reader.h | 3 + 12 files changed, 809 insertions(+), 572 deletions(-) diff --git a/src/runtime/c/gu/mem.c b/src/runtime/c/gu/mem.c index 62ffef85d..cc168637e 100644 --- a/src/runtime/c/gu/mem.c +++ b/src/runtime/c/gu/mem.c @@ -311,9 +311,8 @@ gu_pool_free(GuPool* pool) { GuFinalizerNode* node = pool->finalizers; while (node) { - GuFinalizerNode* next = node->next; node->fin->fn(node->fin); - node = next; + node = node->next; } GuMemChunk* chunk = pool->chunks; while (chunk) { diff --git a/src/runtime/c/gu/seq.c b/src/runtime/c/gu/seq.c index 2b99df318..2c3d6c3e3 100644 --- a/src/runtime/c/gu/seq.c +++ b/src/runtime/c/gu/seq.c @@ -136,12 +136,6 @@ gu_buf_data(GuBuf* buf) return &buf->seq->data; } -void* -gu_buf_last(GuBuf* buf) -{ - return buf->seq->data + buf->elem_size*(buf->seq->len-1); -} - GuSeq* gu_buf_data_seq(GuBuf* buf) { diff --git a/src/runtime/c/gu/seq.h b/src/runtime/c/gu/seq.h index 034620140..5accb0b24 100644 --- a/src/runtime/c/gu/seq.h +++ b/src/runtime/c/gu/seq.h @@ -65,9 +65,6 @@ gu_buf_avail(GuBuf* buf); void* gu_buf_data(GuBuf* buf); -void* -gu_buf_last(GuBuf* buf); - GuSeq* gu_buf_data_seq(GuBuf* buf); diff --git a/src/runtime/c/pgf/data.h b/src/runtime/c/pgf/data.h index dc6965174..8c9b577d9 100644 --- a/src/runtime/c/pgf/data.h +++ b/src/runtime/c/pgf/data.h @@ -76,7 +76,7 @@ typedef struct { PgfEquations* defns; // maybe null PgfExprProb ep; void* predicate; - void* function; + size_t closure_id; } PgfAbsFun; extern GU_DECLARE_TYPE(PgfAbsFun, abstract); @@ -95,31 +95,31 @@ typedef struct { extern GU_DECLARE_TYPE(PgfAbsCat, abstract); +typedef struct PgfEvalGates PgfEvalGates; + typedef struct { PgfCId name; PgfFlags* aflags; PgfCIdMap* funs; // |-> PgfAbsFun* PgfCIdMap* cats; // |-> PgfAbsCat* PgfAbsFun* abs_lin_fun; + PgfEvalGates* eval_gates; } PgfAbstr; typedef enum { - PGF_INSTR_ENTER, - PGF_INSTR_CASE, - PGF_INSTR_CASE_LIT, - PGF_INSTR_ALLOC, - PGF_INSTR_PUT_CONSTR, - PGF_INSTR_PUT_FUN, - PGF_INSTR_PUT_CLOSURE, - PGF_INSTR_PUT_LIT, - PGF_INSTR_SET, - PGF_INSTR_SET_PAD, - PGF_INSTR_PUSH, - PGF_INSTR_EVAL, - PGF_INSTR_CALL, - PGF_INSTR_FAIL, - PGF_INSTR_UPDATE, - PGF_INSTR_RET + PGF_INSTR_CHECK_ARGS = 0, + PGF_INSTR_CASE = 1, + PGF_INSTR_CASE_LIT = 2, + PGF_INSTR_ALLOC = 3, + PGF_INSTR_PUT_CONSTR = 4, + PGF_INSTR_PUT_CLOSURE = 5, + PGF_INSTR_PUT_LIT = 6, + PGF_INSTR_SET = 7, + PGF_INSTR_SET_PAD = 8, + PGF_INSTR_PUSH = 9, + PGF_INSTR_EVAL = 10, + PGF_INSTR_RET = 13, + PGF_INSTR_FAIL = 15 } PgfInstruction; struct PgfPGF { diff --git a/src/runtime/c/pgf/evaluator.c b/src/runtime/c/pgf/evaluator.c index a3f22e274..25a9158dc 100644 --- a/src/runtime/c/pgf/evaluator.c +++ b/src/runtime/c/pgf/evaluator.c @@ -1,288 +1,187 @@ #include "pgf/pgf.h" #include "pgf/data.h" #include "pgf/evaluator.h" +#include -typedef struct PgfEnv PgfEnv; - -struct PgfEnv { - PgfEnv* next; - PgfClosure* closure; -}; - -typedef struct { - PgfClosure header; - PgfEnv* env; - PgfExpr expr; -} PgfExprThunk; - -typedef struct { - PgfClosure header; - PgfClosure* val; -} PgfIndirection; - -typedef struct { - PgfClosure header; - int level; - size_t n_args; - PgfClosure* args[]; -} PgfValueGen; - -typedef struct { - PgfClosure header; - PgfEnv* env; - PgfMetaId id; - size_t n_args; - PgfClosure* args[]; -} PgfValueMeta; - -typedef struct { - PgfClosure header; - PgfLiteral lit; -} PgfValueLit; +#define PGF_ARGS_DELTA 5 PgfClosure* -pgf_evaluate_indirection(PgfEvalState* state, PgfClosure* closure) -{ - PgfIndirection* indir = (PgfIndirection*) closure; - return indir->val; -} - -PgfClosure* -pgf_evaluate_value(PgfEvalState* state, PgfClosure* closure) -{ - return closure; -} - -static PgfClosure* -pgf_evaluate_value_gen(PgfEvalState* state, PgfClosure* closure) -{ - PgfValueGen* val = (PgfValueGen*) closure; - - size_t n_args = val->n_args + gu_buf_length(state->stack); - PgfValueGen* new_val = - gu_new_flex(state->pool, PgfValueGen, args, n_args); - new_val->header.code = pgf_evaluate_value_gen; - new_val->level = val->level; - new_val->n_args = n_args; - - size_t i = 0; - while (i < val->n_args) { - new_val->args[i] = val->args[i]; - i++; - } - while (i < n_args) { - new_val->args[i] = gu_buf_pop(state->stack, PgfClosure*); - i++; - } - - return &new_val->header; -} - -static PgfClosure* -pgf_evaluate_value_meta(PgfEvalState* state, PgfClosure* closure) -{ - PgfValueMeta* val = (PgfValueMeta*) closure; - - size_t n_args = val->n_args + gu_buf_length(state->stack); - PgfValueMeta* new_val = - gu_new_flex(state->pool, PgfValueMeta, args, n_args); - new_val->header.code = pgf_evaluate_value_meta; - new_val->id = val->id; - new_val->n_args = n_args; - - size_t i = 0; - while (i < val->n_args) { - new_val->args[i] = val->args[i]; - i++; - } - while (i < n_args) { - val->args[i] = gu_buf_pop(state->stack, PgfClosure*); - i++; - } - - return &new_val->header; -} - -static PgfClosure* -pgf_evaluate_value_lit(PgfEvalState* state, PgfClosure* closure) -{ - return closure; -} - -static PgfClosure* pgf_evaluate_expr_thunk(PgfEvalState* state, PgfClosure* closure) { PgfExprThunk* thunk = (PgfExprThunk*) closure; PgfEnv* env = thunk->env; PgfExpr expr = thunk->expr; - for (;;) { - GuVariantInfo ei = gu_variant_open(expr); - switch (ei.tag) { - case PGF_EXPR_ABS: { - PgfExprAbs* eabs = ei.data; + size_t n_args = 0; + PgfClosure** args = NULL; + PgfClosure* res = NULL; - if (gu_buf_length(state->stack) > 0) { - PgfEnv* new_env = gu_new(PgfEnv, state->pool); - new_env->next = env; - new_env->closure = gu_buf_pop(state->stack, PgfClosure*); +repeat:; + GuVariantInfo ei = gu_variant_open(expr); + switch (ei.tag) { + case PGF_EXPR_ABS: { + PgfExprAbs* eabs = ei.data; - env = new_env; - expr = eabs->body; - } else { - thunk->expr = expr; - return closure; - } - break; + if (n_args > 0) { + PgfEnv* new_env = gu_new(PgfEnv, state->pool); + new_env->next = env; + new_env->closure = args[--n_args]; + + env = new_env; + expr = eabs->body; + goto repeat; + } else { + thunk->header.code = state->eval_gates->evaluate_value_lambda; + thunk->expr = eabs->body; + res = closure; } - case PGF_EXPR_APP: { - PgfExprApp* eapp = ei.data; - PgfExprThunk* thunk = - gu_new(PgfExprThunk, state->pool); - thunk->header.code = pgf_evaluate_expr_thunk; - thunk->env = env; - thunk->expr = eapp->arg; - gu_buf_push(state->stack, PgfClosure*, &thunk->header); - expr = eapp->fun; - break; + break; + } + case PGF_EXPR_APP: { + PgfExprApp* eapp = ei.data; + PgfExprThunk* thunk = + gu_new(PgfExprThunk, state->pool); + thunk->header.code = state->eval_gates->evaluate_expr_thunk; + thunk->env = env; + thunk->expr = eapp->arg; + + if (n_args % PGF_ARGS_DELTA == 0) { + args = realloc(args, n_args + PGF_ARGS_DELTA); } - case PGF_EXPR_LIT: { - PgfExprLit* elit = ei.data; + args[n_args++] = &thunk->header; - if (gu_buf_length(state->stack) > 0) { - GuExnData* err_data = gu_raise(state->err, PgfExn); - if (err_data) { - err_data->data = "found literal of function type"; - } - return NULL; - } + expr = eapp->fun; + goto repeat; + } + case PGF_EXPR_LIT: { + PgfExprLit* elit = ei.data; + PgfValueLit* val = (PgfValueLit*) closure; + val->header.code = state->eval_gates->evaluate_value_lit; + val->lit = elit->lit; + res = &val->header; + break; + } + case PGF_EXPR_META: { + PgfExprMeta* emeta = ei.data; - PgfValueLit* val = (PgfValueLit*) closure; - val->header.code = pgf_evaluate_value_lit; - val->lit = elit->lit; - return &val->header; + PgfValueMeta* val = + gu_new_flex(state->pool, PgfValueMeta, args, n_args); + val->header.code = state->eval_gates->evaluate_value_meta; + val->id = emeta->id; + val->n_args = n_args*sizeof(PgfClosure*); + for (size_t i = 0; i < n_args; i++) { + val->args[i] = args[n_args-i-1]; } - case PGF_EXPR_META: { - PgfExprMeta* emeta = ei.data; - size_t n_args = gu_buf_length(state->stack); + PgfIndirection* indir = (PgfIndirection*) closure; + indir->header.code = state->eval_gates->evaluate_indirection; + indir->val = &val->header; - PgfValueMeta* val = - gu_new_flex(state->pool, PgfValueMeta, args, n_args); - val->header.code = pgf_evaluate_value_meta; - val->id = emeta->id; - val->n_args = n_args; - for (size_t i = 0; i < n_args; i++) { - val->args[i] = gu_buf_pop(state->stack, PgfClosure*); + res = &val->header; + break; + } + case PGF_EXPR_FUN: { + PgfExprFun* efun = ei.data; + + PgfAbsFun* absfun = + gu_map_get(state->pgf->abstract.funs, efun->fun, PgfAbsFun*); + if (absfun == NULL) { + GuExnData* err_data = gu_raise(state->err, PgfExn); + if (err_data) { + err_data->data = (char* const) + gu_format_string(err_data->pool, + "Unknown function: %s", + efun->fun); } + } else { + if (absfun->closure_id > 0) { + res = &state->globals[absfun->closure_id-1].header; - PgfIndirection* indir = (PgfIndirection*) closure; - indir->header.code = pgf_evaluate_indirection; - indir->val = &val->header; - - return &val->header; - } - case PGF_EXPR_FUN: { - PgfExprFun* efun = ei.data; - - PgfAbsFun* absfun = - gu_map_get(state->pgf->abstract.funs, efun->fun, PgfAbsFun*); - if (absfun == NULL) { - GuExnData* err_data = gu_raise(state->err, PgfExn); - if (err_data) { - err_data->data = (char* const) - gu_format_string(err_data->pool, - "Unknown function: %s", - efun->fun); - } - return NULL; - } - - PgfValue* val; - if (absfun->function != NULL) { - val = (PgfValue*) ((PgfFunction) absfun->function)(state, closure); - } else { - size_t n_args = absfun->arity; - - val = gu_new_flex(state->pool, PgfValue, args, n_args); - val->header.code = pgf_evaluate_value; - val->absfun = absfun; - for (size_t i = 0; i < n_args; i++) { - val->args[i] = gu_buf_pop(state->stack, PgfClosure*); - } - } - - PgfIndirection* indir = (PgfIndirection*) closure; - indir->header.code = pgf_evaluate_indirection; - indir->val = &val->header; - - return &val->header; - } - case PGF_EXPR_VAR: { - PgfExprVar* evar = ei.data; - PgfEnv* tmp_env = env; - size_t i = evar->var; - while (i > 0) { - tmp_env = tmp_env->next; - if (tmp_env == NULL) { - GuExnData* err_data = gu_raise(state->err, PgfExn); - if (err_data) { - err_data->data = "invalid de Bruijn index"; + if (n_args > 0) { + PgfValuePAP* val = gu_new_flex(state->pool, PgfValuePAP, args, n_args); + val->header.code = state->eval_gates->evaluate_value_pap; + val->fun = res; + val->n_args = n_args*sizeof(PgfClosure*); + for (size_t i = 0; i < n_args; i++) { + val->args[i] = args[i]; } - return NULL; + res = &val->header; } - i--; + } else { + size_t arity = absfun->arity; + + PgfValue* val = gu_new_flex(state->pool, PgfValue, args, arity); + val->header.code = state->eval_gates->evaluate_value; + val->absfun = absfun; + for (size_t i = 0; i < arity; i++) { + val->args[i] = args[--n_args]; + } + + res = &val->header; } - PgfClosure* val = - tmp_env->closure->code(state, tmp_env->closure); - PgfIndirection* indir = (PgfIndirection*) closure; - indir->header.code = pgf_evaluate_indirection; - indir->val = val; - - return val; - } - case PGF_EXPR_TYPED: { - PgfExprTyped* etyped = ei.data; - expr = etyped->expr; - break; - } - case PGF_EXPR_IMPL_ARG: { - PgfExprImplArg* eimpl = ei.data; - expr = eimpl->expr; - break; - } - default: - gu_impossible(); + indir->header.code = state->eval_gates->evaluate_indirection; + indir->val = res; } + break; } -} + case PGF_EXPR_VAR: { + PgfExprVar* evar = ei.data; + PgfEnv* tmp_env = env; + size_t i = evar->var; + while (i > 0) { + tmp_env = tmp_env->next; + if (tmp_env == NULL) { + GuExnData* err_data = gu_raise(state->err, PgfExn); + if (err_data) { + err_data->data = "invalid de Bruijn index"; + } + return NULL; + } + i--; + } -void -pgf_evaluate_save_variables(PgfEvalState* state, PgfValue* val) -{ - size_t n_args = val->absfun->arity; - for (size_t i = 0; i < n_args; i++) { - gu_buf_push(state->stack, PgfClosure*, val->args[i]); - } -} + res = tmp_env->closure; -void -pgf_evaluate_slide(PgfEvalState* state, size_t a, size_t b) -{ - size_t len = gu_buf_length(state->stack); - for (size_t i = 0; i < b-a; i++) { - PgfClosure* c = gu_buf_get(state->stack, PgfClosure*, len-(b-a)+i); - gu_buf_set(state->stack, PgfClosure*, len-b+i, c); + PgfIndirection* indir = (PgfIndirection*) closure; + indir->header.code = state->eval_gates->evaluate_indirection; + indir->val = res; + + if (n_args > 0) { + PgfValuePAP* val = gu_new_flex(state->pool, PgfValuePAP, args, n_args); + val->header.code = state->eval_gates->evaluate_value_pap; + val->fun = res; + val->n_args = n_args*sizeof(PgfClosure*); + for (size_t i = 0; i < n_args; i++) { + val->args[i] = args[i]; + } + res = &val->header; + } + break; } - gu_buf_trim_n(state->stack, a); + case PGF_EXPR_TYPED: { + PgfExprTyped* etyped = ei.data; + expr = etyped->expr; + goto repeat; + } + case PGF_EXPR_IMPL_ARG: { + PgfExprImplArg* eimpl = ei.data; + expr = eimpl->expr; + goto repeat; + } + default: + gu_impossible(); + } + + free(args); + return res; } static PgfExpr pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool) { - clos = clos->code(state, clos); + clos = state->eval_gates->enter(state, clos); if (clos == NULL) return gu_null_variant; @@ -290,13 +189,13 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool) size_t n_args = 0; PgfClosure** args; - if (clos->code == pgf_evaluate_value) { + if (clos->code == state->eval_gates->evaluate_value) { PgfValue* val = (PgfValue*) clos; expr = val->absfun->ep.expr; n_args = gu_seq_length(val->absfun->type->hypos); args = val->args; - } else if (clos->code == pgf_evaluate_value_gen) { + } else if (clos->code == state->eval_gates->evaluate_value_gen) { PgfValueGen* val = (PgfValueGen*) clos; PgfExprVar *evar = @@ -305,9 +204,9 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool) &expr, pool); evar->var = level - val->level - 1; - n_args = val->n_args; + n_args = val->n_args/sizeof(PgfClosure*); args = val->args; - } else if (clos->code == pgf_evaluate_value_meta) { + } else if (clos->code == state->eval_gates->evaluate_value_meta) { PgfValueMeta* val = (PgfValueMeta*) clos; PgfExprMeta *emeta = @@ -316,16 +215,16 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool) &expr, pool); emeta->id = val->id; - n_args = val->n_args; + n_args = val->n_args / sizeof(PgfClosure*); args = val->args; - } else if (clos->code == pgf_evaluate_value_lit) { + } else if (clos->code == state->eval_gates->evaluate_value_lit) { PgfValueLit* val = (PgfValueLit*) clos; PgfExprLit *elit = gu_new_variant(PGF_EXPR_LIT, PgfExprLit, &expr, pool); - + GuVariantInfo i = gu_variant_open(val->lit); switch (i.tag) { case PGF_LITERAL_STR: { @@ -362,13 +261,18 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool) default: gu_impossible(); } - } else { + } else if (clos->code == state->eval_gates->evaluate_value_pap) { + PgfValuePAP *pap = (PgfValuePAP*) clos; + + n_args = pap->n_args / sizeof(PgfClosure*); + args = pap->args; + } else if (clos->code == state->eval_gates->evaluate_value_lambda) { PgfExprThunk *old_thunk = (PgfExprThunk*) clos; PgfExprAbs *old_eabs = gu_variant_open(old_thunk->expr).data; PgfValueGen* gen = gu_new(PgfValueGen, state->pool); - gen->header.code = pgf_evaluate_value_gen; + gen->header.code = state->eval_gates->evaluate_value_gen; gen->level = level; gen->n_args = 0; @@ -378,7 +282,7 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool) PgfExprThunk* new_thunk = gu_new(PgfExprThunk, state->pool); - new_thunk->header.code = pgf_evaluate_expr_thunk; + new_thunk->header.code = state->eval_gates->evaluate_expr_thunk; new_thunk->env = new_env; new_thunk->expr = old_eabs->body; @@ -389,6 +293,8 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool) eabs->bind_type = old_eabs->bind_type; eabs->id = gu_format_string(pool, "v%d", level); eabs->body = pgf_value2expr(state, level+1, &new_thunk->header, pool); + } else { + gu_impossible(); } for (size_t i = 0; i < n_args; i++) { @@ -412,15 +318,24 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool) PgfExpr pgf_compute(PgfPGF* pgf, PgfExpr expr, GuExn* err, GuPool* pool, GuPool* out_pool) { - PgfEvalState* state = gu_new(PgfEvalState, pool); + size_t n_closures = gu_seq_length(pgf->abstract.eval_gates->defrules); + + PgfEvalState* state = + gu_new_flex(pool, PgfEvalState, globals, n_closures); state->pgf = pgf; + state->eval_gates = pgf->abstract.eval_gates; state->pool = pool; state->err = err; - state->stack = gu_new_buf(PgfClosure*, pool); + + PgfFunction* defrules = gu_seq_data(state->eval_gates->defrules); + for (size_t i = 0; i < n_closures; i++) { + state->globals[i].header.code = defrules[i]; + state->globals[i].val = NULL; + } PgfExprThunk* thunk = gu_new(PgfExprThunk, pool); - thunk->header.code = pgf_evaluate_expr_thunk; + thunk->header.code = state->eval_gates->evaluate_expr_thunk; thunk->env = NULL; thunk->expr = expr; diff --git a/src/runtime/c/pgf/evaluator.h b/src/runtime/c/pgf/evaluator.h index 3962e772f..a6a98cdf1 100644 --- a/src/runtime/c/pgf/evaluator.h +++ b/src/runtime/c/pgf/evaluator.h @@ -1,21 +1,37 @@ #ifndef PGF_EVALUATOR_H_ #define PGF_EVALUATOR_H_ -struct PgfEvalState { +typedef void *PgfFunction; + +typedef struct { + PgfFunction code; +} PgfClosure; + +typedef struct { + PgfClosure header; + PgfClosure* val; +} PgfIndirection; + +typedef struct { PgfPGF* pgf; + PgfEvalGates* eval_gates; // cached from pgf->abstr->eval_gates GuPool* pool; GuExn* err; - GuBuf* stack; + PgfIndirection globals[]; // derived from gu_seq_data(pgf->abstr->eval_gates->defrules) +} PgfEvalState; + +typedef struct PgfEnv PgfEnv; + +struct PgfEnv { + PgfEnv* next; + PgfClosure* closure; }; -typedef struct PgfClosure PgfClosure; -typedef struct PgfEvalState PgfEvalState; - -typedef PgfClosure* (*PgfFunction)(PgfEvalState* state, PgfClosure* val); - -struct PgfClosure { - PgfFunction code; -}; +typedef struct { + PgfClosure header; + PgfEnv* env; + PgfExpr expr; +} PgfExprThunk; typedef struct { PgfClosure header; @@ -23,16 +39,53 @@ typedef struct { PgfClosure* args[]; } PgfValue; -PgfClosure* -pgf_evaluate_indirection(PgfEvalState* state, PgfClosure* closure); +typedef struct { + PgfClosure header; + int level; + size_t n_args; + PgfClosure* args[]; +} PgfValueGen; + +typedef struct { + PgfClosure header; + PgfEnv* env; + PgfMetaId id; + size_t n_args; + PgfClosure* args[]; +} PgfValueMeta; + +typedef struct { + PgfClosure header; + PgfLiteral lit; +} PgfValueLit; + +typedef struct { + PgfClosure header; + PgfClosure* fun; + size_t n_args; + PgfClosure* args[]; +} PgfValuePAP; + +struct PgfEvalGates { + PgfFunction evaluate_expr_thunk; + PgfFunction evaluate_indirection; + PgfFunction evaluate_value; + PgfFunction evaluate_value_gen; + PgfFunction evaluate_value_meta; + PgfFunction evaluate_value_lit; + PgfFunction evaluate_value_pap; + PgfFunction evaluate_value_lambda; + + PgfFunction update_closure; + PgfFunction update_pap; + + PgfClosure* (*enter)(PgfEvalState* state, PgfClosure* closure); + + GuFinalizer fin; + GuSeq* defrules; +}; PgfClosure* -pgf_evaluate_value(PgfEvalState* state, PgfClosure* closure); - -void -pgf_evaluate_save_variables(PgfEvalState* state, PgfValue* val); - -void -pgf_evaluate_slide(PgfEvalState* state, size_t a, size_t b); +pgf_evaluate_expr_thunk(PgfEvalState* state, PgfClosure* closure); #endif diff --git a/src/runtime/c/pgf/jit.c b/src/runtime/c/pgf/jit.c index 1a9e25e6f..4f6b8e8dc 100644 --- a/src/runtime/c/pgf/jit.c +++ b/src/runtime/c/pgf/jit.c @@ -1,12 +1,13 @@ #include #include +#include #include #include #include #include #include "lightning.h" -//#define PGF_JIT_DEBUG +#define PGF_JIT_DEBUG struct PgfJitState { @@ -15,6 +16,7 @@ struct PgfJitState { char *save_ip_ptr; GuBuf* call_patches; GuBuf* segment_patches; + size_t n_closures; }; #define _jit (rdr->jit_state->jit) @@ -33,18 +35,16 @@ typedef struct { // Between two calls to pgf_jit_make_space we are not allowed // to emit more that JIT_CODE_WINDOW bytes. This is not quite // safe but this is how GNU lightning is designed. -#define JIT_CODE_WINDOW 1280 +#define JIT_CODE_WINDOW 128 -typedef struct { - GuFinalizer fin; - void *page; -} PgfPageFinalizer; +#define JIT_VHEAP JIT_V0 +#define JIT_VSTATE JIT_V1 +#define JIT_VCLOS JIT_V2 static void pgf_jit_finalize_page(GuFinalizer* self) { - PgfPageFinalizer* fin = gu_container(self, PgfPageFinalizer, fin); - free(fin->page); + free(self); } static void @@ -64,43 +64,43 @@ pgf_jit_alloc_page(PgfReader* rdr) gu_fatal("Memory allocation failed"); } - PgfPageFinalizer* fin = - gu_new(PgfPageFinalizer, rdr->opool); - fin->fin.fn = pgf_jit_finalize_page; - fin->page = page; - gu_pool_finally(rdr->opool, &fin->fin); - + GuFinalizer* fin = page; + fin->fn = pgf_jit_finalize_page; + gu_pool_finally(rdr->opool, fin); + rdr->jit_state->buf = page; - jit_set_ip(rdr->jit_state->buf); + jit_set_ip(rdr->jit_state->buf+sizeof(GuFinalizer)); } PgfJitState* pgf_new_jit(PgfReader* rdr) { PgfJitState* state = gu_new(PgfJitState, rdr->tmp_pool); + memset(&state->jit, 0, sizeof(state->jit)); state->call_patches = gu_new_buf(PgfCallPatch, rdr->tmp_pool); state->segment_patches = gu_new_buf(PgfSegmentPatch, rdr->tmp_pool); state->buf = NULL; state->save_ip_ptr = NULL; + state->n_closures = 0; return state; } static void -pgf_jit_make_space(PgfReader* rdr) +pgf_jit_make_space(PgfReader* rdr, size_t space) { size_t page_size = getpagesize(); if (rdr->jit_state->buf == NULL) { pgf_jit_alloc_page(rdr); } else { - assert (rdr->jit_state->save_ip_ptr + JIT_CODE_WINDOW > jit_get_ip().ptr); + assert (jit_get_ip().ptr < rdr->jit_state->save_ip_ptr); - if (jit_get_ip().ptr + JIT_CODE_WINDOW > ((char*) rdr->jit_state->buf) + page_size) { + if (jit_get_ip().ptr + space > ((char*) rdr->jit_state->buf) + page_size) { jit_flush_code(rdr->jit_state->buf, jit_get_ip().ptr); pgf_jit_alloc_page(rdr); } } - rdr->jit_state->save_ip_ptr = jit_get_ip().ptr; + rdr->jit_state->save_ip_ptr = jit_get_ip().ptr + space; } static PgfAbsFun* @@ -137,7 +137,7 @@ pgf_jit_predicate(PgfReader* rdr, PgfAbstr* abstr, size_t n_funs = pgf_read_len(rdr); gu_return_on_exn(rdr->err, ); - pgf_jit_make_space(rdr); + pgf_jit_make_space(rdr, JIT_CODE_WINDOW); abscat->predicate = (PgfPredicate) jit_get_ip().ptr; @@ -183,7 +183,7 @@ pgf_jit_predicate(PgfReader* rdr, PgfAbstr* abstr, #endif for (size_t i = 0; i < n_funs; i++) { - pgf_jit_make_space(rdr); + pgf_jit_make_space(rdr, JIT_CODE_WINDOW); absfun = next_absfun; absfun->predicate = (PgfPredicate) jit_get_ip().ptr; @@ -254,7 +254,7 @@ pgf_jit_predicate(PgfReader* rdr, PgfAbstr* abstr, jit_ret(); if (i+1 < n_hypos) { - pgf_jit_make_space(rdr); + pgf_jit_make_space(rdr, JIT_CODE_WINDOW); jit_patch_movi(ref,jit_get_label()); @@ -318,28 +318,287 @@ pgf_jit_predicate(PgfReader* rdr, PgfAbstr* abstr, } static void -pgf_jit_compile_slide(PgfReader* rdr, int es_arg, size_t a, size_t b) +pgf_jit_finalize_defrules(GuFinalizer* self) { - if (a == b) { - jit_prepare(2); - jit_movi_i(JIT_V1, a); - jit_pusharg_p(JIT_V1); - jit_getarg_p(JIT_V1, es_arg); - jit_ldxi_p(JIT_V1, JIT_V1, offsetof(PgfEvalState,stack)); - jit_pusharg_p(JIT_V1); - jit_finish(gu_buf_trim_n); - } else { - jit_prepare(3); - jit_movi_i(JIT_V1, b); - jit_pusharg_p(JIT_V1); - jit_movi_i(JIT_V1, a); - jit_pusharg_p(JIT_V1); - jit_getarg_p(JIT_V1, es_arg); - jit_pusharg_p(JIT_V1); - jit_finish(pgf_evaluate_slide); - } + PgfEvalGates* gates = gu_container(self, PgfEvalGates, fin); + if (gates->defrules != NULL) + gu_seq_free(gates->defrules); } +PgfEvalGates* +pgf_jit_gates(PgfReader* rdr) +{ + PgfEvalGates* gates = gu_new(PgfEvalGates, rdr->opool); + jit_insn* next; + jit_insn* ref, *ref2; + + pgf_jit_make_space(rdr, JIT_CODE_WINDOW); + + gates->evaluate_indirection = jit_get_ip().ptr; + jit_ldxi_p(JIT_VCLOS, JIT_VCLOS, offsetof(PgfIndirection,val)); + jit_ldr_p(JIT_R0, JIT_VCLOS); + jit_jmpr(JIT_R0); + + pgf_jit_make_space(rdr, JIT_CODE_WINDOW); + + gates->evaluate_value = jit_get_ip().ptr; + jit_movr_p(JIT_VHEAP, JIT_VCLOS); + jit_ldxi_p(JIT_RET, JIT_VHEAP, offsetof(PgfValue, absfun)); + jit_bare_ret(0); + + pgf_jit_make_space(rdr, JIT_CODE_WINDOW); + + gates->evaluate_value_gen = jit_get_ip().ptr; + jit_subr_p(JIT_R0, JIT_FP, JIT_SP); + jit_subi_p(JIT_R0, JIT_R0, sizeof(void*)); + ref = jit_bnei_i(jit_forward(), JIT_R0, 0); + jit_movr_p(JIT_VHEAP, JIT_VCLOS); + jit_bare_ret(0); + jit_patch(ref); + jit_pushr_i(JIT_R0); + jit_prepare(2); + jit_addi_i(JIT_R0, JIT_R0, sizeof(PgfValueGen)); + jit_pusharg_ui(JIT_R0); + jit_ldxi_p(JIT_R0, JIT_VSTATE, offsetof(PgfEvalState,pool)); + jit_pusharg_p(JIT_R0); + jit_finish(gu_malloc); + jit_retval(JIT_VHEAP); + jit_popr_i(JIT_R0); + jit_movi_p(JIT_R1, gates->evaluate_value_gen); + jit_str_p(JIT_VHEAP, JIT_R1); + jit_ldxi_p(JIT_R1, JIT_VCLOS, offsetof(PgfValueGen,level)); + jit_stxi_p(offsetof(PgfValueGen,level), JIT_VHEAP, JIT_R1); + jit_ldxi_p(JIT_R1, JIT_VCLOS, offsetof(PgfValueGen,n_args)); + jit_addr_i(JIT_R1, JIT_R1, JIT_R0); + jit_stxi_p(offsetof(PgfValueGen,n_args), JIT_VHEAP, JIT_R1); + jit_movi_i(JIT_R1, offsetof(PgfValueGen,args)); + jit_ldxi_i(JIT_R2, JIT_VCLOS, offsetof(PgfValueGen,n_args)); + jit_addr_i(JIT_R2, JIT_R2, JIT_R1); + jit_pushr_i(JIT_R0); + next = jit_get_label(); + ref = jit_bger_i(jit_forward(), JIT_R1, JIT_R2); + jit_ldxr_i(JIT_R0, JIT_VCLOS, JIT_R1); + jit_stxr_p(JIT_R1, JIT_VHEAP, JIT_R0); + jit_addi_i(JIT_R1, JIT_R1, sizeof(void*)); + jit_jmpi(next); + jit_patch(ref); + jit_popr_i(JIT_R0); + jit_addr_i(JIT_R2, JIT_R2, JIT_R0); + jit_popr_p(JIT_VCLOS); + next = jit_get_label(); + ref = jit_bger_i(jit_forward(), JIT_R1, JIT_R2); + jit_popr_p(JIT_R0); + jit_stxr_p(JIT_R1, JIT_VHEAP, JIT_R0); + jit_addi_i(JIT_R1, JIT_R1, sizeof(void*)); + jit_jmpi(next); + jit_patch(ref); + jit_jmpr(JIT_VCLOS); + + pgf_jit_make_space(rdr, JIT_CODE_WINDOW); + + gates->evaluate_value_meta = jit_get_ip().ptr; + jit_subr_p(JIT_R0, JIT_FP, JIT_SP); + jit_subi_p(JIT_R0, JIT_R0, sizeof(void*)); + ref = jit_bnei_i(jit_forward(), JIT_R0, 0); + jit_movr_p(JIT_VHEAP, JIT_VCLOS); + jit_bare_ret(0); + jit_patch(ref); + jit_pushr_i(JIT_R0); + jit_prepare(2); + jit_addi_i(JIT_R0, JIT_R0, sizeof(PgfValueMeta)); + jit_pusharg_ui(JIT_R0); + jit_ldxi_p(JIT_R0, JIT_VSTATE, offsetof(PgfEvalState,pool)); + jit_pusharg_p(JIT_R0); + jit_finish(gu_malloc); + jit_retval(JIT_VHEAP); + jit_popr_i(JIT_R0); + jit_movi_p(JIT_R1, gates->evaluate_value_meta); + jit_str_p(JIT_VHEAP, JIT_R1); + jit_ldxi_p(JIT_R1, JIT_VCLOS, offsetof(PgfValueMeta,id)); + jit_stxi_p(offsetof(PgfValueMeta,id), JIT_VHEAP, JIT_R1); + jit_ldxi_p(JIT_R1, JIT_VCLOS, offsetof(PgfValueMeta,n_args)); + jit_addr_i(JIT_R1, JIT_R1, JIT_R0); + jit_stxi_p(offsetof(PgfValueMeta,n_args), JIT_VHEAP, JIT_R1); + jit_movi_i(JIT_R1, offsetof(PgfValueMeta,args)); + jit_ldxi_i(JIT_R2, JIT_VCLOS, offsetof(PgfValueMeta,n_args)); + jit_addr_i(JIT_R2, JIT_R2, JIT_R1); + jit_pushr_i(JIT_R0); + next = jit_get_label(); + ref = jit_bger_i(jit_forward(), JIT_R1, JIT_R2); + jit_ldxr_i(JIT_R0, JIT_VCLOS, JIT_R1); + jit_stxr_p(JIT_R1, JIT_VHEAP, JIT_R0); + jit_addi_i(JIT_R1, JIT_R1, sizeof(PgfClosure*)); + jit_jmpi(next); + jit_patch(ref); + jit_popr_i(JIT_R0); + jit_addr_i(JIT_R2, JIT_R2, JIT_R0); + jit_popr_p(JIT_VCLOS); + next = jit_get_label(); + ref = jit_bger_i(jit_forward(), JIT_R1, JIT_R2); + jit_popr_p(JIT_R0); + jit_stxr_p(JIT_R1, JIT_VHEAP, JIT_R0); + jit_addi_i(JIT_R1, JIT_R1, sizeof(PgfClosure*)); + jit_jmpi(next); + jit_patch(ref); + jit_jmpr(JIT_VCLOS); + + pgf_jit_make_space(rdr, JIT_CODE_WINDOW); + + gates->evaluate_expr_thunk = jit_get_ip().ptr; + jit_prepare(2); + jit_pusharg_p(JIT_VCLOS); + jit_pusharg_p(JIT_VSTATE); + jit_finish(pgf_evaluate_expr_thunk); + jit_retval(JIT_VCLOS); + jit_ldr_p(JIT_R0, JIT_VCLOS); + jit_jmpr(JIT_R0); + + pgf_jit_make_space(rdr, JIT_CODE_WINDOW); + + gates->evaluate_value_lit = jit_get_ip().ptr; + jit_movr_p(JIT_VHEAP, JIT_VCLOS); + jit_prepare(1); + jit_ldxi_p(JIT_R0, JIT_VHEAP, offsetof(PgfValueLit, lit)); + jit_pusharg_p(JIT_R0); + jit_finish(gu_variant_data); + jit_bare_ret(0); + + pgf_jit_make_space(rdr, JIT_CODE_WINDOW); + + gates->enter = (void*) jit_get_ip().ptr; + jit_prolog(2); + int es_arg = jit_arg_p(); + int closure_arg = jit_arg_p(); + jit_getarg_p(JIT_VSTATE, es_arg); + jit_getarg_p(JIT_VCLOS, closure_arg); + jit_ldr_p(JIT_R0, JIT_VCLOS); + jit_callr(JIT_R0); + jit_movr_p(JIT_RET, JIT_VHEAP); + jit_ret(); + + pgf_jit_make_space(rdr, JIT_CODE_WINDOW); + + gates->evaluate_value_pap = jit_get_ip().ptr; + jit_popr_p(JIT_VHEAP); + jit_addi_p(JIT_R1, JIT_VCLOS, offsetof(PgfValuePAP,args)); + jit_ldxi_p(JIT_R2, JIT_VCLOS, offsetof(PgfValuePAP,n_args)); + jit_addr_p(JIT_R2, JIT_R2, JIT_R1); + next = jit_get_label(); + ref = jit_bger_i(jit_forward(), JIT_R1, JIT_R2); + jit_ldr_p(JIT_R0, JIT_R1); + jit_pushr_p(JIT_R0); + jit_addi_p(JIT_R1, JIT_R1, sizeof(PgfClosure*)); + jit_jmpi(next); + jit_patch(ref); + jit_pushr_p(JIT_VHEAP); + jit_ldxi_p(JIT_VCLOS, JIT_VCLOS, offsetof(PgfValuePAP,fun)); + jit_ldr_p(JIT_R0, JIT_VCLOS); + jit_jmpr(JIT_R0); + + pgf_jit_make_space(rdr, JIT_CODE_WINDOW); + + gates->update_closure = jit_get_ip().ptr; + jit_popr_p(JIT_FP); + jit_popr_p(JIT_VCLOS); + jit_movi_p(JIT_R1, gates->evaluate_indirection); + jit_str_p(JIT_VCLOS, JIT_R1); + jit_stxi_p(offsetof(PgfIndirection, val), JIT_VCLOS, JIT_VHEAP); + jit_bare_ret(0); + + pgf_jit_make_space(rdr, JIT_CODE_WINDOW*2); + + gates->update_pap = jit_get_ip().ptr; + jit_subi_p(JIT_R0, JIT_R0, sizeof(void*)); + jit_pushr_i(JIT_R0); + jit_prepare(2); + jit_addi_i(JIT_R0, JIT_R0, sizeof(PgfValuePAP)); + jit_pusharg_ui(JIT_R0); + jit_ldxi_p(JIT_R0, JIT_VSTATE, offsetof(PgfEvalState,pool)); + jit_pusharg_p(JIT_R0); + jit_finish(gu_malloc); + jit_popr_i(JIT_R1); + jit_movi_p(JIT_R2, gates->evaluate_value_pap); + jit_str_p(JIT_RET, JIT_R2); + jit_stxi_p(offsetof(PgfValuePAP,fun), JIT_RET, JIT_VCLOS); + jit_stxi_p(offsetof(PgfValuePAP,n_args), JIT_RET, JIT_R1); + jit_ldr_p(JIT_R2, JIT_SP); + ref2 = jit_bnei_i(jit_forward(), JIT_R2, (int)gates->update_closure); + jit_ldxi_p(JIT_VHEAP, JIT_FP, sizeof(void*)); + jit_movi_p(JIT_R2, gates->evaluate_indirection); + jit_str_p(JIT_VHEAP, JIT_R2); + jit_stxi_p(offsetof(PgfIndirection, val), JIT_VHEAP, JIT_RET); + jit_ldr_p(JIT_R2, JIT_FP); + jit_pushr_p(JIT_R2); + jit_ldxi_p(JIT_R2, JIT_FP, 2*sizeof(void*)); + jit_pushr_p(JIT_R2); + next = jit_get_label(); + ref = jit_blei_i(jit_forward(), JIT_R1, 0); + jit_ldxi_p(JIT_R2, JIT_FP, -sizeof(void*)); + jit_stxi_p(2*sizeof(void*), JIT_FP, JIT_R2); + jit_stxi_p(offsetof(PgfValuePAP,args), JIT_RET, JIT_R2); + jit_addi_i(JIT_RET, JIT_RET, sizeof(void*)); + jit_subi_i(JIT_FP, JIT_FP, sizeof(void*)); + jit_subi_i(JIT_R1, JIT_R1, sizeof(void*)); + jit_jmpi(next); + jit_patch(ref); + jit_popr_p(JIT_R0); + jit_popr_p(JIT_FP); + jit_addi_p(JIT_SP, JIT_SP, 4*sizeof(void*)); + jit_pushr_p(JIT_R0); + jit_ldr_p(JIT_R0, JIT_VCLOS); + jit_jmpr(JIT_R0); + jit_patch(ref2); + jit_movr_p(JIT_VHEAP, JIT_RET); + jit_pushr_p(JIT_R1); + next = jit_get_label(); + ref = jit_blei_i(jit_forward(), JIT_R1, 0); + jit_ldxi_p(JIT_R2, JIT_FP, -sizeof(void*)); + jit_stxi_p(offsetof(PgfValuePAP,args), JIT_RET, JIT_R2); + jit_addi_i(JIT_RET, JIT_RET, sizeof(void*)); + jit_subi_i(JIT_FP, JIT_FP, sizeof(void*)); + jit_subi_i(JIT_R1, JIT_R1, sizeof(void*)); + jit_jmpi(next); + jit_patch(ref); + jit_popr_p(JIT_R1); + jit_popr_p(JIT_R0); + jit_addr_p(JIT_SP, JIT_SP, JIT_R1); + jit_jmpr(JIT_R0); + + pgf_jit_make_space(rdr, JIT_CODE_WINDOW); + + gates->evaluate_value_lambda = jit_get_ip().ptr; + jit_subr_p(JIT_R0, JIT_FP, JIT_SP); + jit_blti_i(gates->update_pap, JIT_R0, 2*sizeof(PgfClosure*)); + jit_prepare(2); + jit_movi_i(JIT_R0, sizeof(PgfEnv)); + jit_pusharg_ui(JIT_R0); + jit_ldxi_p(JIT_R0, JIT_VSTATE, offsetof(PgfEvalState,pool)); + jit_pusharg_p(JIT_R0); + jit_finish(gu_malloc); + jit_popr_p(JIT_R2); + jit_ldxi_p(JIT_R1, JIT_VCLOS, offsetof(PgfExprThunk,env)); + jit_stxi_p(offsetof(PgfEnv,next), JIT_RET, JIT_R1); + jit_popr_p(JIT_R1); + jit_stxi_p(offsetof(PgfEnv,closure), JIT_RET, JIT_R1); + jit_stxi_p(offsetof(PgfExprThunk,env), JIT_VCLOS, JIT_RET); + jit_pushr_p(JIT_R2); + jit_prepare(2); + jit_pusharg_p(JIT_VCLOS); + jit_pusharg_p(JIT_VSTATE); + jit_finish(pgf_evaluate_expr_thunk); + jit_retval(JIT_VCLOS); + jit_ldr_p(JIT_R0, JIT_VCLOS); + jit_jmpr(JIT_R0); + + gates->fin.fn = pgf_jit_finalize_defrules; + gates->defrules = NULL; + gu_pool_finally(rdr->opool, &gates->fin); + + return gates; +} + +#define PGF_DEFRULES_DELTA 20 + void pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, PgfAbsFun* absfun) @@ -353,34 +612,43 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, gu_puts(":\n", out, err); #endif - pgf_jit_make_space(rdr); - - absfun->function = jit_get_ip().ptr; + if (rdr->jit_state->n_closures % PGF_DEFRULES_DELTA == 0) { + abstr->eval_gates->defrules = + gu_realloc_seq(abstr->eval_gates->defrules, + PgfFunction, + rdr->jit_state->n_closures + PGF_DEFRULES_DELTA); + } + absfun->closure_id = ++rdr->jit_state->n_closures; size_t n_segments = pgf_read_len(rdr); gu_return_on_exn(rdr->err, ); gu_buf_flush(rdr->jit_state->segment_patches); - int es_arg = 0; - int closure_arg = 0; - for (size_t segment = 0; segment < n_segments; segment++) { size_t n_instrs = pgf_read_len(rdr); gu_return_on_exn(rdr->err, ); - + + pgf_jit_make_space(rdr, (JIT_CODE_WINDOW/4)*n_instrs); + + if (segment == 0) { + gu_seq_set(abstr->eval_gates->defrules, + PgfFunction, + absfun->closure_id-1, + jit_get_ip().ptr); + } + size_t curr_offset = 0; size_t n_patches = gu_buf_length(rdr->jit_state->segment_patches); - if (n_patches > 0) { + for (size_t i = 0; i < n_patches; i++) { PgfSegmentPatch* patch = - gu_buf_index(rdr->jit_state->segment_patches, PgfSegmentPatch, n_patches-1); + gu_buf_index(rdr->jit_state->segment_patches, PgfSegmentPatch, i); if (patch->segment == segment) { if (patch->is_abs) jit_patch_movi(patch->ref,jit_get_ip().ptr); else jit_patch(patch->ref); - gu_buf_trim_n(rdr->jit_state->segment_patches, 1); } } @@ -395,27 +663,27 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, #endif uint8_t tag = pgf_read_tag(rdr); - uint8_t opcode = tag >> 3; - uint8_t mod = tag & 0x07; + uint8_t opcode = tag >> 2; + uint8_t mod = tag & 0x03; switch (opcode) { - case PGF_INSTR_ENTER: { + case PGF_INSTR_CHECK_ARGS: { + int n = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "ENTER\n"); + gu_printf(out, err, "CHECK_ARGS %d\n", n); #endif - - jit_prolog(2); - es_arg = jit_arg_p(); - closure_arg = jit_arg_p(); + jit_subr_p(JIT_R0, JIT_FP, JIT_SP); + jit_blti_i(abstr->eval_gates->update_pap, JIT_R0, (n+1)*sizeof(PgfClosure*)); break; } case PGF_INSTR_CASE: { - PgfCId id = pgf_read_cid(rdr, rdr->opool); + PgfCId id = pgf_read_cid(rdr, rdr->tmp_pool); + int n = pgf_read_int(rdr); int target = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "CASE %s %03d\n", id, target); + gu_printf(out, err, "CASE %s %d %03d\n", id, n, target); #endif - jit_insn *jump= - jit_bnei_i(jit_forward(), JIT_V0, (int) jit_forward()); + jit_insn *jump = + jit_bnei_i(jit_forward(), JIT_RET, (int) jit_forward()); PgfSegmentPatch label_patch; label_patch.segment = target; @@ -428,42 +696,68 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, call_patch.ref = jump-6; gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, call_patch); - jit_prepare(2); - jit_pusharg_p(JIT_V1); - jit_getarg_p(JIT_V2, es_arg); - jit_pusharg_p(JIT_V2); - jit_finish(pgf_evaluate_save_variables); + for (int i = 0; i < n; i++) { + jit_ldxi_p(JIT_R0, JIT_VHEAP, sizeof(PgfValue)+sizeof(PgfClosure*)*i); + jit_pushr_p(JIT_R0); + } break; } case PGF_INSTR_CASE_LIT: { + int target; + jit_insn *jump; + switch (mod) { case 0: { - int n = pgf_read_int(rdr); - int target = pgf_read_int(rdr); + int n = pgf_read_int(rdr); + target = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG gu_printf(out, err, "CASE_LIT %d %03d\n", n, target); #endif + jit_ldxi_p(JIT_R1, JIT_RET, offsetof(PgfLiteralInt,val)); + jump = + jit_bnei_i(jit_forward(), JIT_R1, n); break; } case 1: { GuString s = pgf_read_string(rdr); - int target = pgf_read_int(rdr); + target = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG gu_printf(out, err, "CASE_LIT %s %03d\n", s, target); #endif + jit_pushr_p(JIT_RET); + jit_prepare(2); + jit_pusharg_p(JIT_RET); + jit_movi_p(JIT_R0, s); + jit_pusharg_p(JIT_R0); + jit_finish(strcmp); + jit_retval(JIT_R1); + jit_popr_p(JIT_RET); + jump = + jit_bnei_i(jit_forward(), JIT_R1, 0); break; } case 2: { double d = pgf_read_double(rdr); - int target = pgf_read_int(rdr); + target = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG gu_printf(out, err, "CASE_LIT %f %03d\n", d, target); #endif + jit_ldxi_d(JIT_FPR0, JIT_RET, offsetof(PgfLiteralFlt,val)); + jit_movi_d(JIT_FPR1, d); + jump = + jit_bner_d(jit_forward(), JIT_FPR0, JIT_FPR1); break; } default: gu_impossible(); } + + PgfSegmentPatch label_patch; + label_patch.segment = target; + label_patch.ref = jump; + label_patch.is_abs = false; + gu_buf_push(rdr->jit_state->segment_patches, PgfSegmentPatch, label_patch); + break; } case PGF_INSTR_ALLOC: { @@ -472,14 +766,13 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, gu_printf(out, err, "ALLOC %d\n", size); #endif jit_prepare(2); - jit_movi_ui(JIT_V0, size*sizeof(void*)); - jit_pusharg_ui(JIT_V0); - jit_getarg_p(JIT_V0, es_arg); - jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,pool)); - jit_pusharg_p(JIT_V0); + jit_movi_ui(JIT_R0, size*sizeof(void*)); + jit_pusharg_ui(JIT_R0); + jit_ldxi_p(JIT_R0, JIT_VSTATE, offsetof(PgfEvalState,pool)); + jit_pusharg_p(JIT_R0); jit_finish(gu_malloc); - jit_retval_p(JIT_V1); - + jit_retval_p(JIT_VHEAP); + curr_offset = 0; break; } @@ -489,30 +782,14 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, gu_printf(out, err, "PUT_CONSTR %s\n", id); #endif - jit_movi_p(JIT_V0, pgf_evaluate_value); - jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); + jit_movi_p(JIT_R0, abstr->eval_gates->evaluate_value); + jit_stxi_p(curr_offset*sizeof(void*), JIT_VHEAP, JIT_R0); curr_offset++; PgfCallPatch patch; patch.cid = id; - patch.ref = jit_movi_p(JIT_V0, jit_forward()); - jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); - curr_offset++; - - gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch); - break; - } - case PGF_INSTR_PUT_FUN: { - PgfCId id = pgf_read_cid(rdr, rdr->tmp_pool); -#ifdef PGF_JIT_DEBUG - gu_printf(out, err, "PUT_FUN %s\n", id); -#endif - - PgfCallPatch patch; - patch.cid = id; - patch.ref = jit_movi_p(JIT_V0, jit_forward()); - jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfAbsFun,function)); - jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); + patch.ref = jit_movi_p(JIT_R0, jit_forward()); + jit_stxi_p(curr_offset*sizeof(void*), JIT_VHEAP, JIT_R0); curr_offset++; gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch); @@ -526,40 +803,72 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, PgfSegmentPatch patch; patch.segment = target; - patch.ref = jit_movi_p(JIT_V0, jit_forward()); + patch.ref = jit_movi_p(JIT_R0, jit_forward()); patch.is_abs = true; - jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); + jit_stxi_p(curr_offset*sizeof(void*), JIT_VHEAP, JIT_R0); curr_offset++; - + gu_buf_push(rdr->jit_state->segment_patches, PgfSegmentPatch, patch); break; } case PGF_INSTR_PUT_LIT: { + jit_movi_p(JIT_R0, abstr->eval_gates->evaluate_value_lit); + jit_stxi_p(curr_offset*sizeof(void*), JIT_VHEAP, JIT_R0); + curr_offset++; + + PgfLiteral lit; switch (mod) { case 0: { - size_t n = pgf_read_int(rdr); + PgfLiteralInt *lit_int = + gu_new_variant(PGF_LITERAL_INT, + PgfLiteralInt, + &lit, + rdr->opool); + lit_int->val = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "PUT_LIT %d\n", n); + gu_printf(out, err, "PUT_LIT %d\n", lit_int->val); #endif break; } case 1: { - GuString s = pgf_read_string(rdr); + GuLength len = pgf_read_len(rdr); + uint8_t* buf = alloca(len*6+1); + uint8_t* p = buf; + for (size_t i = 0; i < len; i++) { + gu_in_utf8_buf(&p, rdr->in, rdr->err); + } + *p++ = 0; + + PgfLiteralStr *lit_str = + gu_new_flex_variant(PGF_LITERAL_STR, + PgfLiteralStr, + val, p-buf, + &lit, rdr->opool); + strcpy((char*) lit_str->val, (char*) buf); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "PUT_LIT \"%s\"\n", s); + gu_printf(out, err, "PUT_LIT \"%s\"\n", lit_str->val); #endif break; } case 2: { - double d = pgf_read_double(rdr); + PgfLiteralFlt *lit_flt = + gu_new_variant(PGF_LITERAL_FLT, + PgfLiteralFlt, + &lit, + rdr->opool); + lit_flt->val = pgf_read_double(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "PUT_LIT %f\n", d); + gu_printf(out, err, "PUT_LIT %f\n", lit_flt->val); #endif break; } default: gu_impossible(); } + + jit_movi_p(JIT_R0, lit); + jit_stxi_p(curr_offset*sizeof(void*), JIT_VHEAP, JIT_R0); + curr_offset++; break; } case PGF_INSTR_SET: { @@ -569,7 +878,7 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, #ifdef PGF_JIT_DEBUG gu_printf(out, err, "SET hp(%d)\n", offset); #endif - jit_addi_p(JIT_V0, JIT_V1, offset*sizeof(void*)); + jit_addi_p(JIT_R0, JIT_VHEAP, offset*sizeof(void*)); break; } case 1: { @@ -577,13 +886,7 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, #ifdef PGF_JIT_DEBUG gu_printf(out, err, "SET stk(%d)\n", index); #endif - - jit_getarg_p(JIT_V0, es_arg); - jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); - jit_prepare(1); - jit_pusharg_p(JIT_V0); - jit_finish(gu_buf_last); - jit_ldxi_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*)); + jit_ldxi_p(JIT_R0, JIT_SP, index*sizeof(PgfClosure*)); break; } case 2: { @@ -591,16 +894,14 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, #ifdef PGF_JIT_DEBUG gu_printf(out, err, "SET env(%d)\n", index); #endif - - jit_getarg_p(JIT_V0, closure_arg); - jit_ldxi_p(JIT_V0, JIT_V0, sizeof(PgfClosure)+index*sizeof(PgfClosure*)); + jit_ldxi_p(JIT_R0, JIT_VCLOS, sizeof(PgfClosure)+index*sizeof(PgfClosure*)); break; } default: gu_impossible(); } - jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); + jit_stxi_p(curr_offset*sizeof(void*), JIT_VHEAP, JIT_R0); curr_offset++; break; } @@ -608,18 +909,12 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, #ifdef PGF_JIT_DEBUG gu_printf(out, err, "SET_PAD\n"); #endif - jit_movi_p(JIT_V0, NULL); - jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); + jit_movi_p(JIT_R0, NULL); + jit_stxi_p(curr_offset*sizeof(void*), JIT_VHEAP, JIT_R0); curr_offset++; break; } case PGF_INSTR_PUSH: { - jit_getarg_p(JIT_V0, es_arg); - jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); - jit_prepare(1); - jit_pusharg_p(JIT_V0); - jit_finish(gu_buf_extend); - switch (mod) { case 0: { size_t offset = pgf_read_int(rdr); @@ -628,10 +923,10 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, #endif if (offset == 0) { - jit_str_p(JIT_RET, JIT_V1); + jit_pushr_p(JIT_VHEAP); } else { - jit_addi_p(JIT_V0, JIT_V1, offset*sizeof(void*)); - jit_str_p(JIT_RET, JIT_V0); + jit_addi_p(JIT_R0, JIT_VHEAP, offset*sizeof(void*)); + jit_pushr_p(JIT_R0); } break; } @@ -640,9 +935,8 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, #ifdef PGF_JIT_DEBUG gu_printf(out, err, "PUSH stk(%d)\n", index); #endif - - jit_ldxi_p(JIT_V0, JIT_RET, -(index+1)*sizeof(PgfClosure*)); - jit_str_p(JIT_RET, JIT_V0); + jit_ldxi_p(JIT_R0, JIT_SP, index*sizeof(PgfClosure*)); + jit_pushr_p(JIT_R0); break; } case 2: { @@ -650,10 +944,8 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, #ifdef PGF_JIT_DEBUG gu_printf(out, err, "PUSH env(%d)\n", index); #endif - - jit_getarg_p(JIT_V0, closure_arg); - jit_ldxi_p(JIT_V0, JIT_V0, sizeof(PgfClosure)+index*sizeof(PgfClosure*)); - jit_str_p(JIT_RET, JIT_V0); + jit_ldxi_p(JIT_R0, JIT_VCLOS, sizeof(PgfClosure)+index*sizeof(PgfClosure*)); + jit_pushr_p(JIT_R0); break; } default: @@ -661,15 +953,17 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, } break; } - case PGF_INSTR_EVAL: { - switch (mod & 0x3) { + case PGF_INSTR_EVAL+0: + case PGF_INSTR_EVAL+2: + jit_movr_p(JIT_R2, JIT_VCLOS); + case PGF_INSTR_EVAL+1: { + switch (mod) { case 0: { size_t offset = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG gu_printf(out, err, "EVAL hp(%d)", offset); #endif - - jit_addi_p(JIT_V0, JIT_V1, offset*sizeof(void*)); + jit_addi_p(JIT_VCLOS, JIT_VHEAP, offset*sizeof(void*)); break; } case 1: { @@ -677,13 +971,7 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, #ifdef PGF_JIT_DEBUG gu_printf(out, err, "EVAL stk(%d)", index); #endif - - jit_getarg_p(JIT_V0, es_arg); - jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); - jit_prepare(1); - jit_pusharg_p(JIT_V0); - jit_finish(gu_buf_last); - jit_ldxi_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*)); + jit_ldxi_p(JIT_VCLOS, JIT_SP, index*sizeof(PgfClosure*)); break; } case 2: { @@ -691,40 +979,84 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, #ifdef PGF_JIT_DEBUG gu_printf(out, err, "EVAL env(%d)", index); #endif + jit_ldxi_p(JIT_VCLOS, JIT_VCLOS, sizeof(PgfClosure)+index*sizeof(PgfClosure*)); + break; + } + case 3: { + PgfCId id = pgf_read_cid(rdr, rdr->tmp_pool); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "EVAL %s", id); +#endif + PgfCallPatch patch; + patch.cid = id; + patch.ref = jit_addi_p(JIT_VCLOS, JIT_VSTATE, jit_forward()); + gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch); break; } default: gu_impossible(); } - switch (mod >> 2) { + jit_ldr_p(JIT_R0, JIT_VCLOS); + + switch (opcode - PGF_INSTR_EVAL) { case 0: { #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "\n"); + gu_printf(out, err, "\n"); #endif - - jit_prepare(2); - jit_pusharg_p(JIT_V0); - jit_getarg_p(JIT_V2, es_arg); - jit_pusharg_p(JIT_V2); - jit_ldr_p(JIT_V0, JIT_V0); - jit_finishr(JIT_V0); - jit_retval_p(JIT_V1); - jit_ldxi_p(JIT_V0, JIT_V1, offsetof(PgfValue, absfun)); + jit_pushr_p(JIT_R2); + jit_callr(JIT_R0); + jit_popr_p(JIT_VCLOS); break; } case 1: { size_t a = pgf_read_int(rdr); - size_t b = pgf_read_int(rdr); - + size_t b = pgf_read_int(rdr); + size_t c = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, " tail(%d,%d)\n", a, b); + gu_printf(out, err, " tail(%d,%d,%d)\n", a, b, c); #endif - pgf_jit_compile_slide(rdr, es_arg, a, b); - jit_setarg_p(JIT_V0, closure_arg); - jit_ldr_p(JIT_RET, JIT_V0); - jit_tail_finishr(JIT_RET); + jit_ldxi_p(JIT_R2, JIT_SP, sizeof(PgfClosure*)*(c-a-1)); + for (size_t i = 0; i < c-b; i++) { + jit_ldxi_p(JIT_R1, JIT_SP, sizeof(PgfClosure*)*((c-b-1)-i)); + jit_stxi_p(sizeof(PgfClosure*)*((c-1)-i), JIT_SP, JIT_R1); + } + jit_addi_p(JIT_SP, JIT_SP, b*sizeof(PgfClosure*)); + jit_pushr_p(JIT_R2); + jit_jmpr(JIT_R0); + break; + } + case 2: { + size_t b = pgf_read_int(rdr); + size_t c = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, " update(%d,%d)\n", b, c); +#endif + + if (b >= 3) { + jit_stxi_p(sizeof(PgfClosure*)*(c-3), JIT_SP, JIT_FP); + jit_stxi_p(sizeof(PgfClosure*)*(c-2), JIT_SP, JIT_R2); + for (size_t i = 0; i < c-b; i++) { + jit_ldxi_p(JIT_R1, JIT_SP, sizeof(PgfClosure*)*((c-b-1)-i)); + jit_stxi_p(sizeof(PgfClosure*)*((c-4)-i), JIT_SP, JIT_R1); + } + jit_addi_p(JIT_SP, JIT_SP, (b-3)*sizeof(PgfClosure*)); + } else { + jit_subi_p(JIT_SP, JIT_SP, (3-b)*sizeof(PgfClosure*)); + for (size_t i = 0; i < c-b; i++) { + jit_ldxi_p(JIT_R1, JIT_SP, sizeof(PgfClosure*)*(i+(3-b))); + jit_stxi_p(sizeof(PgfClosure*)*i, JIT_SP, JIT_R1); + } + jit_stxi_p(sizeof(PgfClosure*)*(c-b), JIT_SP, JIT_FP); + jit_stxi_p(sizeof(PgfClosure*)*(c-b+1), JIT_SP, JIT_R2); + } + + jit_addi_p(JIT_FP, JIT_SP, sizeof(PgfClosure*)*(c-b)); + jit_movi_p(JIT_R1, abstr->eval_gates->update_closure); + jit_pushr_p(JIT_R1); + + jit_jmpr(JIT_R0); break; } default: @@ -732,55 +1064,33 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, } break; } - case PGF_INSTR_CALL: { - PgfCId id = pgf_read_cid(rdr, rdr->tmp_pool); + case PGF_INSTR_RET: { + size_t h = pgf_read_int(rdr); + + if (h > 0) + jit_addi_p(JIT_VHEAP, JIT_VHEAP, h*sizeof(PgfClosure*)); + + size_t a, b; + if (mod == 1) { + a = pgf_read_int(rdr); + b = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "CALL %s", id); + gu_printf(out, err, "RET hp(%d) tail(%d,%d)\n", h, a, b); #endif - - switch (mod >> 2) { - case 0: { + } else { + a = 0; + b = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "\n"); + gu_printf(out, err, "RET hp(%d) update(%d)\n", h, b); #endif - - jit_getarg_p(JIT_V0, es_arg); - jit_getarg_p(JIT_V1, closure_arg); - jit_prepare(2); - jit_pusharg_p(JIT_V1); - jit_pusharg_p(JIT_V0); - - PgfCallPatch patch; - patch.cid = id; - patch.ref = jit_movi_p(JIT_V0, jit_forward()); - gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch); - jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfAbsFun,function)); - - jit_finishr(JIT_V0); - jit_retval_p(JIT_V1); - break; + jit_movi_p(JIT_R0, abstr->eval_gates->evaluate_indirection); + jit_str_p(JIT_VCLOS, JIT_R0); + jit_stxi_p(offsetof(PgfIndirection,val), JIT_VCLOS, JIT_VHEAP); } - case 1: { - size_t a = pgf_read_int(rdr); - size_t b = pgf_read_int(rdr); -#ifdef PGF_JIT_DEBUG - gu_printf(out, err, " tail(%d,%d)\n", a, b); -#endif - - pgf_jit_compile_slide(rdr, es_arg, a, b); - - PgfCallPatch patch; - patch.cid = id; - patch.ref = jit_movi_p(JIT_V0, jit_forward()); - gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch); - jit_ldxi_p(JIT_RET, JIT_V0, offsetof(PgfAbsFun,function)); - jit_tail_finishr(JIT_RET); - break; - } - default: - gu_impossible(); - } + if (b-(a+1) > 0) + jit_subi_p(JIT_SP, JIT_SP, (b-(a+1))*sizeof(PgfClosure*)); + jit_bare_ret(a*sizeof(PgfClosure*)); break; } case PGF_INSTR_FAIL: @@ -788,38 +1098,6 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, gu_printf(out, err, "FAIL\n"); #endif break; - case PGF_INSTR_UPDATE: { -#ifdef PGF_JIT_DEBUG - gu_printf(out, err, "UPDATE\n"); -#endif - - jit_getarg_p(JIT_V0, closure_arg); - jit_movi_p(JIT_V2, pgf_evaluate_indirection); - jit_stxi_p(0, JIT_V0, JIT_V2); - jit_stxi_p(sizeof(PgfClosure), JIT_V0, JIT_V1); - break; - } - case PGF_INSTR_RET: { - size_t count = pgf_read_int(rdr); - -#ifdef PGF_JIT_DEBUG - gu_printf(out, err, "RET %d\n", count); -#endif - - if (count > 0) { - jit_prepare(2); - jit_movi_ui(JIT_V0, count); - jit_pusharg_p(JIT_V0); - jit_getarg_p(JIT_V0, es_arg); - jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); - jit_pusharg_p(JIT_V0); - jit_finish(gu_buf_trim_n); - } - - jit_movr_p(JIT_RET, JIT_V1); - jit_ret(); - break; - } default: gu_impossible(); } @@ -842,10 +1120,15 @@ pgf_jit_done(PgfReader* rdr, PgfAbstr* abstr) else { PgfAbsFun* con = gu_map_get(abstr->funs, patch->cid, PgfAbsFun*); - if (con != NULL) - jit_patch_movi(patch->ref,con); - else { + if (con == NULL) gu_impossible(); + else if (con->closure_id == 0) { + jit_patch_movi(patch->ref,con); + } else { + size_t offset = + offsetof(PgfEvalState,globals)+ + sizeof(PgfIndirection)*(con->closure_id-1); + jit_patch_movi(patch->ref,offset); } } } diff --git a/src/runtime/c/pgf/lightning/core-common.h b/src/runtime/c/pgf/lightning/core-common.h index 04dbb2c7b..3cda23322 100644 --- a/src/runtime/c/pgf/lightning/core-common.h +++ b/src/runtime/c/pgf/lightning/core-common.h @@ -52,6 +52,12 @@ typedef struct { #define JIT_V0 JIT_V(0) #define JIT_V1 JIT_V(1) #define JIT_V2 JIT_V(2) +#define JIT_FPR0 JIT_FPR(0) +#define JIT_FPR1 JIT_FPR(1) +#define JIT_FPR2 JIT_FPR(2) +#define JIT_FPR3 JIT_FPR(3) +#define JIT_FPR4 JIT_FPR(4) +#define JIT_FPR5 JIT_FPR(5) #define _jitl _jit.jitl @@ -149,7 +155,7 @@ typedef union jit_code { #define jit_xorr_ul(d, s1, s2) jit_xorr_l((d), (s1), (s2)) #define jit_addr_p(d, s1, s2) jit_addr_ul((d), (s1), (s2)) -#define jit_addi_p(d, rs, is) jit_addi_ul((d), (rs), (long) (is)) +#define jit_addi_p(d, rs, is) (jit_addi_ul((d), (rs), (long) (is)), _jit.x.pc) #define jit_movr_p(d, rs) jit_movr_ul((d), (rs)) #define jit_subr_p(d, s1, s2) jit_subr_ul((d), (s1), (s2)) #define jit_subi_p(d, rs, is) jit_subi_ul((d), (rs), (long) (is)) diff --git a/src/runtime/c/pgf/lightning/i386/core-32.h b/src/runtime/c/pgf/lightning/i386/core-32.h index 561fab5fb..9de85b86e 100644 --- a/src/runtime/c/pgf/lightning/i386/core-32.h +++ b/src/runtime/c/pgf/lightning/i386/core-32.h @@ -101,6 +101,8 @@ struct jit_local_state { #define jit_ret() jit_base_ret (_jitl.alloca_offset) #endif +#define jit_bare_ret(IM) ((IM == 0) ? RET_() : RETi(IM)) + #define jit_calli(label) (CALLm( ((unsigned long) (label))), _jit.x.pc) #define jit_callr(reg) CALLsr(reg) @@ -108,16 +110,6 @@ struct jit_local_state { #define jit_finish(sub) (_jitl.finish_ref = jit_calli((sub)), ADDLir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0, _jitl.finish_ref) #define jit_finishr(reg) (jit_callr((reg)), ADDLir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0) -#ifdef __APPLE__ -#define jit_tail_finishr(reg) jit_base_tail_finishr(-12, reg) -#else -#define jit_tail_finishr(reg) jit_base_tail_finishr(_jitl.alloca_offset, reg) -#endif - -#define jit_base_tail_finishr(ofs, reg) \ - (((ofs) < 0 ? LEAVE_() : POPLr(_EBP)), \ - POPLr(_EDI), POPLr(_ESI), POPLr(_EBX), jit_jmpr(reg)) - #define jit_arg_c() ((_jitl.framesize += sizeof(int)) - sizeof(int)) #define jit_arg_uc() ((_jitl.framesize += sizeof(int)) - sizeof(int)) #define jit_arg_s() ((_jitl.framesize += sizeof(int)) - sizeof(int)) diff --git a/src/runtime/c/pgf/lightning/i386/core-64.h b/src/runtime/c/pgf/lightning/i386/core-64.h index 70b4d6069..bd53d9744 100644 --- a/src/runtime/c/pgf/lightning/i386/core-64.h +++ b/src/runtime/c/pgf/lightning/i386/core-64.h @@ -190,14 +190,6 @@ struct jit_local_state { ? (ADDQir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0) \ : 0)) -#ifdef __APPLE__ -#define jit_tail_finishr(reg) jit_base_tail_finishr(-12, reg) -#else -#define jit_tail_finishr(reg) jit_base_tail_finishr(_jitl.alloca_offset, reg) -#endif - -#define jit_base_tail_finishr(ofs, reg) - #define jit_retval_l(rd) ((void)jit_movr_l ((rd), _EAX)) #define jit_arg_i() (_jitl.nextarg_geti < JIT_ARG_MAX \ ? _jitl.nextarg_geti++ \ @@ -273,6 +265,7 @@ static int jit_arg_reg_order[] = { _EDI, _ESI, _EDX, _ECX, _R8D, _R9D }; #define jit_patch_at(jump_pc,v) (_jitl.long_jumps ? jit_patch_long_at((jump_pc)-3, v) : jit_patch_short_at(jump_pc, v)) #define jit_patch_calli(pa,pv) (*_PSL((pa) - sizeof(long)) = _jit_SL((pv))) #define jit_ret() (LEAVE_(), POPQr(_R14), POPQr(_R13), POPQr(_R12), POPQr(_EBX), RET_()) +#define jit_bare_ret(IM) ((IM == 0) ? RET_() : RETi(IM)) /* Memory */ diff --git a/src/runtime/c/pgf/reader.c b/src/runtime/c/pgf/reader.c index 20dfd6e6c..3594f80ed 100644 --- a/src/runtime/c/pgf/reader.c +++ b/src/runtime/c/pgf/reader.c @@ -441,7 +441,7 @@ pgf_read_absfun(PgfReader* rdr, PgfAbstr* abstr) switch (tag) { case 0: absfun->defns = NULL; - absfun->function = NULL; + absfun->closure_id = 0; break; case 1: { GuLength length = pgf_read_len(rdr); @@ -557,6 +557,8 @@ pgf_read_abstract(PgfReader* rdr, PgfAbstr* abstract) abstract->aflags = pgf_read_flags(rdr); gu_return_on_exn(rdr->err, ); + abstract->eval_gates = pgf_jit_gates(rdr); + abstract->funs = pgf_read_absfuns(rdr, abstract); gu_return_on_exn(rdr->err, ); diff --git a/src/runtime/c/pgf/reader.h b/src/runtime/c/pgf/reader.h index 98042c330..6fa24e6d2 100644 --- a/src/runtime/c/pgf/reader.h +++ b/src/runtime/c/pgf/reader.h @@ -53,6 +53,9 @@ typedef struct PgfJitState PgfJitState; PgfJitState* pgf_new_jit(PgfReader* rdr); +PgfEvalGates* +pgf_jit_gates(PgfReader* rdr); + void pgf_jit_predicate(PgfReader* rdr, PgfAbstr* abstr, PgfAbsCat* abscat);