Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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_op_nsrc(inst->op);
  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.         struct simple_node *node;
  102.  
  103.         foreach(node, &c->instructions) {
  104.                 struct qinst *inst = (struct qinst *)node;
  105.                 if (constant_fold(c, inst))
  106.                         progress = true;
  107.         }
  108.  
  109.         return progress;
  110. }
  111.