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