diff options
author | Alyssa Rosenzweig <[email protected]> | 2019-02-17 03:35:03 +0000 |
---|---|---|
committer | Alyssa Rosenzweig <[email protected]> | 2019-02-21 07:05:59 +0000 |
commit | 5e55c11a1b2a0cfe91fcf58785fabe1269f1c439 (patch) | |
tree | a0a3136b96703fc41c1f058d90786b8924d25541 | |
parent | 396eb1440a84d6ee69a74e9e6bf189718b91481d (diff) |
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 <[email protected]>
-rw-r--r-- | src/gallium/drivers/panfrost/midgard/midgard_compile.c | 58 |
1 files changed, 31 insertions, 27 deletions
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; |