Mesa (master): vc4: Turn a SEL_X_Y(x, 0) into SEL_X_0(x).

Eric Anholt anholt at kemper.freedesktop.org
Mon Sep 29 22:02:07 UTC 2014


Module: Mesa
Branch: master
Commit: 3311513041b81fe4e2fcf2c0e8a363a6d292c7b1
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3311513041b81fe4e2fcf2c0e8a363a6d292c7b1

Author: Eric Anholt <eric at anholt.net>
Date:   Wed Sep 24 21:37:12 2014 -0700

vc4: Turn a SEL_X_Y(x, 0) into SEL_X_0(x).

This may reduce register pressure and uniform counts.  Drops a bunch of 0
uniform loads on vs-temp-array-mat4-index-col-row-wr.shader_test, which is
failing to register allocate.

---

 src/gallium/drivers/vc4/vc4_opt_algebraic.c |   75 ++++++++++++++++++++++-----
 1 file changed, 61 insertions(+), 14 deletions(-)

diff --git a/src/gallium/drivers/vc4/vc4_opt_algebraic.c b/src/gallium/drivers/vc4/vc4_opt_algebraic.c
index df57e5d..868677a 100644
--- a/src/gallium/drivers/vc4/vc4_opt_algebraic.c
+++ b/src/gallium/drivers/vc4/vc4_opt_algebraic.c
@@ -34,39 +34,86 @@
 
 #include "vc4_qir.h"
 
+static bool debug;
+
+static void
+dump_from(struct qinst *inst)
+{
+        if (!debug)
+                return;
+
+        fprintf(stderr, "optimizing: ");
+        qir_dump_inst(inst);
+        fprintf(stderr, "\n");
+}
+
+static void
+dump_to(struct qinst *inst)
+{
+        if (!debug)
+                return;
+
+        fprintf(stderr, "to: ");
+        qir_dump_inst(inst);
+        fprintf(stderr, "\n");
+}
+
+static struct qreg
+follow_movs(struct qinst **defs, struct qreg reg)
+{
+        while (reg.file == QFILE_TEMP && defs[reg.index]->op == QOP_MOV)
+                reg = defs[reg.index]->src[0];
+
+        return reg;
+}
+
+static bool
+is_zero(struct vc4_compile *c, struct qinst **defs, struct qreg reg)
+{
+        reg = follow_movs(defs, reg);
+
+        return (reg.file == QFILE_UNIF &&
+                c->uniform_contents[reg.index] == QUNIFORM_CONSTANT &&
+                c->uniform_data[reg.index] == 0);
+}
+
 bool
 qir_opt_algebraic(struct vc4_compile *c)
 {
         bool progress = false;
         struct simple_node *node;
-        bool debug = false;
+        struct qinst *defs[c->num_temps];
 
         foreach(node, &c->instructions) {
                 struct qinst *inst = (struct qinst *)node;
 
+                if (inst->dst.file == QFILE_TEMP)
+                        defs[inst->dst.index] = inst;
+
                 switch (inst->op) {
                 case QOP_SEL_X_Y_ZS:
                 case QOP_SEL_X_Y_ZC:
                 case QOP_SEL_X_Y_NS:
                 case QOP_SEL_X_Y_NC:
-                        /* Turn "dst = (sf == x) ? a : a)" into "dst = a" */
                         if (qir_reg_equals(inst->src[0], inst->src[1])) {
-                                if (debug) {
-                                        fprintf(stderr, "optimizing: ");
-                                        qir_dump_inst(inst);
-                                        fprintf(stderr, "\n");
-                                }
-
+                                /* Turn "dst = (sf == x) ? a : a)" into
+                                 * "dst = a"
+                                 */
+                                dump_from(inst);
                                 inst->op = QOP_MOV;
                                 inst->src[0] = inst->src[1];
                                 inst->src[1] = c->undef;
                                 progress = true;
-
-                                if (debug) {
-                                        fprintf(stderr, "to: ");
-                                        qir_dump_inst(inst);
-                                        fprintf(stderr, "\n");
-                                }
+                                dump_to(inst);
+                        } else if (is_zero(c, defs, inst->src[1])) {
+                                /* Replace references to a 0 uniform value
+                                 * with the SEL_X_0 equivalent.
+                                 */
+                                dump_from(inst);
+                                inst->op -= (QOP_SEL_X_Y_ZS - QOP_SEL_X_0_ZS);
+                                inst->src[1] = c->undef;
+                                progress = true;
+                                dump_to(inst);
                         }
                         break;
 




More information about the mesa-commit mailing list