Path: blob/21.2-virgl/src/gallium/drivers/vc4/vc4_opt_dead_code.c
4570 views
/*1* Copyright © 2014 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_dead_code.c25*26* This is a simple dead code eliminator for SSA values in QIR.27*28* It walks all the instructions finding what temps are used, then walks again29* to remove instructions writing unused temps.30*31* This is an inefficient implementation if you have long chains of32* instructions where the entire chain is dead, but we expect those to have33* been eliminated at the NIR level, and here we're just cleaning up small34* problems produced by NIR->QIR.35*/3637#include "vc4_qir.h"3839static bool debug;4041static void42dce(struct vc4_compile *c, struct qinst *inst)43{44if (debug) {45fprintf(stderr, "Removing: ");46qir_dump_inst(c, inst);47fprintf(stderr, "\n");48}49assert(!inst->sf);50qir_remove_instruction(c, inst);51}5253static bool54has_nonremovable_reads(struct vc4_compile *c, struct qinst *inst)55{56for (int i = 0; i < qir_get_nsrc(inst); i++) {57if (inst->src[i].file == QFILE_VPM) {58uint32_t attr = inst->src[i].index / 4;59uint32_t offset = (inst->src[i].index % 4) * 4;6061if (c->vattr_sizes[attr] != offset + 4)62return true;6364/* Can't get rid of the last VPM read, or the65* simulator (at least) throws an error.66*/67uint32_t total_size = 0;68for (uint32_t i = 0; i < ARRAY_SIZE(c->vattr_sizes); i++)69total_size += c->vattr_sizes[i];70if (total_size == 4)71return true;72}7374if (inst->src[i].file == QFILE_VARY &&75c->input_slots[inst->src[i].index].slot == 0xff) {76return true;77}78}7980return false;81}8283bool84qir_opt_dead_code(struct vc4_compile *c)85{86bool progress = false;87bool *used = calloc(c->num_temps, sizeof(bool));8889qir_for_each_inst_inorder(inst, c) {90for (int i = 0; i < qir_get_nsrc(inst); i++) {91if (inst->src[i].file == QFILE_TEMP)92used[inst->src[i].index] = true;93}94}9596qir_for_each_block(block, c) {97qir_for_each_inst_safe(inst, block) {98if (inst->dst.file != QFILE_NULL &&99!(inst->dst.file == QFILE_TEMP &&100!used[inst->dst.index])) {101continue;102}103104if (qir_has_side_effects(c, inst))105continue;106107if (inst->sf ||108has_nonremovable_reads(c, inst)) {109/* If we can't remove the instruction, but we110* don't need its destination value, just111* remove the destination. The register112* allocator would trivially color it and it113* wouldn't cause any register pressure, but114* it's nicer to read the QIR code without115* unused destination regs.116*/117if (inst->dst.file == QFILE_TEMP) {118if (debug) {119fprintf(stderr,120"Removing dst from: ");121qir_dump_inst(c, inst);122fprintf(stderr, "\n");123}124c->defs[inst->dst.index] = NULL;125inst->dst.file = QFILE_NULL;126progress = true;127}128continue;129}130131for (int i = 0; i < qir_get_nsrc(inst); i++) {132if (inst->src[i].file != QFILE_VPM)133continue;134uint32_t attr = inst->src[i].index / 4;135uint32_t offset = (inst->src[i].index % 4) * 4;136137if (c->vattr_sizes[attr] == offset + 4) {138c->num_inputs--;139c->vattr_sizes[attr] -= 4;140}141}142143dce(c, inst);144progress = true;145continue;146}147}148149free(used);150151return progress;152}153154155