mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-24 03:52:50 -06:00
an optimization in the jitter for generating more compact code
This commit is contained in:
@@ -41,15 +41,12 @@ pgf_jit_finalize_page(GuFinalizer* self)
|
|||||||
free(fin->page);
|
free(fin->page);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t total_size = 0;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pgf_jit_alloc_page(PgfJitState* state)
|
pgf_jit_alloc_page(PgfJitState* state)
|
||||||
{
|
{
|
||||||
void *page;
|
void *page;
|
||||||
|
|
||||||
size_t page_size = getpagesize();
|
size_t page_size = getpagesize();
|
||||||
total_size += page_size;
|
|
||||||
|
|
||||||
if (posix_memalign(&page, page_size, page_size) != 0) {
|
if (posix_memalign(&page, page_size, page_size) != 0) {
|
||||||
gu_fatal("Memory allocation failed");
|
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_V1, rs_arg);
|
||||||
jit_getarg_p(JIT_V2, st_arg);
|
jit_getarg_p(JIT_V2, st_arg);
|
||||||
|
|
||||||
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);
|
|
||||||
#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);
|
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);
|
|
||||||
|
|
||||||
jit_insn *ref;
|
if (n_hypos > 0) {
|
||||||
|
if (i+1 < n_funs) {
|
||||||
// call the predicate for the category in hypo->type->cid
|
PgfAbsFun* absfun =
|
||||||
PgfAbsCat* arg =
|
gu_buf_get(abscat->functions, PgfAbsFun*, i+1);
|
||||||
gu_map_get(abscats, &hypo->type->cid, PgfAbsCat*);
|
|
||||||
|
|
||||||
#ifdef PGF_JIT_DEBUG
|
#ifdef PGF_JIT_DEBUG
|
||||||
gu_puts(" CALL ", wtr, err);
|
gu_puts(" TRY_ELSE ", wtr, err);
|
||||||
gu_string_write(hypo->type->cid, wtr, err);
|
gu_string_write(absfun->name, wtr, err);
|
||||||
gu_printf(wtr, err, " L%d\n", label);
|
gu_puts("\n", wtr, err);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// compile CALL
|
// compile TRY_ELSE
|
||||||
ref = jit_movi_p(JIT_V0, jit_forward());
|
jit_prepare(3);
|
||||||
jit_str_p(JIT_V2, JIT_V0);
|
jit_movi_p(JIT_V0, absfun);
|
||||||
jit_prepare(2);
|
jit_pusharg_p(JIT_V0);
|
||||||
jit_pusharg_p(JIT_V2);
|
jit_pusharg_p(JIT_V2);
|
||||||
jit_pusharg_p(JIT_V1);
|
jit_pusharg_p(JIT_V1);
|
||||||
if (arg != NULL) {
|
jit_finish(pgf_try_else);
|
||||||
jit_finish(arg->predicate);
|
}
|
||||||
|
|
||||||
|
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*);
|
||||||
|
|
||||||
|
#ifdef PGF_JIT_DEBUG
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef PGF_JIT_DEBUG
|
||||||
|
gu_puts(" RET\n", wtr, err);
|
||||||
|
if (i+1 < n_hypos) {
|
||||||
|
gu_printf(wtr, err, "L%d:\n", label++);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
#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 {
|
} else {
|
||||||
PgfCallPatch patch;
|
#ifdef PGF_JIT_DEBUG
|
||||||
patch.cid = hypo->type->cid;
|
gu_puts(" COMPLETE\n", wtr, err);
|
||||||
patch.ref = jit_finish(jit_forward());
|
#endif
|
||||||
gu_buf_push(state->patches, PgfCallPatch, patch);
|
|
||||||
|
// compile COMPLETE
|
||||||
|
jit_prepare(2);
|
||||||
|
jit_pusharg_p(JIT_V2);
|
||||||
|
jit_pusharg_p(JIT_V1);
|
||||||
|
jit_finish(pgf_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PGF_JIT_DEBUG
|
#ifdef PGF_JIT_DEBUG
|
||||||
gu_puts(" RET\n", wtr, err);
|
gu_puts(" RET\n", wtr, err);
|
||||||
gu_printf(wtr, err, "L%d:\n", label++);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// compile RET
|
// compile RET
|
||||||
jit_ret();
|
jit_ret();
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PGF_JIT_DEBUG
|
|
||||||
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);
|
|
||||||
|
|
||||||
#ifdef PGF_JIT_DEBUG
|
|
||||||
gu_puts(" RET\n", wtr, err);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// compile RET
|
|
||||||
jit_ret();
|
|
||||||
|
|
||||||
#ifdef PGF_JIT_DEBUG
|
#ifdef PGF_JIT_DEBUG
|
||||||
if (i+1 < n_funs) {
|
if (i+1 < n_funs) {
|
||||||
PgfAbsFun* absfun =
|
PgfAbsFun* absfun =
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ struct PgfExprState {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// base must be the first field in order to be able to cast
|
// base must be the first field in order to be able to cast
|
||||||
// from PgfCombine2State to PgfReasonerState
|
// from PgfCombine1State to PgfReasonerState
|
||||||
PgfReasonerState base;
|
PgfReasonerState base;
|
||||||
GuBuf* exprs;
|
GuBuf* exprs;
|
||||||
PgfExprState* parent;
|
PgfExprState* parent;
|
||||||
@@ -331,6 +331,13 @@ pgf_complete(PgfReasoner* rs, PgfExprState* st)
|
|||||||
nst->base.continuation(rs, &nst->base);
|
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*
|
static PgfExprProb*
|
||||||
pgf_reasoner_next(PgfReasoner* rs)
|
pgf_reasoner_next(PgfReasoner* rs)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user