summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/vc4/vc4_opt_peephole_sf.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/gallium/drivers/vc4/vc4_opt_peephole_sf.c b/src/gallium/drivers/vc4/vc4_opt_peephole_sf.c
index 414a9ef1eb3..f4856673ba2 100644
--- a/src/gallium/drivers/vc4/vc4_opt_peephole_sf.c
+++ b/src/gallium/drivers/vc4/vc4_opt_peephole_sf.c
@@ -106,18 +106,21 @@ inst_result_equals(struct qinst *a, struct qinst *b)
return true;
}
-bool
-qir_opt_peephole_sf(struct vc4_compile *c)
+static bool
+qir_opt_peephole_sf_block(struct vc4_compile *c, struct qblock *block)
{
bool progress = false;
+ /* We don't have liveness dataflow analysis for flags, but we also
+ * never generate a use of flags across control flow, so just treat
+ * them as unused at block exit.
+ */
bool sf_live = false;
struct qinst *last_sf = NULL;
/* Walk the block from bottom to top, tracking if the SF is used, and
* removing unused or repeated ones.
*/
- list_for_each_entry_rev(struct qinst, inst, &c->cur_block->instructions,
- link) {
+ qir_for_each_inst_rev(inst, block) {
if (inst->sf) {
if (!sf_live) {
/* Our instruction's SF isn't read, so drop it.
@@ -153,3 +156,14 @@ qir_opt_peephole_sf(struct vc4_compile *c)
return progress;
}
+
+bool
+qir_opt_peephole_sf(struct vc4_compile *c)
+{
+ bool progress = false;
+
+ qir_for_each_block(block, c)
+ progress = qir_opt_peephole_sf_block(c, block) || progress;
+
+ return progress;
+}