pan: Adapt calc_dominance from nir to bi

Mostly "s/nir_block/bi_block/g" and some small fixups.

Reviewed-by: Eric R. Smith <eric.smith@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38393>
This commit is contained in:
Christoph Pillmayer
2025-11-11 12:39:22 +00:00
committed by Marge Bot
parent dd01573207
commit 5ae1b68cb0
4 changed files with 67 additions and 52 deletions

View File

@@ -25,7 +25,7 @@
*
*/
#include "nir.h"
#include "compiler.h"
/*
* Implements the algorithms for computing the dominance tree and the
@@ -34,15 +34,15 @@
*/
static bool
init_block(nir_block *block, nir_function_impl *impl)
init_block(bi_block *block, bi_context *ctx)
{
if (block == nir_start_block(impl))
if (block == bi_entry_block(ctx))
block->imm_dom = block;
else
block->imm_dom = NULL;
block->num_dom_children = 0;
/* See nir_block_dominates */
/* See bi_block_dominates */
block->dom_pre_index = UINT32_MAX;
block->dom_post_index = 0;
@@ -51,8 +51,8 @@ init_block(nir_block *block, nir_function_impl *impl)
return true;
}
static nir_block *
intersect(nir_block *b1, nir_block *b2)
static bi_block *
intersect(bi_block *b1, bi_block *b2)
{
while (b1 != b2) {
/*
@@ -70,11 +70,11 @@ intersect(nir_block *b1, nir_block *b2)
}
static bool
calc_dominance(nir_block *block)
calc_dominance(bi_block *block)
{
nir_block *new_idom = NULL;
set_foreach(&block->predecessors, entry) {
nir_block *pred = (nir_block *)entry->key;
bi_block *new_idom = NULL;
bi_foreach_predecessor(block, p) {
bi_block *pred = (*p);
if (pred->imm_dom) {
if (new_idom)
@@ -93,11 +93,11 @@ calc_dominance(nir_block *block)
}
static bool
calc_dom_frontier(nir_block *block)
calc_dom_frontier(bi_block *block)
{
if (block->predecessors.entries > 1) {
set_foreach(&block->predecessors, entry) {
nir_block *runner = (nir_block *)entry->key;
if (block->predecessors.size > 1) {
bi_foreach_predecessor(block, p) {
bi_block *runner = (*p);
/* Skip unreachable predecessors */
if (runner->imm_dom == NULL)
@@ -125,16 +125,16 @@ calc_dom_frontier(nir_block *block)
*/
static void
calc_dom_children(nir_function_impl *impl)
calc_dom_children(bi_context *ctx)
{
void *mem_ctx = ralloc_parent(impl);
void *mem_ctx = ctx;
nir_foreach_block_unstructured(block, impl) {
bi_foreach_block(ctx, block) {
if (block->imm_dom)
block->imm_dom->num_dom_children++;
}
nir_foreach_block_unstructured(block, impl) {
bi_foreach_block(ctx, block) {
if (!block->num_dom_children) {
block->dom_children = NULL;
continue;
@@ -143,23 +143,24 @@ calc_dom_children(nir_function_impl *impl)
if (block->num_dom_children <= 3) {
block->dom_children = block->_dom_children_storage;
} else {
block->dom_children = ralloc_array(mem_ctx, nir_block *,
block->num_dom_children);
block->dom_children =
ralloc_array(mem_ctx, bi_block *, block->num_dom_children);
}
block->num_dom_children = 0;
}
nir_foreach_block_unstructured(block, impl) {
bi_foreach_block(ctx, block) {
if (block->imm_dom) {
block->imm_dom->dom_children[block->imm_dom->num_dom_children++] = block;
block->imm_dom->dom_children[block->imm_dom->num_dom_children++] =
block;
}
}
}
static void
calc_dfs_indices(nir_block *block, uint32_t *index)
calc_dfs_indices(bi_block *block, uint32_t *index)
{
/* UINT32_MAX has special meaning. See nir_block_dominates. */
/* UINT32_MAX has special meaning. See bi_block_dominates. */
assert(*index < UINT32_MAX - 2);
block->dom_pre_index = (*index)++;
@@ -171,47 +172,34 @@ calc_dfs_indices(nir_block *block, uint32_t *index)
}
void
nir_calc_dominance_impl(nir_function_impl *impl)
bi_calc_dominance(bi_context *ctx)
{
if (impl->valid_metadata & nir_metadata_dominance)
return;
nir_metadata_require(impl, nir_metadata_block_index);
nir_foreach_block_unstructured(block, impl) {
init_block(block, impl);
bi_foreach_block(ctx, block) {
init_block(block, ctx);
}
bool progress = true;
while (progress) {
progress = false;
nir_foreach_block_unstructured(block, impl) {
if (block != nir_start_block(impl))
bi_foreach_block(ctx, block) {
if (block != bi_entry_block(ctx))
progress |= calc_dominance(block);
}
}
nir_foreach_block_unstructured(block, impl) {
bi_foreach_block(ctx, block) {
calc_dom_frontier(block);
}
nir_block *start_block = nir_start_block(impl);
bi_block *start_block = bi_entry_block(ctx);
start_block->imm_dom = NULL;
calc_dom_children(impl);
calc_dom_children(ctx);
uint32_t dfs_index = 1;
calc_dfs_indices(start_block, &dfs_index);
}
void
nir_calc_dominance(nir_shader *shader)
{
nir_foreach_function_impl(impl, shader) {
nir_calc_dominance_impl(impl);
}
}
/**
* Returns true if parent dominates child according to the following
* definition:
@@ -224,14 +212,8 @@ nir_calc_dominance(nir_shader *shader)
* another unreachable block.
*/
bool
nir_block_dominates(nir_block *parent, nir_block *child)
bi_block_dominates(bi_block *parent, bi_block *child)
{
assert(nir_cf_node_get_function(&parent->cf_node) ==
nir_cf_node_get_function(&child->cf_node));
assert(nir_cf_node_get_function(&parent->cf_node)->valid_metadata &
nir_metadata_dominance);
/* If a block is unreachable, then nir_block::dom_pre_index == UINT32_MAX
* and nir_block::dom_post_index == 0. This allows us to trivially handle
* unreachable blocks here with zero extra work.

View File

@@ -4986,6 +4986,8 @@ create_empty_block(bi_context *ctx)
util_dynarray_init(&blk->predecessors, blk);
_mesa_pointer_set_init(&blk->dom_frontier, ctx);
return blk;
}

View File

@@ -940,6 +940,33 @@ typedef struct bi_block {
/* Flags available for pass-internal use */
uint8_t pass_flags;
/*
* this node's immediate dominator in the dominance tree - set to NULL for
* the start block and any unreachable blocks.
*/
struct bi_block *imm_dom;
/* This node's children in the dominance tree */
unsigned num_dom_children;
struct bi_block **dom_children;
/*
* This is the backing storage for "dom_children" if the array is small
* enough to fit in it, so that we don't have to ralloc the array.
*/
struct bi_block *_dom_children_storage[3];
/* Set of nir_blocks on the dominance frontier of this block */
struct set dom_frontier;
/*
* These two indices have the property that dom_{pre,post}_index for each
* child of this block in the dominance tree will always be between
* dom_pre_index and dom_post_index for this block, which makes testing if
* a given block is dominated by another block an O(1) operation.
*/
uint32_t dom_pre_index, dom_post_index;
} bi_block;
static inline unsigned
@@ -1381,6 +1408,9 @@ bool bi_reconverge_branches(bi_block *block);
bool bi_can_replace_with_csel(bi_instr *I);
void bi_calc_dominance(bi_context *ctx);
bool bi_block_dominates(bi_block *parent, bi_block *child);
void bi_print_instr(const bi_instr *I, FILE *fp);
void bi_print_slots(bi_registers *regs, FILE *fp);
void bi_print_tuple(bi_tuple *tuple, FILE *fp);

View File

@@ -27,6 +27,7 @@ libpanfrost_bifrost_files = files(
'bi_ra_ssa.c',
'bi_spill_ssa.c',
'bi_validate.c',
'bi_dominance.c',
'bir.c',
'bifrost_compile.c',
'bifrost/bi_opt_message_preload.c',