ir3: Extract out helper for nop flags

Extract out a helper to add a flag to a nop, potentially re-using a
previous nop where possible.

Signed-off-by: Rob Clark <rob.clark@oss.qualcomm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38450>
This commit is contained in:
Rob Clark 2025-11-11 07:41:29 -08:00 committed by Marge Bot
parent d1df3b4e39
commit a48e4b8340

View file

@ -631,6 +631,34 @@ ir3_update_legalize_state(struct ir3_legalize_state *state,
state->cycle += n->repeat + n->nop; state->cycle += n->repeat + n->nop;
} }
static struct ir3_instruction *
insert_nop_flags(struct ir3_legalize_ctx *ctx,
struct ir3_legalize_state *state,
struct ir3_instruction *last_n,
struct ir3_builder *build,
enum ir3_instruction_flags flags)
{
if (last_n && last_n->opc == OPC_NOP) {
/* Note that reusing the previous nop isn't just an optimization
* but prevents infinitely adding nops when this block is in a loop
* and needs to be legalized more than once.
*/
last_n->flags |= flags;
/* If we reuse the last nop, we shouldn't do a full state update as
* its delay has already been taken into account.
*/
sync_update(state, ctx->compiler, last_n);
} else {
struct ir3_instruction *nop = ir3_NOP(build);
nop->flags |= flags;
ir3_update_legalize_state(state, ctx->compiler, nop);
last_n = nop;
}
return last_n;
}
/* We want to evaluate each block from the position of any other /* We want to evaluate each block from the position of any other
* predecessor block, in order that the flags set are the union of * predecessor block, in order that the flags set are the union of
* all possible program paths. * all possible program paths.
@ -732,24 +760,7 @@ legalize_block(struct ir3_legalize_ctx *ctx, struct ir3_block *block)
* this should be a pretty rare case: * this should be a pretty rare case:
*/ */
if ((n->flags & IR3_INSTR_SS) && !supports_ss(n)) { if ((n->flags & IR3_INSTR_SS) && !supports_ss(n)) {
if (last_n && last_n->opc == OPC_NOP) { last_n = insert_nop_flags(ctx, state, last_n, &build, IR3_INSTR_SS);
/* Note that reusing the previous nop isn't just an optimization
* but prevents infinitely adding nops when this block is in a loop
* and needs to be legalized more than once.
*/
last_n->flags |= IR3_INSTR_SS;
/* If we reuse the last nop, we shouldn't do a full state update as
* its delay has already been taken into account.
*/
sync_update(state, ctx->compiler, last_n);
} else {
struct ir3_instruction *nop = ir3_NOP(&build);
nop->flags |= IR3_INSTR_SS;
ir3_update_legalize_state(state, ctx->compiler, nop);
last_n = nop;
}
n->flags &= ~IR3_INSTR_SS; n->flags &= ~IR3_INSTR_SS;
} }