Path: blob/21.2-virgl/src/gallium/drivers/vc4/vc4_opt_peephole_sf.c
4570 views
/*1* Copyright © 2016 Broadcom2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223/**24* @file vc4_opt_peephole_sf.c25*26* Quick optimization to eliminate unused or identical SF updates.27*/2829#include "vc4_qir.h"30#include "util/u_math.h"3132static bool debug;3334static void35dump_from(struct vc4_compile *c, struct qinst *inst, const char *type)36{37if (!debug)38return;3940fprintf(stderr, "optimizing %s: ", type);41qir_dump_inst(c, inst);42fprintf(stderr, "\n");43}4445static void46dump_to(struct vc4_compile *c, struct qinst *inst)47{48if (!debug)49return;5051fprintf(stderr, "to: ");52qir_dump_inst(c, inst);53fprintf(stderr, "\n");54}5556static bool57inst_srcs_updated(struct qinst *inst, struct qinst *writer)58{59/* If the sources get overwritten, stop tracking the60* last instruction writing SF.61*/62switch (writer->dst.file) {63case QFILE_TEMP:64for (int i = 0; i < qir_get_nsrc(inst); i++) {65if (inst->src[i].file == QFILE_TEMP &&66inst->src[i].index == writer->dst.index) {67return true;68}69}70return false;71default:72return false;73}74}7576static bool77src_file_varies_on_reread(struct qreg reg)78{79switch (reg.file) {80case QFILE_VARY:81case QFILE_VPM:82return true;83default:84return false;85}86}8788static bool89inst_result_equals(struct qinst *a, struct qinst *b)90{91if (a->op != b->op ||92qir_depends_on_flags(a) ||93qir_depends_on_flags(b)) {94return false;95}9697for (int i = 0; i < qir_get_nsrc(a); i++) {98if (!qir_reg_equals(a->src[i], b->src[i]) ||99src_file_varies_on_reread(a->src[i]) ||100src_file_varies_on_reread(b->src[i])) {101return false;102}103}104105return true;106}107108static bool109qir_opt_peephole_sf_block(struct vc4_compile *c, struct qblock *block)110{111bool progress = false;112/* We don't have liveness dataflow analysis for flags, but we also113* never generate a use of flags across control flow, so just treat114* them as unused at block exit.115*/116bool sf_live = false;117struct qinst *last_sf = NULL;118119/* Walk the block from bottom to top, tracking if the SF is used, and120* removing unused or repeated ones.121*/122qir_for_each_inst_rev(inst, block) {123if (inst->sf) {124if (!sf_live) {125/* Our instruction's SF isn't read, so drop it.126*/127dump_from(c, inst, "dead SF");128inst->sf = false;129dump_to(c, inst);130progress = true;131} else if (last_sf &&132inst_result_equals(last_sf, inst)) {133/* The last_sf sets up same value as inst, so134* just drop the later one.135*/136dump_from(c, last_sf, "repeated SF");137last_sf->sf = false;138dump_to(c, last_sf);139progress = true;140last_sf = inst;141} else {142last_sf = inst;143}144sf_live = false;145}146147if (last_sf) {148if (inst_srcs_updated(last_sf, inst))149last_sf = NULL;150}151152if (qir_depends_on_flags(inst))153sf_live = true;154}155156return progress;157}158159bool160qir_opt_peephole_sf(struct vc4_compile *c)161{162bool progress = false;163164qir_for_each_block(block, c)165progress = qir_opt_peephole_sf_block(c, block) || progress;166167return progress;168}169170171