diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2015-11-22 02:46:45 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2015-11-22 02:46:45 +0000 |
commit | 3e40341f9dcd7c1bbc9afb8ddb812304820396cf (patch) | |
tree | 274b3f522afe1da16ab2b5347758c908bc23fac4 /lib/mesa/src/gallium/drivers/vc4/vc4_opt_dead_code.c | |
parent | 7b644ad52b574bec410d557155d666ac17fdf51a (diff) |
import Mesa 11.0.6
Diffstat (limited to 'lib/mesa/src/gallium/drivers/vc4/vc4_opt_dead_code.c')
-rw-r--r-- | lib/mesa/src/gallium/drivers/vc4/vc4_opt_dead_code.c | 112 |
1 files changed, 60 insertions, 52 deletions
diff --git a/lib/mesa/src/gallium/drivers/vc4/vc4_opt_dead_code.c b/lib/mesa/src/gallium/drivers/vc4/vc4_opt_dead_code.c index f04d0ff97..ffd42422d 100644 --- a/lib/mesa/src/gallium/drivers/vc4/vc4_opt_dead_code.c +++ b/lib/mesa/src/gallium/drivers/vc4/vc4_opt_dead_code.c @@ -24,15 +24,11 @@ /** * @file vc4_opt_dead_code.c * - * This is a simple dead code eliminator for SSA values in QIR. + * This is a simmple dead code eliminator for QIR with no control flow. * - * It walks all the instructions finding what temps are used, then walks again - * to remove instructions writing unused temps. - * - * This is an inefficient implementation if you have long chains of - * instructions where the entire chain is dead, but we expect those to have - * been eliminated at the NIR level, and here we're just cleaning up small - * problems produced by NIR->QIR. + * It walks from the bottom of the instruction list, removing instructions + * with a destination that is never used, and marking the sources of non-dead + * instructions as used. */ #include "vc4_qir.h" @@ -54,7 +50,7 @@ dce(struct vc4_compile *c, struct qinst *inst) static bool has_nonremovable_reads(struct vc4_compile *c, struct qinst *inst) { - for (int i = 0; i < qir_get_nsrc(inst); i++) { + for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) { if (inst->src[i].file == QFILE_VPM) { uint32_t attr = inst->src[i].index / 4; uint32_t offset = (inst->src[i].index % 4) * 4; @@ -73,7 +69,7 @@ has_nonremovable_reads(struct vc4_compile *c, struct qinst *inst) } if (inst->src[i].file == QFILE_VARY && - c->input_slots[inst->src[i].index].slot == 0xff) { + c->input_semantics[inst->src[i].index].semantic == 0xff) { return true; } } @@ -86,50 +82,28 @@ qir_opt_dead_code(struct vc4_compile *c) { bool progress = false; bool *used = calloc(c->num_temps, sizeof(bool)); - - qir_for_each_inst_inorder(inst, c) { - for (int i = 0; i < qir_get_nsrc(inst); i++) { - if (inst->src[i].file == QFILE_TEMP) - used[inst->src[i].index] = true; - } - } - - qir_for_each_block(block, c) { - qir_for_each_inst_safe(inst, block) { - if (inst->dst.file != QFILE_NULL && - !(inst->dst.file == QFILE_TEMP && - !used[inst->dst.index])) { - continue; + bool sf_used = false; + /* Whether we're eliminating texture setup currently. */ + bool dce_tex = false; + + struct list_head *node, *t; + for (node = c->instructions.prev, t = node->prev; + &c->instructions != node; + node = t, t = t->prev) { + struct qinst *inst = (struct qinst *)node; + + if (inst->dst.file == QFILE_TEMP && + !used[inst->dst.index] && + !inst->sf && + (!qir_has_side_effects(c, inst) || + inst->op == QOP_TEX_RESULT) && + !has_nonremovable_reads(c, inst)) { + if (inst->op == QOP_TEX_RESULT) { + dce_tex = true; + c->num_texture_samples--; } - if (qir_has_side_effects(c, inst)) - continue; - - if (inst->sf || - has_nonremovable_reads(c, inst)) { - /* If we can't remove the instruction, but we - * don't need its destination value, just - * remove the destination. The register - * allocator would trivially color it and it - * wouldn't cause any register pressure, but - * it's nicer to read the QIR code without - * unused destination regs. - */ - if (inst->dst.file == QFILE_TEMP) { - if (debug) { - fprintf(stderr, - "Removing dst from: "); - qir_dump_inst(c, inst); - fprintf(stderr, "\n"); - } - c->defs[inst->dst.index] = NULL; - inst->dst.file = QFILE_NULL; - progress = true; - } - continue; - } - - for (int i = 0; i < qir_get_nsrc(inst); i++) { + for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) { if (inst->src[i].file != QFILE_VPM) continue; uint32_t attr = inst->src[i].index / 4; @@ -145,6 +119,40 @@ qir_opt_dead_code(struct vc4_compile *c) progress = true; continue; } + + if (qir_depends_on_flags(inst)) + sf_used = true; + if (inst->sf) { + if (!sf_used) { + if (debug) { + fprintf(stderr, "Removing SF on: "); + qir_dump_inst(c, inst); + fprintf(stderr, "\n"); + } + + inst->sf = false; + progress = true; + } + sf_used = false; + } + + if (inst->op == QOP_TEX_RESULT) + dce_tex = false; + + if (dce_tex && (inst->op == QOP_TEX_S || + inst->op == QOP_TEX_T || + inst->op == QOP_TEX_R || + inst->op == QOP_TEX_B || + inst->op == QOP_TEX_DIRECT)) { + dce(c, inst); + progress = true; + continue; + } + + for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) { + if (inst->src[i].file == QFILE_TEMP) + used[inst->src[i].index] = true; + } } free(used); |