"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/broadcom/compiler/vir_opt_redundant_flags.c" (16 Sep 2020, 4947 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "vir_opt_redundant_flags.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright © 2019 Broadcom
    3  *
    4  * Permission is hereby granted, free of charge, to any person obtaining a
    5  * copy of this software and associated documentation files (the "Software"),
    6  * to deal in the Software without restriction, including without limitation
    7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    8  * and/or sell copies of the Software, and to permit persons to whom the
    9  * Software is furnished to do so, subject to the following conditions:
   10  *
   11  * The above copyright notice and this permission notice (including the next
   12  * paragraph) shall be included in all copies or substantial portions of the
   13  * Software.
   14  *
   15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   21  * IN THE SOFTWARE.
   22  */
   23 
   24 /**
   25  * @file v3d_opt_redundant_flags.c
   26  *
   27  * This eliminates the APF/MPF flags for redundant flags updates.  These are
   28  * often produced by our channel masking in nonuniform control flow.
   29  */
   30 
   31 #include "v3d_compiler.h"
   32 
   33 static bool debug;
   34 
   35 static void
   36 vir_dce_pf(struct v3d_compile *c, struct qinst *inst)
   37 {
   38         if (debug) {
   39                 fprintf(stderr,
   40                         "Removing flags write from: ");
   41                 vir_dump_inst(c, inst);
   42                 fprintf(stderr, "\n");
   43         }
   44 
   45         assert(inst->qpu.type == V3D_QPU_INSTR_TYPE_ALU);
   46 
   47         inst->qpu.flags.apf = V3D_QPU_PF_NONE;
   48         inst->qpu.flags.mpf = V3D_QPU_PF_NONE;
   49 }
   50 
   51 static bool
   52 vir_sources_modified(struct qinst *srcs, struct qinst *write)
   53 {
   54         for (int i = 0; i < vir_get_nsrc(srcs); i++) {
   55                 if (write->dst.file == QFILE_TEMP &&
   56                     srcs->src[i].file == QFILE_TEMP &&
   57                     srcs->src[i].index == write->dst.index) {
   58                         return true;
   59                 }
   60 
   61                 /* assume magic regs may be modified by basically anything. */
   62                 if (srcs->src[i].file != QFILE_TEMP &&
   63                     srcs->src[i].file != QFILE_SMALL_IMM)
   64                         return true;
   65         }
   66 
   67         return false;
   68 }
   69 
   70 static bool
   71 vir_instr_flags_op_equal(struct qinst *a, struct qinst *b)
   72 {
   73         for (int i = 0; i < vir_get_nsrc(a); i++) {
   74                 if (a->src[i].file != b->src[i].file ||
   75                     a->src[i].index != b->src[i].index) {
   76                         return false;
   77                 }
   78         }
   79 
   80         if (a->qpu.flags.apf != b->qpu.flags.apf ||
   81             a->qpu.flags.mpf != b->qpu.flags.mpf ||
   82             a->qpu.alu.add.op != b->qpu.alu.add.op ||
   83             a->qpu.alu.mul.op != b->qpu.alu.mul.op ||
   84             a->qpu.alu.add.a_unpack != b->qpu.alu.add.a_unpack ||
   85             a->qpu.alu.add.b_unpack != b->qpu.alu.add.b_unpack ||
   86             a->qpu.alu.add.output_pack != b->qpu.alu.add.output_pack ||
   87             a->qpu.alu.mul.a_unpack != b->qpu.alu.mul.a_unpack ||
   88             a->qpu.alu.mul.b_unpack != b->qpu.alu.mul.b_unpack ||
   89             a->qpu.alu.mul.output_pack != b->qpu.alu.mul.output_pack) {
   90                 return false;
   91         }
   92 
   93         return true;
   94 }
   95 
   96 static bool
   97 vir_opt_redundant_flags_block(struct v3d_compile *c, struct qblock *block)
   98 {
   99         struct qinst *last_flags = NULL;
  100         bool progress = false;
  101 
  102         vir_for_each_inst(inst, block) {
  103                 if (inst->qpu.type != V3D_QPU_INSTR_TYPE_ALU ||
  104                     inst->qpu.flags.auf != V3D_QPU_UF_NONE ||
  105                     inst->qpu.flags.muf != V3D_QPU_UF_NONE) {
  106                         last_flags = NULL;
  107                         continue;
  108                 }
  109 
  110                 /* Flags aren't preserved across a thrsw. */
  111                 if (inst->qpu.sig.thrsw)
  112                         last_flags = NULL;
  113 
  114                 if (inst->qpu.flags.apf != V3D_QPU_PF_NONE ||
  115                     inst->qpu.flags.mpf != V3D_QPU_PF_NONE) {
  116                         if (last_flags &&
  117                             vir_instr_flags_op_equal(inst, last_flags)) {
  118                                 vir_dce_pf(c, inst);
  119                                 progress = true;
  120                         } else {
  121                                 last_flags = inst;
  122                         }
  123                 }
  124 
  125                 if (last_flags && vir_sources_modified(last_flags, inst)) {
  126                         last_flags = NULL;
  127                 }
  128         }
  129 
  130         return progress;
  131 }
  132 
  133 bool
  134 vir_opt_redundant_flags(struct v3d_compile *c)
  135 {
  136         bool progress = false;
  137 
  138         vir_for_each_block(block, c) {
  139                 progress = vir_opt_redundant_flags_block(c, block) || progress;
  140         }
  141 
  142         return progress;
  143 }