Beispiel #1
0
static bool
qir_opt_peephole_sf_block(struct vc4_compile *c, struct qblock *block)
{
        bool progress = false;
        /* We don't have liveness dataflow analysis for flags, but we also
         * never generate a use of flags across control flow, so just treat
         * them as unused at block exit.
         */
        bool sf_live = false;
        struct qinst *last_sf = NULL;

        /* Walk the block from bottom to top, tracking if the SF is used, and
         * removing unused or repeated ones.
         */
        qir_for_each_inst_rev(inst, block) {
                if (inst->sf) {
                        if (!sf_live) {
                                /* Our instruction's SF isn't read, so drop it.
                                 */
                                dump_from(c, inst, "dead SF");
                                inst->sf = false;
                                dump_to(c, inst);
                                progress = true;
                        } else if (last_sf &&
                                   inst_result_equals(last_sf, inst)) {
                                /* The last_sf sets up same value as inst, so
                                 * just drop the later one.
                                 */
                                dump_from(c, last_sf, "repeated SF");
                                last_sf->sf = false;
                                dump_to(c, last_sf);
                                progress = true;
                                last_sf = inst;
                        } else {
                                last_sf = inst;
                        }
                        sf_live = false;
                }

                if (last_sf) {
                        if (inst_srcs_updated(last_sf, inst))
                                last_sf = NULL;
                }

                if (qir_depends_on_flags(inst))
                        sf_live = true;
        }

        return progress;
}
Beispiel #2
0
bool
qir_opt_peephole_sf(struct vc4_compile *c)
{
        bool progress = false;
        bool sf_live = false;
        struct qinst *last_sf = NULL;

        /* Walk the block from bottom to top, tracking if the SF is used, and
         * removing unused or repeated ones.
         */
        list_for_each_entry_rev(struct qinst, inst, &c->instructions, link) {
                if (inst->sf) {
                        if (!sf_live) {
                                /* Our instruction's SF isn't read, so drop it.
                                 */
                                dump_from(c, inst, "dead SF");
                                inst->sf = false;
                                dump_to(c, inst);
                                progress = true;
                        } else if (last_sf &&
                                   inst_result_equals(last_sf, inst)) {
                                /* The last_sf sets up same value as inst, so
                                 * just drop the later one.
                                 */
                                dump_from(c, last_sf, "repeated SF");
                                last_sf->sf = false;
                                dump_to(c, last_sf);
                                progress = true;
                                last_sf = inst;
                        } else {
                                last_sf = inst;
                        }
                        sf_live = false;
                }

                if (last_sf) {
                        if (inst_srcs_updated(last_sf, inst))
                                last_sf = NULL;
                }

                if (qir_depends_on_flags(inst))
                        sf_live = true;
        }

        return progress;
}