Mesa (master): vc4: Allow dead code elimination of unused varyings.

Eric Anholt anholt at kemper.freedesktop.org
Fri Oct 24 17:08:59 UTC 2014


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

Author: Eric Anholt <eric at anholt.net>
Date:   Fri Oct 24 15:03:04 2014 +0100

vc4: Allow dead code elimination of unused varyings.

total instructions in shared programs: 39022 -> 37341 (-4.31%)
instructions in affected programs:     26979 -> 25298 (-6.23%)
total uniforms in shared programs: 11242 -> 10523 (-6.40%)
uniforms in affected programs:     5836 -> 5117 (-12.32%)

---

 src/gallium/drivers/vc4/vc4_opt_cse.c       |    2 +-
 src/gallium/drivers/vc4/vc4_opt_dead_code.c |    2 +-
 src/gallium/drivers/vc4/vc4_program.c       |   15 +++++++++++++++
 src/gallium/drivers/vc4/vc4_qir.c           |   15 +++++++++++++--
 src/gallium/drivers/vc4/vc4_qir.h           |    2 +-
 5 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/src/gallium/drivers/vc4/vc4_opt_cse.c b/src/gallium/drivers/vc4/vc4_opt_cse.c
index d3ef910..bebfb652 100644
--- a/src/gallium/drivers/vc4/vc4_opt_cse.c
+++ b/src/gallium/drivers/vc4/vc4_opt_cse.c
@@ -132,7 +132,7 @@ qir_opt_cse(struct vc4_compile *c)
         foreach_s(node, t, &c->instructions) {
                 struct qinst *inst = (struct qinst *)node;
 
-                if (qir_has_side_effects(inst)) {
+                if (qir_has_side_effects(c, inst)) {
                         if (inst->op == QOP_TLB_DISCARD_SETUP)
                                 last_sf = NULL;
                         continue;
diff --git a/src/gallium/drivers/vc4/vc4_opt_dead_code.c b/src/gallium/drivers/vc4/vc4_opt_dead_code.c
index f08818a..d958dcb 100644
--- a/src/gallium/drivers/vc4/vc4_opt_dead_code.c
+++ b/src/gallium/drivers/vc4/vc4_opt_dead_code.c
@@ -63,7 +63,7 @@ qir_opt_dead_code(struct vc4_compile *c)
 
                 if (inst->dst.file == QFILE_TEMP &&
                     !used[inst->dst.index] &&
-                    (!qir_has_side_effects(inst) ||
+                    (!qir_has_side_effects(c, inst) ||
                      inst->op == QOP_TEX_RESULT)) {
                         if (inst->op == QOP_TEX_RESULT) {
                                 dce_tex = true;
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index 01941f8..0674e4f 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -2018,6 +2018,18 @@ vc4_get_compiled_shader(struct vc4_context *vc4, enum qstage stage,
 
         shader->program_id = vc4->next_compiled_program_id++;
         if (stage == QSTAGE_FRAG) {
+                bool input_live[c->num_input_semantics];
+                struct simple_node *node;
+
+                memset(input_live, 0, sizeof(input_live));
+                foreach(node, &c->instructions) {
+                        struct qinst *inst = (struct qinst *)node;
+                        for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) {
+                                if (inst->src[i].file == QFILE_VARY)
+                                        input_live[inst->src[i].index] = true;
+                        }
+                }
+
                 shader->input_semantics = ralloc_array(shader,
                                                        struct vc4_varying_semantic,
                                                        c->num_input_semantics);
@@ -2025,6 +2037,9 @@ vc4_get_compiled_shader(struct vc4_context *vc4, enum qstage stage,
                 for (int i = 0; i < c->num_input_semantics; i++) {
                         struct vc4_varying_semantic *sem = &c->input_semantics[i];
 
+                        if (!input_live[i])
+                                continue;
+
                         /* Skip non-VS-output inputs. */
                         if (sem->semantic == (uint8_t)~0)
                                 continue;
diff --git a/src/gallium/drivers/vc4/vc4_qir.c b/src/gallium/drivers/vc4/vc4_qir.c
index 9c7c15e..a7a4d96 100644
--- a/src/gallium/drivers/vc4/vc4_qir.c
+++ b/src/gallium/drivers/vc4/vc4_qir.c
@@ -122,12 +122,23 @@ qir_get_op_nsrc(enum qop qop)
                 abort();
 }
 
+/**
+ * Returns whether the instruction has any side effects that must be
+ * preserved.
+ */
 bool
-qir_has_side_effects(struct qinst *inst)
+qir_has_side_effects(struct vc4_compile *c, struct qinst *inst)
 {
+        /* We can dead-code eliminate varyings, because we only tell the VS
+         * about the live ones at the end.  But we have to preserve the
+         * point/line coordinates reads, because they're generated by
+         * fixed-function hardware.
+         */
         for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) {
-                if (inst->src[i].file == QFILE_VARY)
+                if (inst->src[i].file == QFILE_VARY &&
+                    c->input_semantics[inst->src[i].index].semantic == 0xff) {
                         return true;
+                }
         }
 
         return qir_op_info[inst->op].has_side_effects;
diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h
index c2f83a7..077a55a 100644
--- a/src/gallium/drivers/vc4/vc4_qir.h
+++ b/src/gallium/drivers/vc4/vc4_qir.h
@@ -309,7 +309,7 @@ void qir_emit(struct vc4_compile *c, struct qinst *inst);
 struct qreg qir_get_temp(struct vc4_compile *c);
 int qir_get_op_nsrc(enum qop qop);
 bool qir_reg_equals(struct qreg a, struct qreg b);
-bool qir_has_side_effects(struct qinst *inst);
+bool qir_has_side_effects(struct vc4_compile *c, struct qinst *inst);
 bool qir_depends_on_flags(struct qinst *inst);
 bool qir_writes_r4(struct qinst *inst);
 bool qir_reads_r4(struct qinst *inst);




More information about the mesa-commit mailing list