Mesa (master): pan/mdg: Analyze helper execution requirements

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue May 12 22:54:14 UTC 2020


Module: Mesa
Branch: master
Commit: d429187bf3988fca190fcbd53e416b8a46506b25
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=d429187bf3988fca190fcbd53e416b8a46506b25

Author: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Date:   Tue May 12 13:19:23 2020 -0400

pan/mdg: Analyze helper execution requirements

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5014>

---

 src/panfrost/midgard/compiler.h                   |  2 +
 src/panfrost/midgard/midgard_helper_invocations.c | 87 +++++++++++++++++++++++
 src/panfrost/midgard/midgard_print.c              |  3 +
 src/panfrost/util/pan_ir.h                        |  7 ++
 src/panfrost/util/pan_liveness.c                  |  8 ---
 5 files changed, 99 insertions(+), 8 deletions(-)

diff --git a/src/panfrost/midgard/compiler.h b/src/panfrost/midgard/compiler.h
index 6db0cfea466..bf125369fde 100644
--- a/src/panfrost/midgard/compiler.h
+++ b/src/panfrost/midgard/compiler.h
@@ -107,6 +107,7 @@ typedef struct midgard_instruction {
         /* For textures: should helpers execute this instruction (instead of
          * just helping with derivatives)? Should helpers terminate after? */
         bool helper_terminate;
+        bool helper_execute;
 
         /* I.e. (1 << alu_bit) */
         int unit;
@@ -634,6 +635,7 @@ midgard_lower_derivatives(compiler_context *ctx, midgard_block *block);
 bool mir_op_computes_derivatives(gl_shader_stage stage, unsigned op);
 
 void mir_analyze_helper_terminate(compiler_context *ctx);
+void mir_analyze_helper_requirements(compiler_context *ctx);
 
 /* Final emission */
 
diff --git a/src/panfrost/midgard/midgard_helper_invocations.c b/src/panfrost/midgard/midgard_helper_invocations.c
index 9f8c68a8125..6dfb9c09973 100644
--- a/src/panfrost/midgard/midgard_helper_invocations.c
+++ b/src/panfrost/midgard/midgard_helper_invocations.c
@@ -158,3 +158,90 @@ mir_analyze_helper_terminate(compiler_context *ctx)
                 }
         }
 }
+
+static bool
+mir_helper_block_update(BITSET_WORD *deps, pan_block *_block, unsigned temp_count)
+{
+        bool progress = false;
+        midgard_block *block = (midgard_block *) _block;
+
+        mir_foreach_instr_in_block_rev(block, ins) {
+                /* Ensure we write to a helper dependency */
+                if (ins->dest >= temp_count || !BITSET_TEST(deps, ins->dest))
+                        continue;
+
+                /* Then add all of our dependencies */
+                mir_foreach_src(ins, s) {
+                        if (ins->src[s] >= temp_count)
+                                continue;
+
+                        /* Progress if the dependency set changes */
+                        progress |= !BITSET_TEST(deps, ins->src[s]);
+                        BITSET_SET(deps, ins->src[s]);
+                }
+        }
+
+        return progress;
+}
+
+void
+mir_analyze_helper_requirements(compiler_context *ctx)
+{
+        mir_compute_temp_count(ctx);
+        unsigned temp_count = ctx->temp_count;
+        BITSET_WORD *deps = calloc(sizeof(BITSET_WORD), BITSET_WORDS(temp_count));
+
+        /* Initialize with the sources of instructions consuming
+         * derivatives */
+
+        mir_foreach_instr_global(ctx, ins) {
+                if (ins->type != TAG_TEXTURE_4) continue;
+                if (ins->dest >= ctx->temp_count) continue;
+                if (!mir_op_computes_derivatives(ctx->stage, ins->texture.op)) continue;
+
+                mir_foreach_src(ins, s) {
+                        if (ins->src[s] < temp_count)
+                                BITSET_SET(deps, ins->src[s]);
+                }
+        }
+
+        /* Propagate that up */
+
+        struct set *work_list = _mesa_set_create(NULL,
+                        _mesa_hash_pointer,
+                        _mesa_key_pointer_equal);
+
+        struct set *visited = _mesa_set_create(NULL,
+                        _mesa_hash_pointer,
+                        _mesa_key_pointer_equal);
+
+        struct set_entry *cur = _mesa_set_add(work_list, pan_exit_block(&ctx->blocks));
+
+        do {
+                pan_block *blk = (struct pan_block *) cur->key;
+                _mesa_set_remove(work_list, cur);
+
+                bool progress = mir_helper_block_update(deps, blk, temp_count);
+
+                if (progress || !_mesa_set_search(visited, blk)) {
+                        pan_foreach_predecessor(blk, pred)
+                                _mesa_set_add(work_list, pred);
+                }
+
+                _mesa_set_add(visited, blk);
+        } while((cur = _mesa_set_next_entry(work_list, NULL)) != NULL);
+
+        _mesa_set_destroy(visited, NULL);
+        _mesa_set_destroy(work_list, NULL);
+
+        /* Set the execute bits */
+
+        mir_foreach_instr_global(ctx, ins) {
+                if (ins->type != TAG_TEXTURE_4) continue;
+                if (ins->dest >= ctx->temp_count) continue;
+
+                ins->helper_execute = BITSET_TEST(deps, ins->dest);
+        }
+
+        free(deps);
+}
diff --git a/src/panfrost/midgard/midgard_print.c b/src/panfrost/midgard/midgard_print.c
index 002026a16b5..1b1ff6a145f 100644
--- a/src/panfrost/midgard/midgard_print.c
+++ b/src/panfrost/midgard/midgard_print.c
@@ -332,6 +332,9 @@ mir_print_instruction(midgard_instruction *ins)
                 if (ins->helper_terminate)
                         printf(".terminate");
 
+                if (ins->helper_execute)
+                        printf(".execute");
+
                 break;
         }
 
diff --git a/src/panfrost/util/pan_ir.h b/src/panfrost/util/pan_ir.h
index c57a8e01c34..a45478ae6ec 100644
--- a/src/panfrost/util/pan_ir.h
+++ b/src/panfrost/util/pan_ir.h
@@ -160,6 +160,13 @@ struct pan_instruction {
                 _entry_##v = _mesa_set_next_entry(blk->predecessors, _entry_##v), \
                 v = (struct pan_block *) (_entry_##v ? _entry_##v->key : NULL))
 
+static inline pan_block *
+pan_exit_block(struct list_head *blocks)
+{
+        pan_block *last = list_last_entry(blocks, pan_block, link);
+        assert(!last->successors[0] && !last->successors[1]);
+        return last;
+}
 
 typedef void (*pan_liveness_update)(uint16_t *, void *, unsigned max);
 
diff --git a/src/panfrost/util/pan_liveness.c b/src/panfrost/util/pan_liveness.c
index a46a11d9d3c..9772feb1a9c 100644
--- a/src/panfrost/util/pan_liveness.c
+++ b/src/panfrost/util/pan_liveness.c
@@ -104,14 +104,6 @@ liveness_block_update(
  * adding the predecessors of the block to the work list if we made progress.
  */
 
-static inline pan_block *
-pan_exit_block(struct list_head *blocks)
-{
-        pan_block *last = list_last_entry(blocks, pan_block, link);
-        assert(!last->successors[0] && !last->successors[1]);
-        return last;
-}
-
 void
 pan_compute_liveness(
                 struct list_head *blocks,



More information about the mesa-commit mailing list