From c24dfc9da42abadf079b012f0d6e52fb4c829112 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Wed, 6 May 2020 16:06:54 -0400 Subject: [PATCH] pan/mdg: Precompute mir_special_index Rather than O(N) each call, we can precompute the whole set - also O(N) - and then subsequent checks are O(1). Signed-off-by: Alyssa Rosenzweig Part-of: --- src/panfrost/midgard/compiler.h | 1 - src/panfrost/midgard/mir.c | 21 ----------- src/panfrost/midgard/mir_promote_uniforms.c | 40 ++++++++++++++++++++- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/panfrost/midgard/compiler.h b/src/panfrost/midgard/compiler.h index 618c0d79265..93ff9605542 100644 --- a/src/panfrost/midgard/compiler.h +++ b/src/panfrost/midgard/compiler.h @@ -481,7 +481,6 @@ void mir_rewrite_index_dst_single(midgard_instruction *ins, unsigned old, unsign void mir_rewrite_index_src_single(midgard_instruction *ins, unsigned old, unsigned new); void mir_rewrite_index_src_swizzle(compiler_context *ctx, unsigned old, unsigned new, unsigned *swizzle); bool mir_single_use(compiler_context *ctx, unsigned value); -bool mir_special_index(compiler_context *ctx, unsigned idx); unsigned mir_use_count(compiler_context *ctx, unsigned value); uint16_t mir_bytemask_of_read_components(midgard_instruction *ins, unsigned node); uint16_t mir_bytemask_of_read_components_index(midgard_instruction *ins, unsigned i); diff --git a/src/panfrost/midgard/mir.c b/src/panfrost/midgard/mir.c index 68f6286c590..0289e5e3496 100644 --- a/src/panfrost/midgard/mir.c +++ b/src/panfrost/midgard/mir.c @@ -176,27 +176,6 @@ mir_nontrivial_outmod(midgard_instruction *ins) return mod != midgard_outmod_none; } -/* Checks if an index will be used as a special register -- basically, if we're - * used as the input to a non-ALU op */ - -bool -mir_special_index(compiler_context *ctx, unsigned idx) -{ - mir_foreach_instr_global(ctx, ins) { - bool is_ldst = ins->type == TAG_LOAD_STORE_4; - bool is_tex = ins->type == TAG_TEXTURE_4; - bool is_writeout = ins->compact_branch && ins->writeout; - - if (!(is_ldst || is_tex || is_writeout)) - continue; - - if (mir_has_arg(ins, idx)) - return true; - } - - return false; -} - /* Grabs the type size. */ midgard_reg_mode diff --git a/src/panfrost/midgard/mir_promote_uniforms.c b/src/panfrost/midgard/mir_promote_uniforms.c index 620b443d314..d78484c3568 100644 --- a/src/panfrost/midgard/mir_promote_uniforms.c +++ b/src/panfrost/midgard/mir_promote_uniforms.c @@ -127,12 +127,46 @@ mir_work_heuristic(compiler_context *ctx) return 8; } +/* Bitset of indices that will be used as a special register -- inputs to a + * non-ALU op. We precompute this set so that testing is efficient, otherwise + * we end up O(mn) behaviour for n instructions and m uniform reads */ + +static BITSET_WORD * +mir_special_indices(compiler_context *ctx) +{ + mir_compute_temp_count(ctx); + BITSET_WORD *bset = calloc(BITSET_WORDS(ctx->temp_count), sizeof(BITSET_WORD)); + + mir_foreach_instr_global(ctx, ins) { + /* Look for special instructions */ + bool is_ldst = ins->type == TAG_LOAD_STORE_4; + bool is_tex = ins->type == TAG_TEXTURE_4; + bool is_writeout = ins->compact_branch && ins->writeout; + + if (!(is_ldst || is_tex || is_writeout)) + continue; + + /* Anything read by a special instruction is itself special */ + mir_foreach_src(ins, i) { + unsigned idx = ins->src[i]; + + if (idx < ctx->temp_count) + BITSET_SET(bset, idx); + } + } + + return bset; +} + void midgard_promote_uniforms(compiler_context *ctx) { unsigned work_count = mir_work_heuristic(ctx); unsigned promoted_count = 24 - work_count; + /* First, figure out special indices a priori so we don't recompute a lot */ + BITSET_WORD *special = mir_special_indices(ctx); + mir_foreach_instr_global_safe(ctx, ins) { if (!mir_is_promoteable_ubo(ins)) continue; @@ -153,7 +187,9 @@ midgard_promote_uniforms(compiler_context *ctx) * we're being fed into a special class */ bool needs_move = ins->dest & PAN_IS_REG; - needs_move |= mir_special_index(ctx, ins->dest); + + if (ins->dest < ctx->temp_count) + needs_move |= BITSET_TEST(special, ins->dest); if (needs_move) { midgard_instruction mov = v_mov(promoted, ins->dest); @@ -170,4 +206,6 @@ midgard_promote_uniforms(compiler_context *ctx) mir_remove_instruction(ins); } + + free(special); } -- 2.30.2