X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fvc4%2Fvc4_opt_copy_propagation.c;h=0eee5c34e1ddb455bf488e13f7f9d083513dd011;hb=fad158a0e01f4c28851477e6d1eb5c8fd67e226b;hp=dc4b5bc3c38ecc82f3e0ade6caeacf9ce18b64cd;hpb=ec9da314baf11bea57f315346091ae941ac4f662;p=mesa.git diff --git a/src/gallium/drivers/vc4/vc4_opt_copy_propagation.c b/src/gallium/drivers/vc4/vc4_opt_copy_propagation.c index dc4b5bc3c38..0eee5c34e1d 100644 --- a/src/gallium/drivers/vc4/vc4_opt_copy_propagation.c +++ b/src/gallium/drivers/vc4/vc4_opt_copy_propagation.c @@ -32,47 +32,87 @@ * there's no killing to worry about. */ -#include -#include #include "vc4_qir.h" bool -qir_opt_copy_propagation(struct qcompile *c) +qir_opt_copy_propagation(struct vc4_compile *c) { bool progress = false; - struct simple_node *node; bool debug = false; - struct qreg *movs = calloc(c->num_temps, sizeof(struct qreg)); - foreach(node, &c->instructions) { - struct qinst *inst = (struct qinst *)node; + list_for_each_entry(struct qinst, inst, &c->instructions, link) { + int nsrc = qir_get_op_nsrc(inst->op); + for (int i = 0; i < nsrc; i++) { + if (inst->src[i].file != QFILE_TEMP) + continue; - for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) { - int index = inst->src[i].index; - if (inst->src[i].file == QFILE_TEMP && - movs[index].file == QFILE_TEMP) { - if (debug) { - fprintf(stderr, "Copy propagate: "); - qir_dump_inst(inst); - fprintf(stderr, "\n"); - } + struct qinst *mov = c->defs[inst->src[i].index]; + if (!mov || + (mov->op != QOP_MOV && + mov->op != QOP_FMOV && + mov->op != QOP_MMOV)) { + continue; + } + + if (mov->src[0].file != QFILE_TEMP && + mov->src[0].file != QFILE_UNIF) { + continue; + } - inst->src[i] = movs[index]; + if (mov->dst.pack) + continue; - if (debug) { - fprintf(stderr, "to: "); - qir_dump_inst(inst); - fprintf(stderr, "\n"); + uint8_t unpack; + if (mov->src[0].pack) { + /* Make sure that the meaning of the unpack + * would be the same between the two + * instructions. + */ + if (qir_is_float_input(inst) != + qir_is_float_input(mov)) { + continue; } - progress = true; + /* There's only one unpack field, so make sure + * this instruction doesn't already use it. + */ + bool already_has_unpack = false; + for (int j = 0; j < nsrc; j++) { + if (inst->src[j].pack) + already_has_unpack = true; + } + if (already_has_unpack) + continue; + + /* A destination pack requires the PM bit to + * be set to a specific value already, which + * may be different from ours. + */ + if (inst->dst.pack) + continue; + + unpack = mov->src[0].pack; + } else { + unpack = inst->src[i].pack; } - } - if (inst->op == QOP_MOV && inst->dst.file == QFILE_TEMP) - movs[inst->dst.index] = inst->src[0]; - } + if (debug) { + fprintf(stderr, "Copy propagate: "); + qir_dump_inst(c, inst); + fprintf(stderr, "\n"); + } - free(movs); + inst->src[i] = mov->src[0]; + inst->src[i].pack = unpack; + + if (debug) { + fprintf(stderr, "to: "); + qir_dump_inst(c, inst); + fprintf(stderr, "\n"); + } + + progress = true; + } + } return progress; }