Home | History | Annotate | Download | only in vc4
      1 /*
      2  * Copyright  2015 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 vc4_opt_constant_folding.c
     26  *
     27  * Simple constant folding pass to clean up operations on only constants,
     28  * which we might have generated within vc4_program.c.
     29  */
     30 
     31 #include "vc4_qir.h"
     32 #include "util/u_math.h"
     33 
     34 static bool debug;
     35 
     36 static void
     37 dump_from(struct vc4_compile *c, struct qinst *inst)
     38 {
     39         if (!debug)
     40                 return;
     41 
     42         fprintf(stderr, "optimizing: ");
     43         qir_dump_inst(c, inst);
     44         fprintf(stderr, "\n");
     45 }
     46 
     47 static void
     48 dump_to(struct vc4_compile *c, struct qinst *inst)
     49 {
     50         if (!debug)
     51                 return;
     52 
     53         fprintf(stderr, "to: ");
     54         qir_dump_inst(c, inst);
     55         fprintf(stderr, "\n");
     56 }
     57 
     58 static bool
     59 constant_fold(struct vc4_compile *c, struct qinst *inst)
     60 {
     61         int nsrc = qir_get_nsrc(inst);
     62         uint32_t ui[nsrc];
     63 
     64         for (int i = 0; i < nsrc; i++) {
     65                 struct qreg reg = inst->src[i];
     66                 if (reg.file == QFILE_UNIF &&
     67                     c->uniform_contents[reg.index] == QUNIFORM_CONSTANT) {
     68                         ui[i] = c->uniform_data[reg.index];
     69                 } else if (reg.file == QFILE_SMALL_IMM) {
     70                         ui[i] = reg.index;
     71                 } else {
     72                         return false;
     73                 }
     74         }
     75 
     76         uint32_t result = 0;
     77         switch (inst->op) {
     78         case QOP_SHR:
     79                 result = ui[0] >> ui[1];
     80                 break;
     81 
     82         default:
     83                 return false;
     84         }
     85 
     86         dump_from(c, inst);
     87 
     88         inst->src[0] = qir_uniform_ui(c, result);
     89         for (int i = 1; i < nsrc; i++)
     90                 inst->src[i] = c->undef;
     91         inst->op = QOP_MOV;
     92 
     93         dump_to(c, inst);
     94         return true;
     95 }
     96 
     97 bool
     98 qir_opt_constant_folding(struct vc4_compile *c)
     99 {
    100         bool progress = false;
    101 
    102         qir_for_each_inst_inorder(inst, c) {
    103                 if (constant_fold(c, inst))
    104                         progress = true;
    105         }
    106 
    107         return progress;
    108 }
    109