• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
dump_from(struct vc4_compile * c,struct qinst * inst)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
dump_to(struct vc4_compile * c,struct qinst * inst)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
constant_fold(struct vc4_compile * c,struct qinst * inst)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
qir_opt_constant_folding(struct vc4_compile * c)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