From: Alyssa Rosenzweig Date: Tue, 12 May 2020 17:19:23 +0000 (-0400) Subject: pan/mdg: Analyze helper execution requirements X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d429187bf3988fca190fcbd53e416b8a46506b25;p=mesa.git pan/mdg: Analyze helper execution requirements Signed-off-by: Alyssa Rosenzweig Part-of: --- 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,