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;
|
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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue