Skip to content

Commit

Permalink
fixed #258: do a folding during analyzing.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kray-G committed Mar 31, 2021
1 parent 5f0de1a commit bdeddc3
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 34 deletions.
2 changes: 1 addition & 1 deletion include/kxoptimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <kinx.h>

typedef void (*opt_ast_func_t)(kx_context_t *ctx, kx_object_t *node);
extern void opt_ast_constant_folding(kx_context_t *ctx, kx_object_t *node);
extern int opt_ast_constant_folding(kx_context_t *ctx, kx_object_t *node);

typedef void (*opt_code_func_t)(kvec_pt(kx_code_t) *fixcode, int start);
extern void opt_code_remove_jmp(kvec_pt(kx_code_t) *fixcode, int start);
Expand Down
69 changes: 39 additions & 30 deletions src/ast_analyzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,36 +706,45 @@ LOOP_HEAD:;
kx_object_t *n = NULL;
int vtype = KX_UNKNOWN_T;
if (!actx->lvalue && sym->optional == KXDC_CONST && sym->base->init) {
switch (sym->base->init->type) {
case KXVL_INT:
n = kx_gen_int_object(sym->base->init->value.i);
vtype = KX_INT_T;
break;
case KXVL_DBL:
n = kx_gen_dbl_object(sym->base->init->value.d);
vtype = KX_DBL_T;
break;
case KXVL_STR:
n = kx_gen_str_object(sym->base->init->value.s);
vtype = KX_CSTR_T;
break;
case KXVL_BIG:
n = kx_gen_big_object(sym->base->init->value.s);
vtype = KX_BIG_T;
break;
case KXVL_NULL:
n = kx_gen_special_object(KXVL_NULL);
vtype = KX_UND_T;
break;
case KXVL_TRUE:
n = kx_gen_special_object(KXVL_TRUE);
vtype = KX_INT_T;
break;
case KXVL_FALSE:
n = kx_gen_special_object(KXVL_FALSE);
vtype = KX_INT_T;
break;
}
int retry;
do {
retry = 0;
switch (sym->base->init->type) {
case KXVL_INT:
n = kx_gen_int_object(sym->base->init->value.i);
vtype = KX_INT_T;
break;
case KXVL_DBL:
n = kx_gen_dbl_object(sym->base->init->value.d);
vtype = KX_DBL_T;
break;
case KXVL_STR:
n = kx_gen_str_object(sym->base->init->value.s);
vtype = KX_CSTR_T;
break;
case KXVL_BIG:
n = kx_gen_big_object(sym->base->init->value.s);
vtype = KX_BIG_T;
break;
case KXVL_NULL:
n = kx_gen_special_object(KXVL_NULL);
vtype = KX_UND_T;
break;
case KXVL_TRUE:
n = kx_gen_special_object(KXVL_TRUE);
vtype = KX_INT_T;
break;
case KXVL_FALSE:
n = kx_gen_special_object(KXVL_FALSE);
vtype = KX_INT_T;
break;
default:
if (sym->base->init->type < KXST_EXPR) {
retry = opt_ast_constant_folding(ctx, sym->base->init);
}
break;
}
} while (!n && retry);
if (n) {
node->lhs = n;
analyze_ast(ctx, node->lhs, actx); // expanding const value.
Expand Down
18 changes: 15 additions & 3 deletions src/optimizer/opt_cfold.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <kxoptimizer.h>

#define KX_OPT_REPLACE_NODE(node, expr) \
cctx->changed++; \
node->value.i = expr; \
node->type = KXVL_INT; \
node->lhs = NULL; \
Expand All @@ -9,8 +10,9 @@
/**/
#define KX_CONST_VAR_CHECK(p, br) { \
kx_object_t *n = p->br; \
if (n->type == KXOP_VAR && n->lhs) { \
if (p->br != n->lhs && n->type == KXOP_VAR && n->lhs) { \
if (n->lhs->type == KXVL_INT || n->lhs->type == KXVL_DBL) { \
cctx->changed++; \
p->br = n->lhs; \
} \
} \
Expand All @@ -23,6 +25,7 @@ typedef struct folding_context_ {
int exprlist_r2l;
int in_function;
int in_case_when;
int changed;
} folding_context_t;

static void opt_ast_constant_folding_impl(kx_context_t *ctx, kx_object_t *node, folding_context_t *cctx)
Expand Down Expand Up @@ -223,6 +226,7 @@ static void opt_ast_constant_folding_impl(kx_context_t *ctx, kx_object_t *node,
if (v1val % (v2val > 0 ? v2val : -v2val) == 0) {
KX_OPT_REPLACE_NODE(node, v1val / v2val);
} else {
cctx->changed++;
node->value.d = (double)v1val / v2val;
node->type = KXVL_DBL;
node->lhs = NULL;
Expand Down Expand Up @@ -468,10 +472,18 @@ static void opt_ast_constant_folding_impl(kx_context_t *ctx, kx_object_t *node,
}
}

void opt_ast_constant_folding(kx_context_t *ctx, kx_object_t *node)
int opt_ast_constant_folding(kx_context_t *ctx, kx_object_t *node)
{
folding_context_t cctx = {0};
cctx.anon_check = (node->type == KXST_STMTLIST && node->optional == 0);
++node->optional;
opt_ast_constant_folding_impl(ctx, node, &cctx);
int changed = 0;
do {
cctx.changed = 0;
opt_ast_constant_folding_impl(ctx, node, &cctx);
if (changed < cctx.changed) {
changed = cctx.changed;
}
} while (cctx.changed > 0);
return changed;
}

0 comments on commit bdeddc3

Please sign in to comment.