ir3: insert predicate conversions after their source

Instead of creating a cmps.s.ne for every use of a predicate, create
just one and insert it after the instruction whose def is tested. This
reduces the number of compares or, when they are folded into bitwise
operations, those operations.

It also decreases register pressure on GPRs by increasing pressure on
predicate registers. This should be preferred in general since at worst,
the predicate register will be spilled to a GPR again.

Signed-off-by: Job Noorman <jnoorman@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27411>
This commit is contained in:
Job Noorman
2024-02-01 14:51:23 +01:00
committed by Marge Bot
parent c6a6902e4d
commit c43d0e4e4f
4 changed files with 34 additions and 1 deletions
+15
View File
@@ -560,6 +560,21 @@ ir3_block_get_last_non_terminator(struct ir3_block *block)
return NULL;
}
struct ir3_instruction *
ir3_block_get_last_phi(struct ir3_block *block)
{
struct ir3_instruction *last_phi = NULL;
foreach_instr (instr, &block->instr_list) {
if (instr->opc != OPC_META_PHI)
break;
last_phi = instr;
}
return last_phi;
}
void
ir3_block_add_predecessor(struct ir3_block *block, struct ir3_block *pred)
{
+2
View File
@@ -703,6 +703,8 @@ struct ir3_instruction *ir3_block_take_terminator(struct ir3_block *block);
struct ir3_instruction *
ir3_block_get_last_non_terminator(struct ir3_block *block);
struct ir3_instruction *ir3_block_get_last_phi(struct ir3_block *block);
static inline struct ir3_block *
ir3_after_preamble(struct ir3 *ir)
{
+16 -1
View File
@@ -73,6 +73,7 @@ ir3_context_init(struct ir3_compiler *compiler, struct ir3_shader *shader,
_mesa_hash_table_create(ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
ctx->sel_cond_conversions =
_mesa_hash_table_create(ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
ctx->predicate_conversions = _mesa_pointer_hash_table_create(ctx);
/* TODO: maybe generate some sort of bitmask of what key
* lowers vs what shader has (ie. no need to lower
@@ -460,7 +461,12 @@ ir3_get_addr1(struct ir3_context *ctx, unsigned const_val)
struct ir3_instruction *
ir3_get_predicate(struct ir3_context *ctx, struct ir3_instruction *src)
{
struct ir3_block *b = ctx->block;
struct hash_entry *src_entry =
_mesa_hash_table_search(ctx->predicate_conversions, src);
if (src_entry)
return src_entry->data;
struct ir3_block *b = src->block;
struct ir3_instruction *cond;
/* NOTE: we use cpms.s.ne x, 0 to move x into a predicate register */
@@ -472,6 +478,15 @@ ir3_get_predicate(struct ir3_context *ctx, struct ir3_instruction *src)
/* condition always goes in predicate register: */
cond->dsts[0]->flags |= IR3_REG_PREDICATE;
/* phi's should stay first in a block */
if (src->opc == OPC_META_PHI)
ir3_instr_move_after(zero, ir3_block_get_last_phi(src->block));
else
ir3_instr_move_after(zero, src);
ir3_instr_move_after(cond, zero);
_mesa_hash_table_insert(ctx->predicate_conversions, src, cond);
return cond;
}
+1
View File
@@ -128,6 +128,7 @@ struct ir3_context {
struct hash_table_u64 *addr1_ht;
struct hash_table *sel_cond_conversions;
struct hash_table *predicate_conversions;
/* last dst array, for indirect we need to insert a var-store.
*/