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);