From: Dale Weiler Date: Thu, 17 Oct 2013 04:14:42 +0000 (-0400) Subject: Fix handling on intrinsic folding, this closes #118. X-Git-Tag: 0.3.5~18 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=869905388781e978c4d3a5e4adcf999f19c4a099;p=xonotic%2Fgmqcc.git Fix handling on intrinsic folding, this closes #118. --- diff --git a/fold.c b/fold.c index 99ab737..4664487 100644 --- a/fold.c +++ b/fold.c @@ -734,13 +734,18 @@ static GMQCC_INLINE ast_expression *fold_intrin_fabs(fold_t *fold, ast_value *va } ast_expression *fold_intrin(fold_t *fold, const char *intrin, ast_expression **arg) { - if (!strcmp(intrin, "mod")) return fold_intrin_mod (fold, (ast_value*)arg[0], (ast_value*)arg[1]); - if (!strcmp(intrin, "pow")) return fold_intrin_pow (fold, (ast_value*)arg[0], (ast_value*)arg[1]); - if (!strcmp(intrin, "exp")) return fold_intrin_exp (fold, (ast_value*)arg[0]); - if (!strcmp(intrin, "isnan")) return fold_intrin_isnan(fold, (ast_value*)arg[0]); - if (!strcmp(intrin, "fabs")) return fold_intrin_fabs (fold, (ast_value*)arg[0]); + ast_expression *ret = NULL; - return NULL; + if (!strcmp(intrin, "mod")) ret = fold_intrin_mod (fold, (ast_value*)arg[0], (ast_value*)arg[1]); + if (!strcmp(intrin, "pow")) ret = fold_intrin_pow (fold, (ast_value*)arg[0], (ast_value*)arg[1]); + if (!strcmp(intrin, "exp")) ret = fold_intrin_exp (fold, (ast_value*)arg[0]); + if (!strcmp(intrin, "isnan")) ret = fold_intrin_isnan(fold, (ast_value*)arg[0]); + if (!strcmp(intrin, "fabs")) ret = fold_intrin_fabs (fold, (ast_value*)arg[0]); + + if (ret) + ++opts_optimizationcount[OPTIM_CONST_FOLD]; + + return ret; } /* diff --git a/intrin.c b/intrin.c index 92ae4b8..20d82c6 100644 --- a/intrin.c +++ b/intrin.c @@ -381,12 +381,12 @@ ast_expression *intrin_debug_typestring(intrin_t *intrin) { } static const intrin_func_t intrinsics[] = { - {&intrin_exp, "__builtin_exp", "exp"}, - {&intrin_mod, "__builtin_mod", "mod"}, - {&intrin_pow, "__builtin_pow", "pow"}, - {&intrin_isnan, "__builtin_isnan", "isnan"}, - {&intrin_fabs, "__builtin_fabs", "fabs"}, - {&intrin_debug_typestring, "__builtin_debug_typestring", ""} + {&intrin_exp, "__builtin_exp", "exp", 1}, + {&intrin_mod, "__builtin_mod", "mod", 2}, + {&intrin_pow, "__builtin_pow", "pow", 2}, + {&intrin_isnan, "__builtin_isnan", "isnan", 1}, + {&intrin_fabs, "__builtin_fabs", "fabs", 1}, + {&intrin_debug_typestring, "__builtin_debug_typestring", "", 0} }; static void intrin_error(intrin_t *intrin, const char *fmt, ...) { @@ -427,7 +427,9 @@ ast_expression *intrin_fold(intrin_t *intrin, ast_value *value, ast_expression * return NULL; for (i = 0; i < vec_size(intrin->intrinsics); i++) if (!strcmp(value->name, intrin->intrinsics[i].name)) - return fold_intrin(intrin->fold, value->name + 10, exprs); + return (vec_size(exprs) != intrin->intrinsics[i].args) + ? NULL + : fold_intrin(intrin->fold, value->name + 10, exprs); return NULL; } diff --git a/parser.c b/parser.c index e523166..c42e62d 100644 --- a/parser.c +++ b/parser.c @@ -1227,7 +1227,7 @@ static bool parser_close_call(parser_t *parser, shunt *sy) * sy->out should I be doing here? */ sy->out[fid] = syexp(foldval->node.context, foldval); - vec_shrinkby(sy->out, 1); + vec_shrinkby(sy->out, paramcount); vec_free(exprs); return true; diff --git a/parser.h b/parser.h index cc2ed88..5c24650 100644 --- a/parser.h +++ b/parser.h @@ -43,6 +43,7 @@ typedef struct { ast_expression *(*intrin)(intrin_t *); const char *name; const char *alias; + size_t args; } intrin_func_t; struct intrin_s {