lima/ppir: improve handling for successors in other blocks
authorErico Nunes <nunes.erico@gmail.com>
Sun, 10 May 2020 14:08:13 +0000 (16:08 +0200)
committerErico Nunes <nunes.erico@gmail.com>
Sat, 16 May 2020 15:23:58 +0000 (17:23 +0200)
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>

src/gallium/drivers/lima/ir/pp/lower.c
src/gallium/drivers/lima/ir/pp/node.c
src/gallium/drivers/lima/ir/pp/ppir.h

index 6a088c3328d93038d21830ff0fca61e5c769d575..3434debe15cb0acf644536cc3ed9edef2fdb945f 100644 (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;
 
index d0e97616f3e39f17a277773aee03ff38aaad394a..b85ca6bad18eb32882b606072a036bd81d2981c5 100644 (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;
index 821107302d71fd99ea76c2460cbf4e1c46d18013..775e77ab983aeb36f053aa91b7d0de37e26a6a82 100644 (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);