ir3: add some preamble helpers

Helpers to check for preamble existence, find shpe, and create an empty
preamble.

Signed-off-by: Job Noorman <jnoorman@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31222>
This commit is contained in:
Job Noorman 2025-01-22 15:33:48 +01:00 committed by Marge Bot
parent 144121b6df
commit f3026b3d3e
2 changed files with 99 additions and 0 deletions

View file

@ -586,6 +586,94 @@ ir3_block_get_last_phi(struct ir3_block *block)
return last_phi; return last_phi;
} }
struct ir3_instruction *
ir3_find_shpe(struct ir3 *ir)
{
if (!ir3_has_preamble(ir)) {
return NULL;
}
foreach_block (block, &ir->block_list) {
struct ir3_instruction *last = ir3_block_get_last_non_terminator(block);
if (last && last->opc == OPC_SHPE) {
return last;
}
}
unreachable("preamble without shpe");
}
struct ir3_instruction *
ir3_create_empty_preamble(struct ir3 *ir)
{
assert(!ir3_has_preamble(ir));
struct ir3_block *main_start_block = ir3_start_block(ir);
/* Create a preamble CFG similar to what the frontend would generate. Note
* that the empty else_block is important for ir3_after_preamble to work.
*
* shps_block:
* if (shps) {
* getone_block:
* if (getone) {
* body_block:
* shpe
* }
* } else {
* else_block:
* }
* main_start_block:
*/
struct ir3_block *shps_block = ir3_block_create(ir);
struct ir3_block *getone_block = ir3_block_create(ir);
struct ir3_block *body_block = ir3_block_create(ir);
struct ir3_block *else_block = ir3_block_create(ir);
list_add(&else_block->node, &ir->block_list);
list_add(&body_block->node, &ir->block_list);
list_add(&getone_block->node, &ir->block_list);
list_add(&shps_block->node, &ir->block_list);
struct ir3_builder b = ir3_builder_at(ir3_after_block(shps_block));
ir3_SHPS(&b);
shps_block->successors[0] = getone_block;
ir3_block_add_predecessor(getone_block, shps_block);
ir3_block_link_physical(shps_block, getone_block);
shps_block->successors[1] = else_block;
ir3_block_add_predecessor(else_block, shps_block);
ir3_block_link_physical(shps_block, else_block);
b.cursor = ir3_after_block(getone_block);
ir3_GETONE(&b);
getone_block->divergent_condition = true;
getone_block->successors[0] = body_block;
ir3_block_add_predecessor(body_block, getone_block);
ir3_block_link_physical(getone_block, body_block);
getone_block->successors[1] = main_start_block;
ir3_block_add_predecessor(main_start_block, getone_block);
ir3_block_link_physical(getone_block, main_start_block);
b.cursor = ir3_after_block(body_block);
struct ir3_instruction *shpe = ir3_SHPE(&b);
shpe->barrier_class = shpe->barrier_conflict = IR3_BARRIER_CONST_W;
array_insert(body_block, body_block->keeps, shpe);
ir3_JUMP(&b);
body_block->successors[0] = main_start_block;
ir3_block_add_predecessor(main_start_block, body_block);
ir3_block_link_physical(body_block, main_start_block);
b.cursor = ir3_after_block(else_block);
ir3_JUMP(&b);
else_block->successors[0] = main_start_block;
ir3_block_add_predecessor(main_start_block, else_block);
ir3_block_link_physical(else_block, main_start_block);
main_start_block->reconvergence_point = true;
return shpe;
}
void void
ir3_block_add_predecessor(struct ir3_block *block, struct ir3_block *pred) ir3_block_add_predecessor(struct ir3_block *block, struct ir3_block *pred)
{ {

View file

@ -811,6 +811,17 @@ ir3_after_preamble(struct ir3 *ir)
return block; return block;
} }
static inline bool
ir3_has_preamble(struct ir3 *ir)
{
return ir3_start_block(ir) != ir3_after_preamble(ir);
}
struct ir3_instruction *ir3_find_shpe(struct ir3 *ir);
/* Create an empty preamble and return shpe. */
struct ir3_instruction *ir3_create_empty_preamble(struct ir3 *ir);
void ir3_block_add_predecessor(struct ir3_block *block, struct ir3_block *pred); void ir3_block_add_predecessor(struct ir3_block *block, struct ir3_block *pred);
void ir3_block_link_physical(struct ir3_block *pred, struct ir3_block *succ); void ir3_block_link_physical(struct ir3_block *pred, struct ir3_block *succ);
void ir3_block_remove_predecessor(struct ir3_block *block, void ir3_block_remove_predecessor(struct ir3_block *block,