From 92611e21c19b35d1e5c9091614b2659d789558e2 Mon Sep 17 00:00:00 2001 From: Erico Nunes Date: Sun, 10 May 2020 16:08:13 +0200 Subject: [PATCH] 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 Reviewed-by: Vasily Khoruzhick Part-of: --- src/gallium/drivers/lima/ir/pp/lower.c | 2 +- src/gallium/drivers/lima/ir/pp/node.c | 13 ++++++++----- src/gallium/drivers/lima/ir/pp/ppir.h | 5 +++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/lima/ir/pp/lower.c b/src/gallium/drivers/lima/ir/pp/lower.c index 6a088c3328d..3434debe15c 100644 --- a/src/gallium/drivers/lima/ir/pp/lower.c +++ b/src/gallium/drivers/lima/ir/pp/lower.c @@ -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; diff --git a/src/gallium/drivers/lima/ir/pp/node.c b/src/gallium/drivers/lima/ir/pp/node.c index d0e97616f3e..b85ca6bad18 100644 --- a/src/gallium/drivers/lima/ir/pp/node.c +++ b/src/gallium/drivers/lima/ir/pp/node.c @@ -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; diff --git a/src/gallium/drivers/lima/ir/pp/ppir.h b/src/gallium/drivers/lima/ir/pp/ppir.h index 821107302d7..775e77ab983 100644 --- a/src/gallium/drivers/lima/ir/pp/ppir.h +++ b/src/gallium/drivers/lima/ir/pp/ppir.h @@ -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); -- 2.30.2