-Ovector-components
authorWolfgang Bumiller <blub@speed.at>
Sat, 29 Dec 2012 14:05:04 +0000 (15:05 +0100)
committerWolfgang Bumiller <blub@speed.at>
Sat, 29 Dec 2012 14:05:04 +0000 (15:05 +0100)
ast.c
ir.c
opts.def
parser.c

diff --git a/ast.c b/ast.c
index 89d738cd5d40cc060e9236f41f168275b7ae167a..ff105cc0dac2bd25700765f0aea427e67a031292 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -2089,7 +2089,7 @@ bool ast_member_codegen(ast_member *self, ast_function *func, bool lvalue, ir_va
     }
 
     cgen = self->owner->expression.codegen;
-    if (!(*cgen)((ast_expression*)(self->owner), func, true, &vec))
+    if (!(*cgen)((ast_expression*)(self->owner), func, false, &vec))
         return false;
 
     if (vec->vtype != TYPE_VECTOR &&
diff --git a/ir.c b/ir.c
index 87ad615a4b77ba8d4238706a26a42b27aba79743..4482d1d40b7e3371c994dc9c424755437d280980 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -2310,6 +2310,9 @@ bool ir_function_allocate_locals(ir_function *self)
             if (vec_size(v->writes) == 1 && v->writes[0]->opcode == INSTR_CALL0)
             {
                 v->store = store_return;
+                if (v->members[0]) v->members[0]->store = store_return;
+                if (v->members[1]) v->members[1]->store = store_return;
+                if (v->members[2]) v->members[2]->store = store_return;
                 ++opts_optimizationcount[OPTIM_CALL_STORES];
                 continue;
             }
@@ -3779,7 +3782,7 @@ void ir_function_dump(ir_function *f, char *ind,
             attr = "unique ";
         else if (v->locked)
             attr = "locked ";
-        oprintf("%s\t%s: %s@%i ", ind, v->name, attr, (int)v->code.local);
+        oprintf("%s\t%s: %s %s@%i ", ind, v->name, type_name[v->vtype], attr, (int)v->code.local);
         for (l = 0; l < vec_size(v->life); ++l) {
             oprintf("[%i,%i] ", v->life[l].start, v->life[l].end);
         }
@@ -3802,13 +3805,36 @@ void ir_function_dump(ir_function *f, char *ind,
         }
     }
     for (i = 0; i < vec_size(f->values); ++i) {
-        size_t l;
+        const char *attr = "";
+        size_t l, m;
         ir_value *v = f->values[i];
-        oprintf("%s\t%s: @%i ", ind, v->name, (int)v->code.local);
+        if (v->unique_life && v->locked)
+            attr = "unique,locked ";
+        else if (v->unique_life)
+            attr = "unique ";
+        else if (v->locked)
+            attr = "locked ";
+        oprintf("%s\t%s: %s %s@%i ", ind, v->name, type_name[v->vtype], attr, (int)v->code.local);
         for (l = 0; l < vec_size(v->life); ++l) {
             oprintf("[%i,%i] ", v->life[l].start, v->life[l].end);
         }
         oprintf("\n");
+        for (m = 0; m < 3; ++m) {
+            ir_value *vm = v->members[m];
+            if (!vm)
+                continue;
+            if (vm->unique_life && vm->locked)
+                attr = "unique,locked ";
+            else if (vm->unique_life)
+                attr = "unique ";
+            else if (vm->locked)
+                attr = "locked ";
+            oprintf("%s\t%s: %s@%i ", ind, vm->name, attr, (int)vm->code.local);
+            for (l = 0; l < vec_size(vm->life); ++l) {
+                oprintf("[%i,%i] ", vm->life[l].start, vm->life[l].end);
+            }
+            oprintf("\n");
+        }
     }
     if (vec_size(f->blocks))
     {
index 3c60deb7307f9759ebbdb080a0da3f6e5f86a7f9..b31339135b23ee1b9a7c88720d9d9bdd97e56c0b 100644 (file)
--- a/opts.def
+++ b/opts.def
@@ -95,6 +95,7 @@
     GMQCC_DEFINE_FLAG(OVERLAP_STRINGS,      2)
     GMQCC_DEFINE_FLAG(CALL_STORES,          1)
     GMQCC_DEFINE_FLAG(VOID_RETURN,          1)
+    GMQCC_DEFINE_FLAG(VECTOR_COMPONENTS,    1)
 #endif
 
 /* some cleanup so we don't have to */
index 757178c9946e8c8bdaf59b89bf04fbf036a0ecf5..c780dc26e1de0e09879c897fe0e60db2c37f2fba 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -800,6 +800,58 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                     {
                         if (CanConstFold(exprs[0], exprs[1]))
                             out = (ast_expression*)parser_const_float(parser, vec3_mulvv(ConstV(0), ConstV(1)));
+                        else if (OPTS_OPTIMIZATION(OPTIM_VECTOR_COMPONENTS) && CanConstFold1(exprs[0])) {
+                            vector vec = ConstV(0);
+                            if (!vec.y && !vec.z) { /* 'n 0 0' * v */
+                                ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
+                                out = (ast_expression*)ast_member_new(ctx, exprs[1], 0, NULL);
+                                out->expression.node.keep = false;
+                                if (vec.x != 1)
+                                    out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.x), out);
+                            }
+                            else if (!vec.x && !vec.z) { /* '0 n 0' * v */
+                                ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
+                                out = (ast_expression*)ast_member_new(ctx, exprs[1], 1, NULL);
+                                out->expression.node.keep = false;
+                                if (vec.y != 1)
+                                    out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.y), out);
+                            }
+                            else if (!vec.x && !vec.y) { /* '0 n 0' * v */
+                                ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
+                                out = (ast_expression*)ast_member_new(ctx, exprs[1], 2, NULL);
+                                out->expression.node.keep = false;
+                                if (vec.z != 1)
+                                    out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.z), out);
+                            }
+                            else
+                                out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
+                        }
+                        else if (OPTS_OPTIMIZATION(OPTIM_VECTOR_COMPONENTS) && CanConstFold1(exprs[1])) {
+                            vector vec = ConstV(1);
+                            if (!vec.y && !vec.z) { /* v * 'n 0 0' */
+                                ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
+                                out = (ast_expression*)ast_member_new(ctx, exprs[0], 0, NULL);
+                                out->expression.node.keep = false;
+                                if (vec.x != 1)
+                                    out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.x));
+                            }
+                            else if (!vec.x && !vec.z) { /* v * '0 n 0' */
+                                ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
+                                out = (ast_expression*)ast_member_new(ctx, exprs[0], 1, NULL);
+                                out->expression.node.keep = false;
+                                if (vec.y != 1)
+                                    out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.y));
+                            }
+                            else if (!vec.x && !vec.y) { /* v * '0 n 0' */
+                                ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
+                                out = (ast_expression*)ast_member_new(ctx, exprs[0], 2, NULL);
+                                out->expression.node.keep = false;
+                                if (vec.z != 1)
+                                    out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.z));
+                            }
+                            else
+                                out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
+                        }
                         else
                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
                     }