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