lima/ppir: improve handling for successors in other blocks

ppir doesn't register successors in other blocks, and causes
ppir_node_has_single_succ to be unreliable as it might return true for
nodes with successors in other blocks.
This is bad for optimization passes that try to pipeline registers or
avoid insertion of movs, as that can generally only be done for nodes
with a single user.
As of now, ppir can't just start adding successors in other blocks as
that breaks the scheduling code.
So this patch is a little hacky but enables pipelining optimizations
during lowering. It can hopefully be removed during future scheduler
rework.

Signed-off-by: Erico Nunes <nunes.erico@gmail.com>
Reviewed-by: Vasily Khoruzhick <anarsoul@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4975>
This commit is contained in:
Erico Nunes 2020-05-10 16:08:13 +02:00
parent 96c1d5f629
commit 92611e21c1
3 changed files with 12 additions and 8 deletions

View file

@ -198,7 +198,7 @@ static bool ppir_lower_texture(ppir_block *block, ppir_node *node)
load_tex->src[0].pipeline = load->dest.pipeline = ppir_pipeline_reg_discard;
/* Always create move node since there can be successors in other blocks */
ppir_node *move = ppir_node_insert_mov_all_blocks(node);
ppir_node *move = ppir_node_insert_mov(node);
if (unlikely(!move))
return false;

View file

@ -388,8 +388,10 @@ void ppir_node_add_dep(ppir_node *succ, ppir_node *pred,
ppir_dep_type type)
{
/* don't add dep for two nodes from different block */
if (succ->block != pred->block)
if (succ->block != pred->block) {
pred->succ_different_block = true;
return;
}
/* don't add duplicated dep */
ppir_node_foreach_pred(succ, dep) {
@ -597,7 +599,7 @@ void ppir_node_print_prog(ppir_compiler *comp)
printf("====================\n");
}
ppir_node *ppir_node_insert_mov(ppir_node *node)
static ppir_node *ppir_node_insert_mov_local(ppir_node *node)
{
ppir_node *move = ppir_node_create(node->block, ppir_op_mov, -1, 0);
if (unlikely(!move))
@ -624,9 +626,9 @@ ppir_node *ppir_node_insert_mov(ppir_node *node)
return move;
}
ppir_node *ppir_node_insert_mov_all_blocks(ppir_node *old)
ppir_node *ppir_node_insert_mov(ppir_node *old)
{
ppir_node *move = ppir_node_insert_mov(old);
ppir_node *move = ppir_node_insert_mov_local(old);
ppir_compiler *comp = old->block->comp;
list_for_each_entry(ppir_block, block, &comp->block_list, list) {
@ -645,9 +647,10 @@ ppir_node *ppir_node_insert_mov_all_blocks(ppir_node *old)
return move;
}
bool ppir_node_has_single_src_succ(ppir_node *node)
{
if (list_is_singular(&node->succ_list) &&
if (ppir_node_has_single_succ(node) &&
list_first_entry(&node->succ_list,
ppir_dep, succ_link)->type == ppir_dep_src)
return true;

View file

@ -161,6 +161,7 @@ typedef struct ppir_node {
int instr_pos;
struct ppir_block *block;
bool is_end;
bool succ_different_block;
/* for scheduler */
struct list_head succ_list;
@ -414,7 +415,6 @@ void ppir_node_replace_pred(ppir_dep *dep, ppir_node *new_pred);
ppir_dep *ppir_dep_for_pred(ppir_node *node, ppir_node *pred);
/* Assumes that node successors are in the same block */
ppir_node *ppir_node_insert_mov(ppir_node *node);
ppir_node *ppir_node_insert_mov_all_blocks(ppir_node *node);
static inline bool ppir_node_is_root(ppir_node *node)
{
@ -428,7 +428,8 @@ static inline bool ppir_node_is_leaf(ppir_node *node)
static inline bool ppir_node_has_single_succ(ppir_node *node)
{
return list_is_singular(&node->succ_list);
return list_is_singular(&node->succ_list)
&& !node->succ_different_block;
}
bool ppir_node_has_single_src_succ(ppir_node *node);