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