aco: introduce notion of block_kind_loop_latch

A block annotated with block_kind_loop_latch denotes a block
the re-entry point for a loop back-edge. It is emitted after
the loop preheader and (potentially) before the loop header.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39519>
This commit is contained in:
Daniel Schürmann 2026-01-21 23:20:12 +01:00 committed by Marge Bot
parent 9887ce6709
commit da1594f8bb
3 changed files with 10 additions and 4 deletions

View file

@ -2145,6 +2145,7 @@ enum block_kind {
block_kind_export_end = 1 << 13,
block_kind_end_with_regs = 1 << 14,
block_kind_contains_call = 1 << 15,
block_kind_loop_latch = 1 << 16,
};
/* CFG */

View file

@ -826,7 +826,7 @@ print_vopd_instr(enum amd_gfx_level gfx_level, const Instruction* instr, FILE* o
}
static void
print_block_kind(uint16_t kind, FILE* output)
print_block_kind(uint32_t kind, FILE* output)
{
if (kind & block_kind_uniform)
fprintf(output, "uniform, ");
@ -836,6 +836,8 @@ print_block_kind(uint16_t kind, FILE* output)
fprintf(output, "loop-preheader, ");
if (kind & block_kind_loop_header)
fprintf(output, "loop-header, ");
else if (kind & block_kind_loop_latch)
fprintf(output, "loop-latch, ");
if (kind & block_kind_loop_exit)
fprintf(output, "loop-exit, ");
if (kind & block_kind_continue)

View file

@ -152,24 +152,27 @@ end_loop(isel_context* ctx, loop_context* lc)
* divergent control flow requires WQM.
*/
assert(!ctx->cf_info.exec.potentially_empty_discard);
Block& header = ctx->program->blocks[ctx->cf_info.parent_loop.header_idx];
/* Add the trivial continue. */
if (!ctx->cf_info.has_branch) {
unsigned loop_header_idx = ctx->cf_info.parent_loop.header_idx;
Builder bld(ctx->program, ctx->block);
ctx->block->kind |= (block_kind_continue | block_kind_uniform);
if (!ctx->cf_info.has_divergent_branch) {
append_logical_end(ctx);
add_edge(ctx->block->index, &ctx->program->blocks[loop_header_idx]);
add_edge(ctx->block->index, &header);
} else {
add_linear_edge(ctx->block->index, &ctx->program->blocks[loop_header_idx]);
add_linear_edge(ctx->block->index, &header);
}
bld.reset(ctx->block);
bld.branch(aco_opcode::p_branch);
}
if (header.linear_preds.size() > 1)
header.kind |= block_kind_loop_latch;
/* emit loop successor block */
ctx->program->next_loop_depth--;
ctx->block = ctx->program->insert_block(std::move(lc->loop_exit));