xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/vc4/vc4_opt_constant_folding.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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 
63         if (nsrc == 0)
64                 return false;
65 
66         uint32_t ui[nsrc];
67 
68         for (int i = 0; i < nsrc; i++) {
69                 struct qreg reg = inst->src[i];
70                 if (reg.file == QFILE_UNIF &&
71                     c->uniform_contents[reg.index] == QUNIFORM_CONSTANT) {
72                         ui[i] = c->uniform_data[reg.index];
73                 } else if (reg.file == QFILE_SMALL_IMM) {
74                         ui[i] = reg.index;
75                 } else {
76                         return false;
77                 }
78         }
79 
80         uint32_t result = 0;
81         switch (inst->op) {
82         case QOP_SHR:
83                 result = ui[0] >> ui[1];
84                 break;
85 
86         default:
87                 return false;
88         }
89 
90         dump_from(c, inst);
91 
92         inst->src[0] = qir_uniform_ui(c, result);
93         for (int i = 1; i < nsrc; i++)
94                 inst->src[i] = c->undef;
95         inst->op = QOP_MOV;
96 
97         dump_to(c, inst);
98         return true;
99 }
100 
101 bool
qir_opt_constant_folding(struct vc4_compile * c)102 qir_opt_constant_folding(struct vc4_compile *c)
103 {
104         bool progress = false;
105 
106         qir_for_each_inst_inorder(inst, c) {
107                 if (constant_fold(c, inst))
108                         progress = true;
109         }
110 
111         return progress;
112 }
113