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 <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5123>
This commit is contained in:
Alyssa Rosenzweig
2020-05-06 16:06:54 -04:00
committed by Marge Bot
parent 4cf02b5d4a
commit c24dfc9da4
3 changed files with 39 additions and 23 deletions
-1
View File
@@ -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);
-21
View File
@@ -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
+39 -1
View File
@@ -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);
}