ir3/ra: handle phis with preferred regs first

Handle phis in two groups: first those which already have a preferred
reg set and then those without. The second group should be rare but by
handling them last, they don't accidentally occupy a preferred reg of
another phi, preventing excessive copying in some cases.

Signed-off-by: Job Noorman <jnoorman@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33489>
This commit is contained in:
Job Noorman 2025-02-11 09:13:26 +01:00 committed by Marge Bot
parent 922bfe4b6e
commit c6a932d4b3

View file

@ -2293,9 +2293,22 @@ handle_block(struct ra_ctx *ctx, struct ir3_block *block)
handle_live_in(ctx, reg); handle_live_in(ctx, reg);
} }
/* Handle phis in two groups: first those which already have a preferred reg
* set and then those without. The second group should be rare but by
* handling them last, they don't accidentally occupy a preferred reg of
* another phi, preventing excessive copying in some cases.
*/
bool skipped_phi = false;
foreach_instr (instr, &block->instr_list) { foreach_instr (instr, &block->instr_list) {
if (instr->opc == OPC_META_PHI) { if (instr->opc == OPC_META_PHI) {
handle_phi(ctx, instr->dsts[0]); struct ir3_register *dst = instr->dsts[0];
if (dst->merge_set && dst->merge_set->preferred_reg != (physreg_t)~0) {
handle_phi(ctx, dst);
} else {
skipped_phi = true;
}
} else if (instr->opc == OPC_META_INPUT || } else if (instr->opc == OPC_META_INPUT ||
instr->opc == OPC_META_TEX_PREFETCH) { instr->opc == OPC_META_TEX_PREFETCH) {
handle_input(ctx, instr); handle_input(ctx, instr);
@ -2304,6 +2317,20 @@ handle_block(struct ra_ctx *ctx, struct ir3_block *block)
} }
} }
if (skipped_phi) {
foreach_instr (instr, &block->instr_list) {
if (instr->opc == OPC_META_PHI) {
struct ir3_register *dst = instr->dsts[0];
if (!ctx->intervals[dst->name].interval.inserted) {
handle_phi(ctx, dst);
}
} else {
break;
}
}
}
/* After this point, every live-in/phi/input has an interval assigned to /* After this point, every live-in/phi/input has an interval assigned to
* it. We delay actually assigning values until everything has been * it. We delay actually assigning values until everything has been
* allocated, so we can simply ignore any parallel copy entries created * allocated, so we can simply ignore any parallel copy entries created