summaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/c/pgf/jit.c163
-rw-r--r--src/runtime/c/pgf/reasoner.c9
2 files changed, 104 insertions, 68 deletions
diff --git a/src/runtime/c/pgf/jit.c b/src/runtime/c/pgf/jit.c
index 9889bf4e6..7a512e8f3 100644
--- a/src/runtime/c/pgf/jit.c
+++ b/src/runtime/c/pgf/jit.c
@@ -41,15 +41,12 @@ pgf_jit_finalize_page(GuFinalizer* self)
free(fin->page);
}
-static size_t total_size = 0;
-
static void
pgf_jit_alloc_page(PgfJitState* state)
{
void *page;
size_t page_size = getpagesize();
- total_size += page_size;
if (posix_memalign(&page, page_size, page_size) != 0) {
gu_fatal("Memory allocation failed");
@@ -166,92 +163,124 @@ pgf_jit_predicate(PgfJitState* state,
jit_getarg_p(JIT_V1, rs_arg);
jit_getarg_p(JIT_V2, st_arg);
- if (i+1 < n_funs) {
- PgfAbsFun* absfun =
- gu_buf_get(abscat->functions, PgfAbsFun*, i+1);
+ size_t n_hypos = gu_seq_length(absfun->type->hypos);
+
+ if (n_hypos > 0) {
+ if (i+1 < n_funs) {
+ PgfAbsFun* absfun =
+ gu_buf_get(abscat->functions, PgfAbsFun*, i+1);
#ifdef PGF_JIT_DEBUG
- gu_puts(" TRY_ELSE ", wtr, err);
- gu_string_write(absfun->name, wtr, err);
- gu_puts("\n", wtr, err);
+ gu_puts(" TRY_ELSE ", wtr, err);
+ gu_string_write(absfun->name, wtr, err);
+ gu_puts("\n", wtr, err);
#endif
- // compile TRY_ELSE
- jit_prepare(3);
- jit_movi_p(JIT_V0, absfun);
- jit_pusharg_p(JIT_V0);
- jit_pusharg_p(JIT_V2);
- jit_pusharg_p(JIT_V1);
- jit_finish(pgf_try_else);
- }
-
- size_t n_hypos = gu_seq_length(absfun->type->hypos);
- for (size_t i = 0; i < n_hypos; i++) {
- PgfHypo* hypo = gu_seq_index(absfun->type->hypos, PgfHypo, i);
+ // compile TRY_ELSE
+ jit_prepare(3);
+ jit_movi_p(JIT_V0, absfun);
+ jit_pusharg_p(JIT_V0);
+ jit_pusharg_p(JIT_V2);
+ jit_pusharg_p(JIT_V1);
+ jit_finish(pgf_try_else);
+ }
+
+ for (size_t i = 0; i < n_hypos; i++) {
+ PgfHypo* hypo = gu_seq_index(absfun->type->hypos, PgfHypo, i);
- jit_insn *ref;
-
- // call the predicate for the category in hypo->type->cid
- PgfAbsCat* arg =
- gu_map_get(abscats, &hypo->type->cid, PgfAbsCat*);
+ jit_insn *ref;
+
+ // call the predicate for the category in hypo->type->cid
+ PgfAbsCat* arg =
+ gu_map_get(abscats, &hypo->type->cid, PgfAbsCat*);
#ifdef PGF_JIT_DEBUG
- gu_puts(" CALL ", wtr, err);
- gu_string_write(hypo->type->cid, wtr, err);
- gu_printf(wtr, err, " L%d\n", label);
+ gu_puts(" CALL ", wtr, err);
+ gu_string_write(hypo->type->cid, wtr, err);
+ if (i+1 < n_hypos) {
+ gu_printf(wtr, err, " L%d\n", label);
+ } else {
+ gu_printf(wtr, err, " COMPLETE\n");
+ }
#endif
- // compile CALL
- ref = jit_movi_p(JIT_V0, jit_forward());
- jit_str_p(JIT_V2, JIT_V0);
- jit_prepare(2);
- jit_pusharg_p(JIT_V2);
- jit_pusharg_p(JIT_V1);
- if (arg != NULL) {
- jit_finish(arg->predicate);
- } else {
- PgfCallPatch patch;
- patch.cid = hypo->type->cid;
- patch.ref = jit_finish(jit_forward());
- gu_buf_push(state->patches, PgfCallPatch, patch);
- }
+ // compile CALL
+ ref = jit_movi_p(JIT_V0, jit_forward());
+ jit_str_p(JIT_V2, JIT_V0);
+ jit_prepare(2);
+ jit_pusharg_p(JIT_V2);
+ jit_pusharg_p(JIT_V1);
+ if (arg != NULL) {
+ jit_finish(arg->predicate);
+ } else {
+ PgfCallPatch patch;
+ patch.cid = hypo->type->cid;
+ patch.ref = jit_finish(jit_forward());
+ gu_buf_push(state->patches, PgfCallPatch, patch);
+ }
#ifdef PGF_JIT_DEBUG
- gu_puts(" RET\n", wtr, err);
- gu_printf(wtr, err, "L%d:\n", label++);
+ gu_puts(" RET\n", wtr, err);
+ if (i+1 < n_hypos) {
+ gu_printf(wtr, err, "L%d:\n", label++);
+ }
#endif
- // compile RET
- jit_ret();
-
- pgf_jit_make_space(state);
+ // compile RET
+ jit_ret();
+
+ if (i+1 < n_hypos) {
+ pgf_jit_make_space(state);
+
+ jit_patch_movi(ref,jit_get_label());
+
+ jit_prolog(2);
+ rs_arg = jit_arg_p();
+ st_arg = jit_arg_p();
+ jit_getarg_p(JIT_V1, rs_arg);
+ jit_getarg_p(JIT_V2, st_arg);
+ } else {
+ jit_patch_movi(ref,pgf_complete);
+ }
+ }
+ } else {
+ if (i+1 < n_funs) {
+ PgfAbsFun* absfun =
+ gu_buf_get(abscat->functions, PgfAbsFun*, i+1);
- jit_patch_movi(ref,jit_get_label());
-
- jit_prolog(2);
- rs_arg = jit_arg_p();
- st_arg = jit_arg_p();
- jit_getarg_p(JIT_V1, rs_arg);
- jit_getarg_p(JIT_V2, st_arg);
- }
+#ifdef PGF_JIT_DEBUG
+ gu_puts(" TRY_CONSTANT ", wtr, err);
+ gu_string_write(absfun->name, wtr, err);
+ gu_puts("\n", wtr, err);
+#endif
+ // compile TRY_CONSTANT
+ jit_prepare(3);
+ jit_movi_p(JIT_V0, absfun);
+ jit_pusharg_p(JIT_V0);
+ jit_pusharg_p(JIT_V2);
+ jit_pusharg_p(JIT_V1);
+ jit_finish(pgf_try_constant);
+ } else {
#ifdef PGF_JIT_DEBUG
- gu_puts(" COMPLETE\n", wtr, err);
+ gu_puts(" COMPLETE\n", wtr, err);
#endif
- // compile COMPLETE
- jit_prepare(2);
- jit_pusharg_p(JIT_V2);
- jit_pusharg_p(JIT_V1);
- jit_finish(pgf_complete);
+ // compile COMPLETE
+ jit_prepare(2);
+ jit_pusharg_p(JIT_V2);
+ jit_pusharg_p(JIT_V1);
+ jit_finish(pgf_complete);
+ }
#ifdef PGF_JIT_DEBUG
- gu_puts(" RET\n", wtr, err);
+ gu_puts(" RET\n", wtr, err);
#endif
- // compile RET
- jit_ret();
-
+ // compile RET
+ jit_ret();
+ }
+
#ifdef PGF_JIT_DEBUG
if (i+1 < n_funs) {
PgfAbsFun* absfun =
diff --git a/src/runtime/c/pgf/reasoner.c b/src/runtime/c/pgf/reasoner.c
index 3e5c64692..179933e91 100644
--- a/src/runtime/c/pgf/reasoner.c
+++ b/src/runtime/c/pgf/reasoner.c
@@ -40,7 +40,7 @@ struct PgfExprState {
typedef struct {
// base must be the first field in order to be able to cast
- // from PgfCombine2State to PgfReasonerState
+ // from PgfCombine1State to PgfReasonerState
PgfReasonerState base;
GuBuf* exprs;
PgfExprState* parent;
@@ -331,6 +331,13 @@ pgf_complete(PgfReasoner* rs, PgfExprState* st)
nst->base.continuation(rs, &nst->base);
}
+void
+pgf_try_constant(PgfReasoner* rs, PgfExprState* prev, PgfAbsFun* absfun)
+{
+ pgf_try_else(rs, prev, absfun);
+ pgf_complete(rs, prev);
+}
+
static PgfExprProb*
pgf_reasoner_next(PgfReasoner* rs)
{