From e43001def37e5bb24dc62cac8806a3030b385ab7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Mon, 15 Feb 2021 12:06:58 +0100 Subject: [PATCH] :art: string and branch optimizations --- src/emit/emit.c | 32 +++++++++++++++++++++++++++----- src/lib/string.c | 25 +++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index c015c73f..fe45053d 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1501,7 +1501,15 @@ ANN2(1) /*static */m_bool emit_exp(const Emitter emit, /* const */Exp e) { return GW_OK; } +ANN static m_bool emit_if_const(const Emitter emit, const Stmt_If stmt) { + if(stmt->cond->d.prim.d.num) + return emit_stmt(emit, stmt->if_body, 1); + return stmt->else_body ? emit_stmt(emit, stmt->else_body, 1) : GW_OK; +} + ANN static m_bool emit_if(const Emitter emit, const Stmt_If stmt) { + if(stmt->cond->exp_type == ae_exp_primary && stmt->cond->d.prim.prim_type == ae_prim_num) + return emit_if_const(emit, stmt); DECL_OB(const Instr, op, = emit_flow(emit, stmt->cond)) CHECK_BB(scoped_stmt(emit, stmt->if_body, 1)) const Instr op2 = emit_add_instr(emit, Goto); @@ -1609,16 +1617,30 @@ ANN static void emit_pop_stack(const Emitter emit, const m_uint index) { ANN static m_bool _emit_stmt_flow(const Emitter emit, const Stmt_Flow stmt, const m_uint index) { Instr op = NULL; - if(!stmt->is_do) - op = _flow(emit, stmt->cond, stmt_self(stmt)->stmt_type == ae_stmt_while); + const ae_stmt_t is_while = stmt_self(stmt)->stmt_type == ae_stmt_while; + const uint is_const = stmt->cond->exp_type == ae_exp_primary && stmt->cond->d.prim.prim_type == ae_prim_num; + if(!stmt->is_do) { + if(!is_const) + op = _flow(emit, stmt->cond, is_while); + else if((!is_while && stmt->cond->d.prim.d.num) || + (is_while && !stmt->cond->d.prim.d.num)) + return GW_OK; + } CHECK_BB(scoped_stmt(emit, stmt->body, 1)) if(stmt->is_do) { - CHECK_OB((op = _flow(emit, stmt->cond, stmt_self(stmt)->stmt_type != ae_stmt_while))) - op->m_val = index; + if(!is_const) { + CHECK_OB((op = _flow(emit, stmt->cond, !is_while))) + op->m_val = index; + } else if((is_while && stmt->cond->d.prim.d.num) || + (!is_while && !stmt->cond->d.prim.d.num)) { + const Instr goto_ = emit_add_instr(emit, Goto); + goto_->m_val = index; + } } else { const Instr goto_ = emit_add_instr(emit, Goto); goto_->m_val = index; - op->m_val = emit_code_size(emit); + if(op) + op->m_val = emit_code_size(emit); } return GW_OK; } diff --git a/src/lib/string.c b/src/lib/string.c index 560694de..25b80dfc 100644 --- a/src/lib/string.c +++ b/src/lib/string.c @@ -25,6 +25,29 @@ static INSTR(String_##name) { \ describe_string_logical(eq, (!strcmp(STRING(lhs), STRING(rhs)))) describe_string_logical(neq, (strcmp(STRING(lhs), STRING(rhs)))) +static inline uint is_const_str(const Exp exp) { + return exp->exp_type == ae_exp_primary && + exp->d.prim.prim_type == ae_prim_str; +} + +#define opck_str(name, __exp__) \ +OP_CHECK(opck_string_##name) { \ + Exp_Binary *bin = (Exp_Binary*)data; \ + if(!is_const_str(bin->lhs) || !is_const_str(bin->rhs)) \ + return env->gwion->type[et_bool]; \ + const int ret = __exp__; \ + free_exp(env->gwion->mp, bin->lhs); \ + free_exp(env->gwion->mp, bin->rhs); \ + const Exp e = exp_self(bin); \ + e->exp_type = ae_exp_primary; \ + e->d.prim.prim_type = ae_prim_num; \ + e->d.prim.d.num = ret; \ + return env->gwion->type[et_bool]; \ +} + +opck_str(eq, !strcmp(bin->lhs->d.prim.d.str, bin->rhs->d.prim.d.str)) +opck_str(neq, strcmp(bin->lhs->d.prim.d.str, bin->rhs->d.prim.d.str)) + static CTOR(string_ctor) { STRING(o) = _mp_calloc(shred->info->vm->gwion->mp, 1); } @@ -457,7 +480,9 @@ GWION_IMPORT(string) { GWI_BB(gwi_class_end(gwi)) GWI_BB(gwi_oper_ini(gwi, "string", "string", "bool")) + GWI_BB(gwi_oper_add(gwi, opck_string_eq)) GWI_BB(gwi_oper_end(gwi, "==", String_eq)) + GWI_BB(gwi_oper_add(gwi, opck_string_neq)) GWI_BB(gwi_oper_end(gwi, "!=", String_neq)) GWI_BB(gwi_oper_ini(gwi, "int", "string", "string")) -- 2.43.0