summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <[email protected]>2019-04-25 03:48:08 +0000
committerAlyssa Rosenzweig <[email protected]>2019-04-25 20:37:45 +0000
commit4d821a11012d9a18e7364f4281d94dbe8ee12013 (patch)
tree0f0f4461794f559ab2337e383e6ad611aaf5305a
parentb53b4573c3f0571253672e44ce7d6310d9f987bf (diff)
panfrost/midgard: Optimize csel involving 0
Signed-off-by: Alyssa Rosenzweig <[email protected]>
-rw-r--r--src/gallium/drivers/panfrost/midgard/helpers.h2
-rw-r--r--src/gallium/drivers/panfrost/midgard/midgard_compile.c43
2 files changed, 30 insertions, 15 deletions
diff --git a/src/gallium/drivers/panfrost/midgard/helpers.h b/src/gallium/drivers/panfrost/midgard/helpers.h
index 5912963ccdd..116c69b2c14 100644
--- a/src/gallium/drivers/panfrost/midgard/helpers.h
+++ b/src/gallium/drivers/panfrost/midgard/helpers.h
@@ -217,6 +217,7 @@ static struct {
/* XXX: Test case where it's right on smul but not sadd */
[midgard_alu_op_iand] = {"iand", UNITS_ADD | OP_COMMUTES},
+ [midgard_alu_op_iandnot] = {"iandnot", UNITS_ADD},
[midgard_alu_op_ior] = {"ior", UNITS_ADD | OP_COMMUTES},
[midgard_alu_op_ixor] = {"ixor", UNITS_ADD | OP_COMMUTES},
@@ -237,7 +238,6 @@ static struct {
/* These instructions are not yet emitted by the compiler, so
* don't speculate about units yet */
[midgard_alu_op_ishladd] = {"ishladd", 0},
- [midgard_alu_op_iandnot] = {"iandnot", 0},
[midgard_alu_op_uball_lt] = {"uball_lt", 0},
[midgard_alu_op_uball_lte] = {"uball_lte", 0},
diff --git a/src/gallium/drivers/panfrost/midgard/midgard_compile.c b/src/gallium/drivers/panfrost/midgard/midgard_compile.c
index 5b5a44013a2..b5ab103298e 100644
--- a/src/gallium/drivers/panfrost/midgard/midgard_compile.c
+++ b/src/gallium/drivers/panfrost/midgard/midgard_compile.c
@@ -1227,29 +1227,44 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr)
break;
}
+ /* For a few special csel cases not handled by NIR, we can opt to
+ * bitwise. Otherwise, we emit the condition and do a real csel */
+
case nir_op_b32csel: {
- op = midgard_alu_op_fcsel;
+ if (nir_is_fzero_constant(instr->src[2].src)) {
+ /* (b ? v : 0) = (b & v) */
+ op = midgard_alu_op_iand;
+ nr_inputs = 2;
+ } else if (nir_is_fzero_constant(instr->src[1].src)) {
+ /* (b ? 0 : v) = (!b ? v : 0) = (~b & v) = (v & ~b) */
+ op = midgard_alu_op_iandnot;
+ nr_inputs = 2;
+ instr->src[1] = instr->src[0];
+ instr->src[0] = instr->src[2];
+ } else {
+ op = midgard_alu_op_fcsel;
- /* csel works as a two-arg in Midgard, since the condition is hardcoded in r31.w */
- nr_inputs = 2;
+ /* csel works as a two-arg in Midgard, since the condition is hardcoded in r31.w */
+ nr_inputs = 2;
- /* Figure out which component the condition is in */
+ /* Figure out which component the condition is in */
- unsigned comp = instr->src[0].swizzle[0];
+ unsigned comp = instr->src[0].swizzle[0];
- /* Make sure NIR isn't throwing a mixed condition at us */
+ /* Make sure NIR isn't throwing a mixed condition at us */
- for (unsigned c = 1; c < nr_components; ++c)
- assert(instr->src[0].swizzle[c] == comp);
+ for (unsigned c = 1; c < nr_components; ++c)
+ assert(instr->src[0].swizzle[c] == comp);
- /* Emit the condition into r31.w */
- emit_condition(ctx, &instr->src[0].src, false, comp);
+ /* Emit the condition into r31.w */
+ emit_condition(ctx, &instr->src[0].src, false, comp);
- /* The condition is the first argument; move the other
- * arguments up one to be a binary instruction for
- * Midgard */
+ /* The condition is the first argument; move the other
+ * arguments up one to be a binary instruction for
+ * Midgard */
- memmove(instr->src, instr->src + 1, 2 * sizeof(nir_alu_src));
+ memmove(instr->src, instr->src + 1, 2 * sizeof(nir_alu_src));
+ }
break;
}