From c30e2df228fc42653149752b56e50e77bae03b9f Mon Sep 17 00:00:00 2001 From: "kr.angelov" Date: Mon, 11 Aug 2014 15:53:41 +0000 Subject: [PATCH] pattern matching in def rules is now supported --- src/compiler/GF/Compile/GrammarToPGF.hs | 8 +-- src/runtime/c/gu/seq.c | 6 ++ src/runtime/c/gu/seq.h | 3 + src/runtime/c/pgf/evaluator.c | 44 ++++--------- src/runtime/c/pgf/jit.c | 73 +++++++++++++++------- src/runtime/c/pgf/lightning/i386/core-32.h | 2 +- 6 files changed, 76 insertions(+), 60 deletions(-) diff --git a/src/compiler/GF/Compile/GrammarToPGF.hs b/src/compiler/GF/Compile/GrammarToPGF.hs index f042d5f38..6373133d7 100644 --- a/src/compiler/GF/Compile/GrammarToPGF.hs +++ b/src/compiler/GF/Compile/GrammarToPGF.hs @@ -50,7 +50,7 @@ mkCanon2pgf opts gr am = do funs = Map.fromList [(i2i f, (mkType [] ty, arity, mkDef arity mdef, 0)) | ((m,f),AbsFun (Just (L _ ty)) ma mdef _) <- adefs, - let arity = mkArrity ma] + let arity = mkArrity ma ty] cats = Map.fromList [(i2i c, (snd (mkContext [] cont),catfuns c, 0)) | ((m,c),AbsCat (Just (L _ cont))) <- adefs] @@ -150,9 +150,9 @@ mkDef arity (Just eqs) = Just ([C.Equ ps' (mkExp scope' e) | L _ (ps,e) <- eqs, ) mkDef arity Nothing = Nothing -mkArrity (Just a) = a -mkArrity Nothing = 0 - +mkArrity (Just a) ty = a +mkArrity Nothing ty = let (ctxt, _, _) = GM.typeForm ty + in length ctxt genCncCats gr am cm cdefs = let (index,cats) = mkCncCats 0 cdefs diff --git a/src/runtime/c/gu/seq.c b/src/runtime/c/gu/seq.c index 2c3d6c3e3..2b99df318 100644 --- a/src/runtime/c/gu/seq.c +++ b/src/runtime/c/gu/seq.c @@ -136,6 +136,12 @@ 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 5accb0b24..034620140 100644 --- a/src/runtime/c/gu/seq.h +++ b/src/runtime/c/gu/seq.h @@ -65,6 +65,9 @@ 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/evaluator.c b/src/runtime/c/pgf/evaluator.c index ee2bd8511..fca499a98 100644 --- a/src/runtime/c/pgf/evaluator.c +++ b/src/runtime/c/pgf/evaluator.c @@ -9,12 +9,6 @@ struct PgfEnv { PgfClosure* closure; }; -typedef PgfClosure* (*PgfFunction)(PgfEvalState* state, PgfClosure* val); - -struct PgfClosure { - PgfFunction code; -}; - typedef struct { PgfClosure header; PgfEnv* env; @@ -26,12 +20,6 @@ typedef struct { PgfClosure* val; } PgfIndirection; -typedef struct { - PgfClosure header; - PgfAbsFun* absfun; - PgfClosure* args[]; -} PgfValue; - typedef struct { PgfClosure header; int level; @@ -62,26 +50,7 @@ pgf_evaluate_indirection(PgfEvalState* state, PgfClosure* closure) PgfClosure* pgf_evaluate_value(PgfEvalState* state, PgfClosure* closure) { - PgfValue* val = (PgfValue*) closure; - - size_t n_args = gu_seq_length(val->absfun->type->hypos) + - gu_buf_length(state->stack); - PgfValue* new_val = - gu_new_flex(state->pool, PgfValue, args, n_args); - new_val->header.code = pgf_evaluate_value; - new_val->absfun = val->absfun; - - size_t i = 0; - while (i < gu_seq_length(val->absfun->type->hypos)) { - 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; + return closure; } static PgfClosure* @@ -233,7 +202,7 @@ pgf_evaluate_expr_thunk(PgfEvalState* state, PgfClosure* closure) if (absfun->function != NULL) { val = (PgfValue*) ((PgfFunction) absfun->function)(state, closure); } else { - size_t n_args = gu_buf_length(state->stack); + size_t n_args = absfun->arity; val = gu_new_flex(state->pool, PgfValue, args, n_args); val->header.code = pgf_evaluate_value; @@ -290,6 +259,15 @@ pgf_evaluate_expr_thunk(PgfEvalState* state, PgfClosure* closure) } } +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]); + } +} + static PgfExpr pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool) { diff --git a/src/runtime/c/pgf/jit.c b/src/runtime/c/pgf/jit.c index ba7788a1a..20ddd9f68 100644 --- a/src/runtime/c/pgf/jit.c +++ b/src/runtime/c/pgf/jit.c @@ -13,7 +13,8 @@ struct PgfJitState { jit_state jit; jit_insn *buf; char *save_ip_ptr; - GuBuf* patches; + GuBuf* call_patches; + GuBuf* label_patches; }; #define _jit (rdr->jit_state->jit) @@ -23,6 +24,11 @@ typedef struct { jit_insn *ref; } PgfCallPatch; +typedef struct { + size_t label; + jit_insn *ref; +} PgfLabelPatch; + // 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. @@ -71,7 +77,8 @@ PgfJitState* pgf_new_jit(PgfReader* rdr) { PgfJitState* state = gu_new(PgfJitState, rdr->tmp_pool); - state->patches = gu_new_buf(PgfCallPatch, rdr->tmp_pool); + state->call_patches = gu_new_buf(PgfCallPatch, rdr->tmp_pool); + state->label_patches = gu_new_buf(PgfLabelPatch, rdr->tmp_pool); state->buf = NULL; state->save_ip_ptr = NULL; return state; @@ -233,7 +240,7 @@ pgf_jit_predicate(PgfReader* rdr, PgfAbstr* abstr, PgfCallPatch patch; patch.cid = hypo->type->cid; patch.ref = jit_finish(jit_forward()); - gu_buf_push(rdr->jit_state->patches, PgfCallPatch, patch); + gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch); #ifdef PGF_JIT_DEBUG gu_puts(" RET\n", out, err); @@ -336,8 +343,20 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, size_t curr_offset = 0; size_t curr_label = 0; - + + gu_buf_flush(rdr->jit_state->label_patches); + for (size_t i = 0; i < n_instrs; i++) { + size_t labels_count = gu_buf_length(rdr->jit_state->label_patches); + if (labels_count > 0) { + PgfLabelPatch* patch = + gu_buf_index(rdr->jit_state->label_patches, PgfLabelPatch, labels_count-1); + if (patch->label == curr_label) { + jit_patch(patch->ref); + gu_buf_trim_n(rdr->jit_state->label_patches, 1); + } + } + #ifdef PGF_JIT_DEBUG gu_printf(out, err, "%04d ", curr_label++); #endif @@ -354,19 +373,16 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); jit_prepare(1); jit_pusharg_p(JIT_V0); - jit_finish(gu_buf_length); - jit_subi_i(JIT_V2, JIT_RET, index+1); - jit_lshi_i(JIT_V2, JIT_V2, 2); - jit_prepare(1); - jit_pusharg_p(JIT_V0); - jit_finish(gu_buf_data); - jit_ldxr_p(JIT_V0, JIT_RET, JIT_V2); + jit_finish(gu_buf_last); + jit_ldxr_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*)); 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_callr(JIT_V0); + jit_finishr(JIT_V0); + jit_retval_p(JIT_V1); + jit_ldxi_p(JIT_V0, JIT_V1, offsetof(PgfValue, absfun)); break; } case PGF_INSTR_CASE: { @@ -375,6 +391,24 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, #ifdef PGF_JIT_DEBUG gu_printf(out, err, "CASE %s %04d\n", id, curr_label+offset); #endif + jit_insn *jump= + jit_bnei_i(jit_forward(), JIT_V0, (int) jit_forward()); + + PgfLabelPatch label_patch; + label_patch.label = curr_label+offset; + label_patch.ref = jump; + gu_buf_push(rdr->jit_state->label_patches, PgfLabelPatch, label_patch); + + PgfCallPatch call_patch; + call_patch.cid = id; + 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); break; } case PGF_INSTR_CASE_INT: { @@ -434,7 +468,7 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); curr_offset++; - gu_buf_push(rdr->jit_state->patches, PgfCallPatch, patch); + gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch); break; } case PGF_INSTR_PUT_CLOSURE: { @@ -486,13 +520,8 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); jit_prepare(1); jit_pusharg_p(JIT_V0); - jit_finish(gu_buf_length); - jit_subi_i(JIT_V2, JIT_RET, index+1); - jit_lshi_i(JIT_V2, JIT_V2, 2); - jit_prepare(1); - jit_pusharg_p(JIT_V0); - jit_finish(gu_buf_data); - jit_ldxr_p(JIT_V0, JIT_RET, JIT_V2); + jit_finish(gu_buf_last); + jit_ldxi_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*)); jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); break; } @@ -536,10 +565,10 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, void pgf_jit_done(PgfReader* rdr, PgfAbstr* abstr) { - size_t n_patches = gu_buf_length(rdr->jit_state->patches); + size_t n_patches = gu_buf_length(rdr->jit_state->call_patches); for (size_t i = 0; i < n_patches; i++) { PgfCallPatch* patch = - gu_buf_index(rdr->jit_state->patches, PgfCallPatch, i); + gu_buf_index(rdr->jit_state->call_patches, PgfCallPatch, i); PgfAbsCat* arg = gu_map_get(abstr->cats, patch->cid, PgfAbsCat*); diff --git a/src/runtime/c/pgf/lightning/i386/core-32.h b/src/runtime/c/pgf/lightning/i386/core-32.h index a94682def..9b1810761 100644 --- a/src/runtime/c/pgf/lightning/i386/core-32.h +++ b/src/runtime/c/pgf/lightning/i386/core-32.h @@ -106,7 +106,7 @@ struct jit_local_state { #define jit_pusharg_i(rs) PUSHLr(rs) #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)), ) +#define jit_finishr(reg) (jit_callr((reg)), ADDLir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0) #define jit_arg_c() ((_jitl.framesize += sizeof(int)) - sizeof(int)) #define jit_arg_uc() ((_jitl.framesize += sizeof(int)) - sizeof(int))