mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 22:00:13 +01:00
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:
parent
144121b6df
commit
f3026b3d3e
2 changed files with 99 additions and 0 deletions
|
|
@ -586,6 +586,94 @@ ir3_block_get_last_phi(struct ir3_block *block)
|
|||
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
|
||||
ir3_block_add_predecessor(struct ir3_block *block, struct ir3_block *pred)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -811,6 +811,17 @@ ir3_after_preamble(struct ir3 *ir)
|
|||
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_link_physical(struct ir3_block *pred, struct ir3_block *succ);
|
||||
void ir3_block_remove_predecessor(struct ir3_block *block,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue