2 * Copyright © 2016 Broadcom
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:
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
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
25 * @file vc4_opt_peephole_sf.c
27 * Quick optimization to eliminate unused or identical SF updates.
31 #include "util/u_math.h"
36 dump_from(struct vc4_compile
*c
, struct qinst
*inst
, const char *type
)
41 fprintf(stderr
, "optimizing %s: ", type
);
42 qir_dump_inst(c
, inst
);
43 fprintf(stderr
, "\n");
47 dump_to(struct vc4_compile
*c
, struct qinst
*inst
)
52 fprintf(stderr
, "to: ");
53 qir_dump_inst(c
, inst
);
54 fprintf(stderr
, "\n");
58 inst_srcs_updated(struct qinst
*inst
, struct qinst
*writer
)
60 /* If the sources get overwritten, stop tracking the
61 * last instruction writing SF.
63 switch (writer
->dst
.file
) {
65 for (int i
= 0; i
< qir_get_nsrc(inst
); i
++) {
66 if (inst
->src
[i
].file
== QFILE_TEMP
&&
67 inst
->src
[i
].index
== writer
->dst
.index
) {
78 src_file_varies_on_reread(struct qreg reg
)
90 inst_result_equals(struct qinst
*a
, struct qinst
*b
)
93 qir_depends_on_flags(a
) ||
94 qir_depends_on_flags(b
)) {
98 for (int i
= 0; i
< qir_get_nsrc(a
); i
++) {
99 if (!qir_reg_equals(a
->src
[i
], b
->src
[i
]) ||
100 src_file_varies_on_reread(a
->src
[i
]) ||
101 src_file_varies_on_reread(b
->src
[i
])) {
110 qir_opt_peephole_sf_block(struct vc4_compile
*c
, struct qblock
*block
)
112 bool progress
= false;
113 /* We don't have liveness dataflow analysis for flags, but we also
114 * never generate a use of flags across control flow, so just treat
115 * them as unused at block exit.
117 bool sf_live
= false;
118 struct qinst
*last_sf
= NULL
;
120 /* Walk the block from bottom to top, tracking if the SF is used, and
121 * removing unused or repeated ones.
123 qir_for_each_inst_rev(inst
, block
) {
126 /* Our instruction's SF isn't read, so drop it.
128 dump_from(c
, inst
, "dead SF");
132 } else if (last_sf
&&
133 inst_result_equals(last_sf
, inst
)) {
134 /* The last_sf sets up same value as inst, so
135 * just drop the later one.
137 dump_from(c
, last_sf
, "repeated SF");
149 if (inst_srcs_updated(last_sf
, inst
))
153 if (qir_depends_on_flags(inst
))
161 qir_opt_peephole_sf(struct vc4_compile
*c
)
163 bool progress
= false;
165 qir_for_each_block(block
, c
)
166 progress
= qir_opt_peephole_sf_block(c
, block
) || progress
;