summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2015-01-10 14:57:16 +1300
committerEric Anholt <eric@anholt.net>2015-01-10 15:24:46 +1300
commitc772c92153fdcd4ba4920b7ef1745ce83b09603b (patch)
treec674f7ce50d3c071c116d38441952e08d8af2bce
parenta58ae83882b3ad3ecb53271f42cf1fd8f9c2907c (diff)
vc4: Split two notions of instructions having side effects.
Some ops can't be DCEd, while some of the ops that are just important due to the args they have can be.
-rw-r--r--src/gallium/drivers/vc4/vc4_opt_cse.c3
-rw-r--r--src/gallium/drivers/vc4/vc4_opt_dead_code.c3
-rw-r--r--src/gallium/drivers/vc4/vc4_opt_vpm_writes.c4
-rw-r--r--src/gallium/drivers/vc4/vc4_qir.c8
-rw-r--r--src/gallium/drivers/vc4/vc4_qir.h1
5 files changed, 15 insertions, 4 deletions
diff --git a/src/gallium/drivers/vc4/vc4_opt_cse.c b/src/gallium/drivers/vc4/vc4_opt_cse.c
index 2ca736fe4d..aff777beb4 100644
--- a/src/gallium/drivers/vc4/vc4_opt_cse.c
+++ b/src/gallium/drivers/vc4/vc4_opt_cse.c
@@ -133,7 +133,8 @@ qir_opt_cse(struct vc4_compile *c)
foreach_s(node, t, &c->instructions) {
struct qinst *inst = (struct qinst *)node;
- if (qir_has_side_effects(c, inst)) {
+ if (qir_has_side_effects(c, inst) ||
+ qir_has_side_effect_reads(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 408bd4302b..f555fcb600 100644
--- a/src/gallium/drivers/vc4/vc4_opt_dead_code.c
+++ b/src/gallium/drivers/vc4/vc4_opt_dead_code.c
@@ -64,7 +64,8 @@ qir_opt_dead_code(struct vc4_compile *c)
if (inst->dst.file == QFILE_TEMP &&
!used[inst->dst.index] &&
(!qir_has_side_effects(c, inst) ||
- inst->op == QOP_TEX_RESULT)) {
+ inst->op == QOP_TEX_RESULT) &&
+ !(qir_has_side_effect_reads(c, inst))) {
if (inst->op == QOP_TEX_RESULT) {
dce_tex = true;
c->num_texture_samples--;
diff --git a/src/gallium/drivers/vc4/vc4_opt_vpm_writes.c b/src/gallium/drivers/vc4/vc4_opt_vpm_writes.c
index 477d32605a..0269e32494 100644
--- a/src/gallium/drivers/vc4/vc4_opt_vpm_writes.c
+++ b/src/gallium/drivers/vc4/vc4_opt_vpm_writes.c
@@ -82,8 +82,10 @@ qir_opt_vpm_writes(struct vc4_compile *c)
if (qir_depends_on_flags(inst))
continue;
- if (qir_has_side_effects(c, inst))
+ if (qir_has_side_effects(c, inst) ||
+ qir_has_side_effect_reads(c, inst)) {
continue;
+ }
/* A QOP_TEX_RESULT destination is r4, so we can't move
* accesses to it past another QOP_TEX_RESULT which would
diff --git a/src/gallium/drivers/vc4/vc4_qir.c b/src/gallium/drivers/vc4/vc4_qir.c
index 4f73932e23..40356c99ff 100644
--- a/src/gallium/drivers/vc4/vc4_qir.c
+++ b/src/gallium/drivers/vc4/vc4_qir.c
@@ -141,6 +141,12 @@ qir_get_op_nsrc(enum qop qop)
bool
qir_has_side_effects(struct vc4_compile *c, struct qinst *inst)
{
+ return qir_op_info[inst->op].has_side_effects;
+}
+
+bool
+qir_has_side_effect_reads(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
@@ -159,7 +165,7 @@ qir_has_side_effects(struct vc4_compile *c, struct qinst *inst)
if (inst->dst.file == QFILE_VPM)
return true;
- return qir_op_info[inst->op].has_side_effects;
+ return false;
}
bool
diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h
index 0c2bca93d8..ebec7ccfbe 100644
--- a/src/gallium/drivers/vc4/vc4_qir.h
+++ b/src/gallium/drivers/vc4/vc4_qir.h
@@ -377,6 +377,7 @@ 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 vc4_compile *c, struct qinst *inst);
+bool qir_has_side_effect_reads(struct vc4_compile *c, struct qinst *inst);
bool qir_is_multi_instruction(struct qinst *inst);
bool qir_depends_on_flags(struct qinst *inst);
bool qir_writes_r4(struct qinst *inst);