]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
fold_binary now used instead of ast_binary_new, which calls fold_superfluous
authorWolfgang Bumiller <wry.git@bumiller.com>
Fri, 25 Oct 2013 11:40:31 +0000 (13:40 +0200)
committerWolfgang Bumiller <wry.git@bumiller.com>
Fri, 25 Oct 2013 11:40:31 +0000 (13:40 +0200)
fold.c
parser.c
parser.h

diff --git a/fold.c b/fold.c
index 4664487a3eb776ec6251483fe3180614081337dc..c9f1a0695c07f8fe1b9c35b62f7bbfab4eaaa360 100644 (file)
--- a/fold.c
+++ b/fold.c
@@ -773,18 +773,28 @@ ast_expression *fold_intrin(fold_t *fold, const char *intrin, ast_expression **a
 #define fold_can_1(X)           ((X)->hasvalue && (X)->cvq == CV_CONST)
 /*#define fold_can_2(X,Y)         (fold_can_1(X) && fold_can_1(Y))*/
 
-ast_expression *fold_superfluous(ast_expression *left, ast_expression *right, int op) {
+static ast_expression *fold_superfluous(ast_expression *left, ast_expression *right, int op) {
+    ast_expression *swapped = NULL; /* using this as bool */
     ast_value *load;
 
-    if (!ast_istype(left, ast_value) || !fold_can_1((load = (ast_value*)right)))
+    if (!ast_istype(right, ast_value) || !fold_can_1((load = (ast_value*)right))) {
+        swapped = left;
+        left    = right;
+        right   = swapped;
+    }
+
+    if (!ast_istype(right, ast_value) || !fold_can_1((load = (ast_value*)right)))
         return NULL;
 
     switch (op) {
-        case INSTR_MUL_F:
         case INSTR_DIV_F:
+            if (swapped)
+                return NULL;
+        case INSTR_MUL_F:
             if (fold_immvalue_float(load) == 1.0f) {
                 ++opts_optimizationcount[OPTIM_PEEPHOLE];
-                return (ast_expression*)left;
+                ast_unref(right);
+                return left;
             }
             break;
 
@@ -793,14 +803,16 @@ ast_expression *fold_superfluous(ast_expression *left, ast_expression *right, in
         case INSTR_SUB_F:
             if (fold_immvalue_float(load) == 0.0f) {
                 ++opts_optimizationcount[OPTIM_PEEPHOLE];
-                return (ast_expression*)left;
+                ast_unref(right);
+                return left;
             }
             break;
 
         case INSTR_MUL_V:
             if (vec3_cmp(fold_immvalue_vector(load), vec3_create(1, 1, 1))) {
                 ++opts_optimizationcount[OPTIM_PEEPHOLE];
-                return (ast_expression*)left;
+                ast_unref(right);
+                return left;
             }
             break;
 
@@ -808,7 +820,8 @@ ast_expression *fold_superfluous(ast_expression *left, ast_expression *right, in
         case INSTR_SUB_V:
             if (vec3_cmp(fold_immvalue_vector(load), vec3_create(0, 0, 0))) {
                 ++opts_optimizationcount[OPTIM_PEEPHOLE];
-                return (ast_expression*)left;
+                ast_unref(right);
+                return left;
             }
             break;
     }
@@ -816,6 +829,13 @@ ast_expression *fold_superfluous(ast_expression *left, ast_expression *right, in
     return NULL;
 }
 
+ast_expression *fold_binary(lex_ctx_t ctx, int op, ast_expression *left, ast_expression *right) {
+    ast_expression *ret = fold_superfluous(left, right, op);
+    if (ret)
+        return ret;
+    return (ast_expression*)ast_binary_new(ctx, op, left, right);
+}
+
 static GMQCC_INLINE int fold_cond(ir_value *condval, ast_function *func, ast_ifthen *branch) {
     if (isfloat(condval) && fold_can_1(condval) && OPTS_OPTIMIZATION(OPTIM_CONST_FOLD_DCE)) {
         ast_expression_codegen *cgen;
index b5034350e513e5fe3b4ca751c048a8925f471a12..2dc25508449e2771220d08d5907c3f01799fb183 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -521,10 +521,10 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
             if (!(out = fold_op(parser->fold, op, exprs))) {
                 switch (exprs[0]->vtype) {
                     case TYPE_FLOAT:
-                        out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F, exprs[0], exprs[1]);
+                        out = fold_binary(ctx, INSTR_ADD_F, exprs[0], exprs[1]);
                         break;
                     case TYPE_VECTOR:
-                        out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_V, exprs[0], exprs[1]);
+                        out = fold_binary(ctx, INSTR_ADD_V, exprs[0], exprs[1]);
                         break;
                     default:
                         compile_error(ctx, "invalid types used in expression: cannot add type %s and %s",
@@ -546,10 +546,10 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
             if (!(out = fold_op(parser->fold, op, exprs))) {
                 switch (exprs[0]->vtype) {
                     case TYPE_FLOAT:
-                        out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, exprs[0], exprs[1]);
+                        out = fold_binary(ctx, INSTR_SUB_F, exprs[0], exprs[1]);
                         break;
                     case TYPE_VECTOR:
-                        out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V, exprs[0], exprs[1]);
+                        out = fold_binary(ctx, INSTR_SUB_V, exprs[0], exprs[1]);
                         break;
                     default:
                         compile_error(ctx, "invalid types used in expression: cannot subtract type %s from %s",
@@ -576,15 +576,15 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                 switch (exprs[0]->vtype) {
                     case TYPE_FLOAT:
                         if (exprs[1]->vtype == TYPE_VECTOR)
-                            out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_FV, exprs[0], exprs[1]);
+                            out = fold_binary(ctx, INSTR_MUL_FV, exprs[0], exprs[1]);
                         else
-                            out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, exprs[0], exprs[1]);
+                            out = fold_binary(ctx, INSTR_MUL_F, exprs[0], exprs[1]);
                         break;
                     case TYPE_VECTOR:
                         if (exprs[1]->vtype == TYPE_FLOAT)
-                            out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_VF, exprs[0], exprs[1]);
+                            out = fold_binary(ctx, INSTR_MUL_VF, exprs[0], exprs[1]);
                         else
-                            out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
+                            out = fold_binary(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
                         break;
                     default:
                         compile_error(ctx, "invalid types used in expression: cannot multiply types %s and %s",
@@ -604,7 +604,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
             }
             if (!(out = fold_op(parser->fold, op, exprs))) {
                 if (exprs[0]->vtype == TYPE_FLOAT)
-                    out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F, exprs[0], exprs[1]);
+                    out = fold_binary(ctx, INSTR_DIV_F, exprs[0], exprs[1]);
                 else {
                     ast_type_to_string(exprs[0], ty1, sizeof(ty1));
                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
@@ -657,7 +657,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                  * since scalar ^ vector is not allowed.
                  */
                 if (exprs[0]->vtype == TYPE_FLOAT) {
-                    out = (ast_expression*)ast_binary_new(ctx,
+                    out = fold_binary(ctx,
                         (op->id == opid1('^') ? VINSTR_BITXOR : op->id == opid1('|') ? INSTR_BITOR : INSTR_BITAND),
                         exprs[0], exprs[1]);
                 } else {
@@ -670,11 +670,11 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                          * Bitop all the values of the vector components against the
                          * vectors components in question.
                          */
-                        out = (ast_expression*)ast_binary_new(ctx,
+                        out = fold_binary(ctx,
                             (op->id == opid1('^') ? VINSTR_BITXOR_V : op->id == opid1('|') ? VINSTR_BITOR_V : VINSTR_BITAND_V),
                             exprs[0], exprs[1]);
                     } else {
-                        out = (ast_expression*)ast_binary_new(ctx,
+                        out = fold_binary(ctx,
                             (op->id == opid1('^') ? VINSTR_BITXOR_VF : op->id == opid1('|') ? VINSTR_BITOR_VF : VINSTR_BITAND_VF),
                             exprs[0], exprs[1]);
                     }
@@ -727,7 +727,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                         }
                     }
                 }
-                out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
+                out = fold_binary(ctx, generated_op, exprs[0], exprs[1]);
             }
             break;
 
@@ -774,7 +774,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
             }
 
             if (!(out = fold_op(parser->fold, op, exprs))) {
-                out = (ast_expression*)ast_binary_new(
+                out = fold_binary(
                         parser_ctx(parser),
                         VINSTR_CROSS,
                         exprs[0],
@@ -795,6 +795,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
             }
 
             if (!(out = fold_op(parser->fold, op, exprs))) {
+                /* This whole block is NOT fold_binary safe */
                 ast_binary *eq = ast_binary_new(ctx, INSTR_EQ_F, exprs[0], exprs[1]);
 
                 eq->refs = AST_REF_NONE;
@@ -835,7 +836,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                 return false;
             }
             if (!(out = fold_op(parser->fold, op, exprs)))
-                out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
+                out = fold_binary(ctx, generated_op, exprs[0], exprs[1]);
             break;
         case opid2('!', '='):
             if (exprs[0]->vtype != exprs[1]->vtype) {
@@ -845,7 +846,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                 return false;
             }
             if (!(out = fold_op(parser->fold, op, exprs)))
-                out = (ast_expression*)ast_binary_new(ctx, type_ne_instr[exprs[0]->vtype], exprs[0], exprs[1]);
+                out = fold_binary(ctx, type_ne_instr[exprs[0]->vtype], exprs[0], exprs[1]);
             break;
         case opid2('=', '='):
             if (exprs[0]->vtype != exprs[1]->vtype) {
@@ -855,7 +856,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                 return false;
             }
             if (!(out = fold_op(parser->fold, op, exprs)))
-                out = (ast_expression*)ast_binary_new(ctx, type_eq_instr[exprs[0]->vtype], exprs[0], exprs[1]);
+                out = fold_binary(ctx, type_eq_instr[exprs[0]->vtype], exprs[0], exprs[1]);
             break;
 
         case opid1('='):
@@ -969,9 +970,9 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
             }
             if (!out)
                 return false;
-            out = (ast_expression*)ast_binary_new(ctx, subop,
-                                                  out,
-                                                  (ast_expression*)parser->fold->imm_float[1]);
+            out = fold_binary(ctx, subop,
+                              out,
+                              (ast_expression*)parser->fold->imm_float[1]);
 
             break;
         case opid2('+','='):
@@ -1036,9 +1037,9 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                         out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_MUL_VF,
                                                                 exprs[0], exprs[1]);
                     } else {
-                        out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F,
-                                                                  (ast_expression*)parser->fold->imm_float[1],
-                                                                  exprs[1]);
+                        out = fold_binary(ctx, INSTR_DIV_F,
+                                         (ast_expression*)parser->fold->imm_float[1],
+                                         exprs[1]);
                         if (!out) {
                             compile_error(ctx, "internal error: failed to generate division");
                             return false;
@@ -1095,9 +1096,9 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
             else
                 assignop = type_store_instr[exprs[0]->vtype];
             if (exprs[0]->vtype == TYPE_FLOAT)
-                out = (ast_expression*)ast_binary_new(ctx, INSTR_BITAND, exprs[0], exprs[1]);
+                out = fold_binary(ctx, INSTR_BITAND, exprs[0], exprs[1]);
             else
-                out = (ast_expression*)ast_binary_new(ctx, VINSTR_BITAND_V, exprs[0], exprs[1]);
+                out = fold_binary(ctx, VINSTR_BITAND_V, exprs[0], exprs[1]);
             if (!out)
                 return false;
             (void)check_write_to(ctx, exprs[0]);
@@ -1117,9 +1118,9 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
             }
             if (!(out = fold_op(parser->fold, op, exprs))) {
                 if (exprs[0]->vtype == TYPE_FLOAT) {
-                    out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, (ast_expression*)parser->fold->imm_float[2], exprs[0]);
+                    out = fold_binary(ctx, INSTR_SUB_F, (ast_expression*)parser->fold->imm_float[2], exprs[0]);
                 } else {
-                    out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V, (ast_expression*)parser->fold->imm_vector[1], exprs[0]);
+                    out = fold_binary(ctx, INSTR_SUB_V, (ast_expression*)parser->fold->imm_vector[1], exprs[0]);
                 }
             }
             break;
index 5c24650738ee23b6e6cba7df48b72e2650a6eddb..0396a7e17b3af01ac8e1fdf1f1004a18c8bbed57 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -134,7 +134,7 @@ bool            fold_generate       (fold_t *, ir_builder *);
 ast_expression *fold_op             (fold_t *, const oper_info *, ast_expression **);
 ast_expression *fold_intrin         (fold_t *, const char      *, ast_expression **);
 
-ast_expression *fold_superfluous    (ast_expression *, ast_expression *, int);
+ast_expression *fold_binary         (lex_ctx_t ctx, int, ast_expression *, ast_expression *);
 int             fold_cond_ifthen    (ir_value *, ast_function *, ast_ifthen  *);
 int             fold_cond_ternary   (ir_value *, ast_function *, ast_ternary *);