diff --git a/src/freedreno/ir3/ir3_compiler.c b/src/freedreno/ir3/ir3_compiler.c index b068608cf2f..82349635ba6 100644 --- a/src/freedreno/ir3/ir3_compiler.c +++ b/src/freedreno/ir3/ir3_compiler.c @@ -51,6 +51,7 @@ static const struct debug_named_value shader_debug_options[] = { {"fullnop", IR3_DBG_FULLNOP, "Add nops before each instruction"}, {"noearlypreamble", IR3_DBG_NOEARLYPREAMBLE, "Disable early preambles"}, {"nodescprefetch", IR3_DBG_NODESCPREFETCH, "Disable descriptor prefetch optimization"}, + {"expandrpt", IR3_DBG_EXPANDRPT, "Expand rptN instructions"}, #if MESA_DEBUG /* MESA_DEBUG-only options: */ {"schedmsgs", IR3_DBG_SCHEDMSGS, "Enable scheduler debug messages"}, diff --git a/src/freedreno/ir3/ir3_compiler.h b/src/freedreno/ir3/ir3_compiler.h index 9b9b3dcc406..f1fe77a9932 100644 --- a/src/freedreno/ir3/ir3_compiler.h +++ b/src/freedreno/ir3/ir3_compiler.h @@ -345,6 +345,7 @@ enum ir3_shader_debug { IR3_DBG_FULLNOP = BITFIELD_BIT(16), IR3_DBG_NOEARLYPREAMBLE = BITFIELD_BIT(17), IR3_DBG_NODESCPREFETCH = BITFIELD_BIT(18), + IR3_DBG_EXPANDRPT = BITFIELD_BIT(19), /* MESA_DEBUG-only options: */ IR3_DBG_SCHEDMSGS = BITFIELD_BIT(20), diff --git a/src/freedreno/ir3/ir3_legalize.c b/src/freedreno/ir3/ir3_legalize.c index 7116e47add4..f433f7f642d 100644 --- a/src/freedreno/ir3/ir3_legalize.c +++ b/src/freedreno/ir3/ir3_legalize.c @@ -1369,6 +1369,42 @@ dbg_nop_sched(struct ir3 *ir, struct ir3_shader_variant *so) } } +static void +dbg_expand_rpt(struct ir3 *ir) +{ + foreach_block (block, &ir->block_list) { + foreach_instr_safe (instr, &block->instr_list) { + if (instr->repeat == 0 || instr->opc == OPC_NOP || + instr->opc == OPC_SWZ || instr->opc == OPC_GAT || + instr->opc == OPC_SCT) { + continue; + } + + for (unsigned i = 0; i <= instr->repeat; ++i) { + struct ir3_instruction *rpt = ir3_instr_clone(instr); + ir3_instr_move_before(rpt, instr); + rpt->repeat = 0; + + foreach_dst (dst, rpt) { + dst->num += i; + dst->wrmask = 1; + } + + foreach_src (src, rpt) { + if (!(src->flags & IR3_REG_R)) + continue; + + src->num += i; + src->wrmask = 1; + src->flags &= ~IR3_REG_R; + } + } + + list_delinit(&instr->node); + } + } +} + struct ir3_helper_block_data { /* Whether helper invocations may be used on any path starting at the * beginning of the block. @@ -1695,6 +1731,10 @@ ir3_legalize(struct ir3 *ir, struct ir3_shader_variant *so, int *max_bary) assert(ctx->early_input_release || ctx->compiler->gen >= 5); + if (ir3_shader_debug & IR3_DBG_EXPANDRPT) { + dbg_expand_rpt(ir); + } + /* process each block: */ do { progress = false;