From: Alyssa Rosenzweig Date: Sun, 17 Feb 2019 03:35:03 +0000 (+0000) Subject: panfrost/midgard: Refactor tag lookahead code X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5e55c11a1b2a0cfe91fcf58785fabe1269f1c439;p=mesa.git panfrost/midgard: Refactor tag lookahead code Each Midgard instruction is scheduled to a particular instruction type ("tag"). Presumably the hardware prefetches memory based on tag, so it is required to report out the first tag to the command stream and the next tag of a branch target. This procedure was implemented in two separate parts of the compiler (one time with a slight bug relating to empty blocks); this patch refactors to unite the two routines and solve the bug when branching to empty blocks. Signed-off-by: Alyssa Rosenzweig --- diff --git a/src/gallium/drivers/panfrost/midgard/midgard_compile.c b/src/gallium/drivers/panfrost/midgard/midgard_compile.c index cd8412c2dff..de9420685f5 100644 --- a/src/gallium/drivers/panfrost/midgard/midgard_compile.c +++ b/src/gallium/drivers/panfrost/midgard/midgard_compile.c @@ -3283,6 +3283,33 @@ emit_cf_list(struct compiler_context *ctx, struct exec_list *list) return start_block; } +/* Due to lookahead, we need to report the first tag executed in the command + * stream and in branch targets. An initial block might be empty, so iterate + * until we find one that 'works' */ + +static unsigned +midgard_get_first_tag_from_block(compiler_context *ctx, unsigned block_idx) +{ + midgard_block *initial_block = mir_get_block(ctx, block_idx); + + unsigned first_tag = 0; + + do { + midgard_bundle *initial_bundle = util_dynarray_element(&initial_block->bundles, midgard_bundle, 0); + + if (initial_bundle) { + first_tag = initial_bundle->tag; + break; + } + + /* Initial block is empty, try the next block */ + initial_block = list_first_entry(&(initial_block->link), midgard_block, link); + } while(initial_block != NULL); + + assert(first_tag); + return first_tag; +} + int midgard_compile_shader_nir(nir_shader *nir, midgard_program *program, bool is_blend) { @@ -3465,11 +3492,8 @@ midgard_compile_shader_nir(nir_shader *nir, midgard_program *program, bool is_bl midgard_block *target = mir_get_block(ctx, target_number); assert(target); - /* Determine the destination tag */ - midgard_bundle *first = util_dynarray_element(&target->bundles, midgard_bundle, 0); - assert(first); - - int dest_tag = first->tag; + /* Report the destination tag. */ + int dest_tag = midgard_get_first_tag_from_block(ctx, target_number); /* Count up the number of quadwords we're jumping over. That is, the number of quadwords in each of the blocks between (br_block_idx, target_number) */ int quadword_offset = 0; @@ -3568,28 +3592,8 @@ midgard_compile_shader_nir(nir_shader *nir, midgard_program *program, bool is_bl free(source_order_bundles); - /* Due to lookahead, we need to report in the command stream the first - * tag executed. An initial block might be empty, so iterate until we - * find one that 'works' */ - - midgard_block *initial_block = list_first_entry(&ctx->blocks, midgard_block, link); - - program->first_tag = 0; - - do { - midgard_bundle *initial_bundle = util_dynarray_element(&initial_block->bundles, midgard_bundle, 0); - - if (initial_bundle) { - program->first_tag = initial_bundle->tag; - break; - } - - /* Initial block is empty, try the next block */ - initial_block = list_first_entry(&(initial_block->link), midgard_block, link); - } while(initial_block != NULL); - - /* Make sure we actually set the tag */ - assert(program->first_tag); + /* Report the very first tag executed */ + program->first_tag = midgard_get_first_tag_from_block(ctx, 0); /* Deal with off-by-one related to the fencepost problem */ program->work_register_count = ctx->work_registers + 1;