diff options
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/vc4/Makefile.sources | 1 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_opt_coalesce_ff_writes.c | 105 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_opt_vpm.c | 53 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_qir.c | 1 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_qir.h | 1 |
5 files changed, 110 insertions, 51 deletions
diff --git a/src/gallium/drivers/vc4/Makefile.sources b/src/gallium/drivers/vc4/Makefile.sources index e1496d1012a..f09dac24848 100644 --- a/src/gallium/drivers/vc4/Makefile.sources +++ b/src/gallium/drivers/vc4/Makefile.sources @@ -28,6 +28,7 @@ C_SOURCES := \ vc4_opt_peephole_sf.c \ vc4_opt_small_immediates.c \ vc4_opt_vpm.c \ + vc4_opt_coalesce_ff_writes.c \ vc4_program.c \ vc4_qir.c \ vc4_qir_emit_uniform_stream_resets.c \ diff --git a/src/gallium/drivers/vc4/vc4_opt_coalesce_ff_writes.c b/src/gallium/drivers/vc4/vc4_opt_coalesce_ff_writes.c new file mode 100644 index 00000000000..4e5b1193d3a --- /dev/null +++ b/src/gallium/drivers/vc4/vc4_opt_coalesce_ff_writes.c @@ -0,0 +1,105 @@ +/* + * Copyright © 2014 Broadcom + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** + * @file vc4_opt_coalesce_ff_writes.c + * + * This modifies instructions that generate the value consumed by a VPM write + * to write directly into the VPM. + */ + +#include "vc4_qir.h" + +bool +qir_opt_coalesce_ff_writes(struct vc4_compile *c) +{ + if (c->stage == QSTAGE_FRAG) + return false; + + /* For now, only do this pass when we don't have control flow. */ + struct qblock *block = qir_entry_block(c); + if (block != qir_exit_block(c)) + return false; + + bool progress = false; + struct qinst *vpm_writes[64] = { 0 }; + uint32_t use_count[c->num_temps]; + uint32_t vpm_write_count = 0; + memset(&use_count, 0, sizeof(use_count)); + + qir_for_each_inst_inorder(inst, c) { + switch (inst->dst.file) { + case QFILE_VPM: + vpm_writes[vpm_write_count++] = inst; + break; + default: + break; + } + + for (int i = 0; i < qir_get_nsrc(inst); i++) { + if (inst->src[i].file == QFILE_TEMP) { + uint32_t temp = inst->src[i].index; + use_count[temp]++; + } + } + } + + for (int i = 0; i < vpm_write_count; i++) { + if (!qir_is_raw_mov(vpm_writes[i]) || + vpm_writes[i]->src[0].file != QFILE_TEMP) { + continue; + } + + uint32_t temp = vpm_writes[i]->src[0].index; + if (use_count[temp] != 1) + continue; + + struct qinst *inst = c->defs[temp]; + if (!inst) + continue; + + if (qir_depends_on_flags(inst) || inst->sf) + continue; + + if (qir_has_side_effects(c, inst) || + qir_has_side_effect_reads(c, inst)) { + continue; + } + + /* Move the generating instruction to the end of the program + * to maintain the order of the VPM writes. + */ + assert(!vpm_writes[i]->sf); + list_del(&inst->link); + list_addtail(&inst->link, &vpm_writes[i]->link); + qir_remove_instruction(c, vpm_writes[i]); + + c->defs[inst->dst.index] = NULL; + inst->dst.file = QFILE_VPM; + inst->dst.index = 0; + + progress = true; + } + + return progress; +} diff --git a/src/gallium/drivers/vc4/vc4_opt_vpm.c b/src/gallium/drivers/vc4/vc4_opt_vpm.c index b3bef272254..6f196e7d1b9 100644 --- a/src/gallium/drivers/vc4/vc4_opt_vpm.c +++ b/src/gallium/drivers/vc4/vc4_opt_vpm.c @@ -24,10 +24,8 @@ /** * @file vc4_opt_vpm.c * - * This modifies instructions that: - * 1. exclusively consume a value read from the VPM to directly read the VPM if - * other operands allow it. - * 2. generate the value consumed by a VPM write to write directly into the VPM. + * This modifies instructions that exclusively consume a value read from the + * VPM to directly read the VPM if other operands allow it. */ #include "vc4_qir.h" @@ -44,20 +42,10 @@ qir_opt_vpm(struct vc4_compile *c) return false; bool progress = false; - struct qinst *vpm_writes[64] = { 0 }; uint32_t use_count[c->num_temps]; - uint32_t vpm_write_count = 0; memset(&use_count, 0, sizeof(use_count)); qir_for_each_inst_inorder(inst, c) { - switch (inst->dst.file) { - case QFILE_VPM: - vpm_writes[vpm_write_count++] = inst; - break; - default: - break; - } - for (int i = 0; i < qir_get_nsrc(inst); i++) { if (inst->src[i].file == QFILE_TEMP) { uint32_t temp = inst->src[i].index; @@ -127,42 +115,5 @@ qir_opt_vpm(struct vc4_compile *c) } } - for (int i = 0; i < vpm_write_count; i++) { - if (!qir_is_raw_mov(vpm_writes[i]) || - vpm_writes[i]->src[0].file != QFILE_TEMP) { - continue; - } - - uint32_t temp = vpm_writes[i]->src[0].index; - if (use_count[temp] != 1) - continue; - - struct qinst *inst = c->defs[temp]; - if (!inst) - continue; - - if (qir_depends_on_flags(inst) || inst->sf) - continue; - - if (qir_has_side_effects(c, inst) || - qir_has_side_effect_reads(c, inst)) { - continue; - } - - /* Move the generating instruction to the end of the program - * to maintain the order of the VPM writes. - */ - assert(!vpm_writes[i]->sf); - list_del(&inst->link); - list_addtail(&inst->link, &vpm_writes[i]->link); - qir_remove_instruction(c, vpm_writes[i]); - - c->defs[inst->dst.index] = NULL; - inst->dst.file = QFILE_VPM; - inst->dst.index = 0; - - progress = true; - } - return progress; } diff --git a/src/gallium/drivers/vc4/vc4_qir.c b/src/gallium/drivers/vc4/vc4_qir.c index 7c556a98ea2..a082c41dfe0 100644 --- a/src/gallium/drivers/vc4/vc4_qir.c +++ b/src/gallium/drivers/vc4/vc4_qir.c @@ -784,6 +784,7 @@ qir_optimize(struct vc4_compile *c) OPTPASS(qir_opt_dead_code); OPTPASS(qir_opt_small_immediates); OPTPASS(qir_opt_vpm); + OPTPASS(qir_opt_coalesce_ff_writes); if (!progress) break; diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h index 99cc957853a..a8f90cfe7af 100644 --- a/src/gallium/drivers/vc4/vc4_qir.h +++ b/src/gallium/drivers/vc4/vc4_qir.h @@ -595,6 +595,7 @@ void qir_validate(struct vc4_compile *c); void qir_optimize(struct vc4_compile *c); bool qir_opt_algebraic(struct vc4_compile *c); +bool qir_opt_coalesce_ff_writes(struct vc4_compile *c); bool qir_opt_constant_folding(struct vc4_compile *c); bool qir_opt_copy_propagation(struct vc4_compile *c); bool qir_opt_dead_code(struct vc4_compile *c); |