summaryrefslogtreecommitdiffstats
path: root/src/broadcom
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2018-12-29 12:44:22 -0800
committerEric Anholt <[email protected]>2018-12-30 08:05:11 -0800
commitb36757448dd79a062347c377d4f65b94bfcfaad3 (patch)
treef19fd0cbec3541ba87ba2bf6aa94e47bc760ab36 /src/broadcom
parent20e3526298de92ab2686e0d99c396d4fc8499793 (diff)
v3d: Dead-code eliminate unused flags updates.
The greedy comparison folding in bcsel means that we may have left the original bool-generating NIR ALU instruction dead, but DCE wasn't eliminating the VIR code for it because of the flags updates. total instructions in shared programs: 5186024 -> 5100894 (-1.64%) instructions in affected programs: 1448695 -> 1363565 (-5.88%)
Diffstat (limited to 'src/broadcom')
-rw-r--r--src/broadcom/compiler/vir_opt_dead_code.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/src/broadcom/compiler/vir_opt_dead_code.c b/src/broadcom/compiler/vir_opt_dead_code.c
index 9c93846e9b8..a486708bfa5 100644
--- a/src/broadcom/compiler/vir_opt_dead_code.c
+++ b/src/broadcom/compiler/vir_opt_dead_code.c
@@ -92,6 +92,24 @@ can_write_to_null(struct v3d_compile *c, struct qinst *inst)
return true;
}
+static void
+vir_dce_flags(struct v3d_compile *c, struct qinst *inst)
+{
+ if (debug) {
+ fprintf(stderr,
+ "Removing flags write from: ");
+ vir_dump_inst(c, inst);
+ fprintf(stderr, "\n");
+ }
+
+ assert(inst->qpu.type == V3D_QPU_INSTR_TYPE_ALU);
+
+ inst->qpu.flags.apf = V3D_QPU_PF_NONE;
+ inst->qpu.flags.mpf = V3D_QPU_PF_NONE;
+ inst->qpu.flags.auf = V3D_QPU_UF_NONE;
+ inst->qpu.flags.muf = V3D_QPU_UF_NONE;
+}
+
bool
vir_opt_dead_code(struct v3d_compile *c)
{
@@ -112,7 +130,15 @@ vir_opt_dead_code(struct v3d_compile *c)
}
vir_for_each_block(block, c) {
+ struct qinst *last_flags_write = NULL;
+
vir_for_each_inst_safe(inst, block) {
+ /* If this instruction reads the flags, we can't
+ * remove the flags generation for it.
+ */
+ if (v3d_qpu_reads_flags(&inst->qpu))
+ last_flags_write = NULL;
+
if (inst->dst.file != QFILE_NULL &&
!(inst->dst.file == QFILE_TEMP &&
!used[inst->dst.index])) {
@@ -122,10 +148,21 @@ vir_opt_dead_code(struct v3d_compile *c)
if (vir_has_side_effects(c, inst))
continue;
- if (inst->qpu.flags.apf != V3D_QPU_PF_NONE ||
- inst->qpu.flags.mpf != V3D_QPU_PF_NONE ||
- inst->qpu.flags.auf != V3D_QPU_UF_NONE ||
- inst->qpu.flags.muf != V3D_QPU_UF_NONE ||
+ if (v3d_qpu_writes_flags(&inst->qpu)) {
+ /* If we obscure a previous flags write,
+ * drop it.
+ */
+ if (last_flags_write &&
+ (inst->qpu.flags.apf != V3D_QPU_PF_NONE ||
+ inst->qpu.flags.mpf != V3D_QPU_PF_NONE)) {
+ vir_dce_flags(c, last_flags_write);
+ progress = true;
+ }
+
+ last_flags_write = inst;
+ }
+
+ if (v3d_qpu_writes_flags(&inst->qpu) ||
has_nonremovable_reads(c, inst)) {
/* If we can't remove the instruction, but we
* don't need its destination value, just
@@ -162,6 +199,7 @@ vir_opt_dead_code(struct v3d_compile *c)
}
}
+ assert(inst != last_flags_write);
dce(c, inst);
progress = true;
continue;