Fix handling on intrinsic folding, this closes #118.
authorDale Weiler <killfieldengine@gmail.com>
Thu, 17 Oct 2013 04:14:42 +0000 (00:14 -0400)
committerDale Weiler <killfieldengine@gmail.com>
Thu, 17 Oct 2013 04:14:42 +0000 (00:14 -0400)
fold.c
intrin.c
parser.c
parser.h

diff --git a/fold.c b/fold.c
index 99ab737..4664487 100644 (file)
--- 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;
 }
 
 /*
index 92ae4b8..20d82c6 100644 (file)
--- 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;
 }
 
index e523166..c42e62d 100644 (file)
--- 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;
index cc2ed88..5c24650 100644 (file)
--- 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 {