lima/ppir: refactor const lowering
authorVasily Khoruzhick <anarsoul@gmail.com>
Wed, 24 Jul 2019 22:33:47 +0000 (15:33 -0700)
committerVasily Khoruzhick <anarsoul@gmail.com>
Sat, 24 Aug 2019 01:19:46 +0000 (18:19 -0700)
Const nodes are now cloned for each user, i.e. const is guaranteed to have
exactly one successor, so we can use ppir_do_one_node_to_instr() and
drop insert_to_each_succ_instr()

Tested-by: Andreas Baierl <ichgeh@imkreisrum.de>
Reviewed-by: Qiang Yu <yuq825@gmail.com>
Reviewed-by: Erico Nunes <nunes.erico@gmail.com>
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
src/gallium/drivers/lima/ir/pp/instr.c
src/gallium/drivers/lima/ir/pp/lower.c
src/gallium/drivers/lima/ir/pp/nir.c
src/gallium/drivers/lima/ir/pp/node.c
src/gallium/drivers/lima/ir/pp/node_to_instr.c
src/gallium/drivers/lima/ir/pp/ppir.h

index 19cca714fa1c814b0beb8e34c3ac9b0d47a114fa..474f9ca8cab3a463b0583ba3e2d78ba0a3eabd45 100644 (file)
@@ -186,9 +186,18 @@ bool ppir_instr_insert_node(ppir_instr *instr, ppir_node *node)
          uint8_t swizzle[4] = {0};
 
          if (ppir_instr_insert_const(&ic, nc, swizzle)) {
+            ppir_node *succ = ppir_node_first_succ(node);
+            ppir_src *src = NULL;
+            for (int s = 0; s < ppir_node_get_src_num(succ); s++) {
+               src = ppir_node_get_src(succ, s);
+               if (src->node == node)
+                  break;
+            }
+            assert(src->node == node);
+
             instr->constant[i] = ic;
-            ppir_instr_update_src_pipeline(
-               instr, ppir_pipeline_reg_const0 + i, &c->dest, swizzle);
+            ppir_update_src_pipeline(ppir_pipeline_reg_const0 + i, src,
+                                     &c->dest, swizzle);
             break;
          }
       }
index 87b0b25704611cc1d6516112755b6968ccea0261..bededd37acb6b828ba3f9399db9f8e9ca6a6a33d 100644 (file)
@@ -34,41 +34,55 @@ static bool ppir_lower_const(ppir_block *block, ppir_node *node)
       return true;
    }
 
-   ppir_node *move = NULL;
-   ppir_dest *dest = ppir_node_get_dest(node);
+   assert(ppir_node_has_single_succ(node));
 
-   /* const (register) can only be used in alu node, create a move
-    * node for other types of node */
-   ppir_node_foreach_succ_safe(node, dep) {
-      ppir_node *succ = dep->succ;
+   ppir_node *succ = ppir_node_first_succ(node);
+   ppir_src *src = ppir_node_get_src_for_pred(succ, node);
+   ppir_dest *dest = ppir_node_get_dest(node);
+   assert(src != NULL);
+
+   switch (succ->type) {
+   case ppir_node_type_alu:
+   case ppir_node_type_branch:
+      /* ALU and branch can consume consts directly */
+      dest->type = src->type = ppir_target_pipeline;
+      /* Reg will be updated in node_to_instr later */
+      dest->pipeline = src->pipeline = ppir_pipeline_reg_const0;
+      return true;
+   default:
+      /* Create a move for everyone else */
+      break;
+   }
 
-      if (succ->type != ppir_node_type_alu) {
-         if (!move) {
-            move = ppir_node_create(block, ppir_op_mov, -1, 0);
-            if (unlikely(!move))
-               return false;
+   ppir_node *move = ppir_node_create(block, ppir_op_mov, -1, 0);
+   if (unlikely(!move))
+      return false;
 
-            ppir_debug("lower const create move %d for %d\n",
-                       move->index, node->index);
+   ppir_debug("lower const create move %d for %d\n",
+              move->index, node->index);
 
-            ppir_alu_node *alu = ppir_node_to_alu(move);
-            alu->dest = *dest;
-            alu->num_src = 1;
-            ppir_node_target_assign(alu->src, node);
-            for (int i = 0; i < 4; i++)
-               alu->src->swizzle[i] = i;
-         }
+   ppir_alu_node *alu = ppir_node_to_alu(move);
+   alu->dest = *dest;
+   alu->num_src = 1;
+   ppir_node_target_assign(alu->src, node);
+   for (int s = 0; s < 4; s++)
+      alu->src->swizzle[s] = s;
 
-         ppir_node_replace_pred(dep, move);
-         ppir_node_replace_child(succ, node, move);
-      }
+   ppir_node_foreach_succ_safe(node, dep) {
+      ppir_node_replace_pred(dep, move);
+      ppir_node_replace_child(succ, node, move);
    }
 
-   if (move) {
-      ppir_node_add_dep(move, node);
-      list_addtail(&move->list, &node->list);
-   }
+   /* Need to be careful with changing src/dst type here:
+    * it has to be done *after* successors have their children
+    * replaced, otherwise ppir_node_replace_child() won't find
+    * matching src/dst and as result won't work
+    */
+   alu->src->type = dest->type = ppir_target_pipeline;
+   alu->src->pipeline = dest->pipeline = ppir_pipeline_reg_const0;
 
+   ppir_node_add_dep(move, node);
+   list_addtail(&move->list, &node->list);
    return true;
 }
 
@@ -287,11 +301,10 @@ static bool ppir_lower_branch(ppir_block *block, ppir_node *node)
    if (!zero)
       return false;
 
-   list_addtail(&zero->node.list, &node->list);
-
    zero->constant.value[0].f = 0;
    zero->constant.num = 1;
-   zero->dest.type = ppir_target_ssa;
+   zero->dest.type = ppir_target_pipeline;
+   zero->dest.pipeline = ppir_pipeline_reg_const0;
    zero->dest.ssa.num_components = 1;
    zero->dest.ssa.live_in = INT_MAX;
    zero->dest.ssa.live_out = 0;
@@ -302,13 +315,13 @@ static bool ppir_lower_branch(ppir_block *block, ppir_node *node)
     * comparision node into branch itself and use current
     * way as a fallback for complex conditions.
     */
-   branch->src[1].type = ppir_target_ssa;
-   branch->src[1].ssa = &zero->dest.ssa;
+   ppir_node_target_assign(&branch->src[1], &zero->node);
 
    branch->cond_gt = true;
    branch->cond_lt = true;
 
    ppir_node_add_dep(&branch->node, &zero->node);
+   list_addtail(&zero->node.list, &node->list);
 
    return true;
 }
@@ -340,6 +353,5 @@ bool ppir_lower_prog(ppir_compiler *comp)
       }
    }
 
-   ppir_node_print_prog(comp);
    return true;
 }
index b20a701afc4ab15733c3dc7239765a3a4bdd99a7..3c0ff7dd93b5f73b6ad344821b9a8ef65c5d0e7c 100644 (file)
@@ -100,6 +100,10 @@ static void ppir_node_add_src(ppir_compiler *comp, ppir_node *node,
 
    if (ns->is_ssa) {
       child = comp->var_nodes[ns->ssa->index];
+      /* Clone consts for each successor */
+      if (child->type == ppir_node_type_const)
+         child = ppir_node_clone_const(node->block, child);
+
       ppir_node_add_dep(node, child);
    }
    else {
@@ -624,6 +628,8 @@ bool ppir_compile_nir(struct lima_fs_shader_state *prog, struct nir_shader *nir,
    if (!ppir_lower_prog(comp))
       goto err_out0;
 
+   ppir_node_print_prog(comp);
+
    if (!ppir_node_to_instr(comp))
       goto err_out0;
 
index a121e87a5a903fcb8ff5a79c83945b6004572b09..15479150448d311f681c1b075c010c5f8c8ec24d 100644 (file)
@@ -571,3 +571,26 @@ void ppir_node_print_prog(ppir_compiler *comp)
    }
    printf("====================\n");
 }
+
+ppir_node *ppir_node_clone_const(ppir_block *block, ppir_node *node)
+{
+   ppir_const_node *cnode = ppir_node_to_const(node);
+   ppir_const_node *new_cnode = ppir_node_create(block, ppir_op_const, -1, 0);
+
+   if (!new_cnode)
+      return NULL;
+
+   list_addtail(&new_cnode->node.list, &block->node_list);
+
+   new_cnode->constant.num = cnode->constant.num;
+   for (int i = 0; i < cnode->constant.num; i++) {
+      new_cnode->constant.value[i] = cnode->constant.value[i];
+   }
+   new_cnode->dest.type = ppir_target_ssa;
+   new_cnode->dest.ssa.num_components = cnode->dest.ssa.num_components;
+   new_cnode->dest.ssa.live_in = INT_MAX;
+   new_cnode->dest.ssa.live_out = 0;
+   new_cnode->dest.write_mask = cnode->dest.write_mask;
+
+   return &new_cnode->node;
+}
index 919a2a3b38fa31daef783966c8b9d108bec00bba..d1ceb2c67b6b828340cd8e9975de12462df1e4d9 100644 (file)
@@ -37,97 +37,6 @@ static bool create_new_instr(ppir_block *block, ppir_node *node)
    return true;
 }
 
-static bool insert_to_each_succ_instr(ppir_block *block, ppir_node *node)
-{
-   ppir_dest *dest = ppir_node_get_dest(node);
-   assert(dest->type == ppir_target_ssa);
-
-   ppir_node *move = NULL;
-
-   ppir_node_foreach_succ_safe(node, dep) {
-      ppir_node *succ = dep->succ;
-      assert(succ->type == ppir_node_type_alu ||
-             succ->type == ppir_node_type_branch);
-
-      if (!ppir_instr_insert_node(succ->instr, node)) {
-         /* create a move node to insert for failed node */
-         if (!move) {
-            move = ppir_node_create(block, ppir_op_mov, -1, 0);
-            if (unlikely(!move))
-               return false;
-
-            ppir_debug("node_to_instr create move %d for %d\n",
-                       move->index, node->index);
-
-            ppir_alu_node *alu = ppir_node_to_alu(move);
-            alu->dest = *dest;
-            alu->num_src = 1;
-            ppir_node_target_assign(alu->src, node);
-            for (int i = 0; i < 4; i++)
-               alu->src->swizzle[i] = i;
-         }
-
-         ppir_node_replace_pred(dep, move);
-         ppir_node_replace_child(succ, node, move);
-      }
-   }
-
-   if (move) {
-      if (!create_new_instr(block, move))
-         return false;
-
-      ASSERTED bool insert_result =
-         ppir_instr_insert_node(move->instr, node);
-      assert(insert_result);
-
-      ppir_node_add_dep(move, node);
-      list_addtail(&move->list, &node->list);
-   }
-
-   /* dupliacte node for each successor */
-
-   bool first = true;
-   struct list_head dup_list;
-   list_inithead(&dup_list);
-
-   ppir_node_foreach_succ_safe(node, dep) {
-      ppir_node *succ = dep->succ;
-
-      if (first) {
-         first = false;
-         node->instr = succ->instr;
-         continue;
-      }
-
-      if (succ->instr == node->instr)
-         continue;
-
-      list_for_each_entry(ppir_node, dup, &dup_list, list) {
-         if (succ->instr == dup->instr) {
-            ppir_node_replace_pred(dep, dup);
-            continue;
-         }
-      }
-
-      ppir_node *dup = ppir_node_create(block, node->op, -1, 0);
-      if (unlikely(!dup))
-         return false;
-      list_addtail(&dup->list, &dup_list);
-
-      ppir_debug("node_to_instr duplicate %s %d from %d\n",
-                 ppir_op_infos[dup->op].name, dup->index, node->index);
-
-      ppir_instr *instr = succ->instr;
-      dup->instr = instr;
-      dup->instr_pos = node->instr_pos;
-      ppir_node_replace_pred(dep, dup);
-   }
-
-   list_splicetail(&dup_list, &node->list);
-
-   return true;
-}
-
 /*
  * If a node has a pipeline dest, schedule it in the same instruction as its
  * successor.
@@ -199,8 +108,8 @@ static bool ppir_do_one_node_to_instr(ppir_block *block, ppir_node *node, ppir_n
          return false;
       break;
    case ppir_node_type_const:
-      if (!insert_to_each_succ_instr(block, node))
-         return false;
+      /* Const nodes are supposed to go through do_node_to_instr_pipeline() */
+      assert(false);
       break;
    case ppir_node_type_store:
    {
index 420ccd4a0f406b59ff75600b315aeaffaf4224f4..3c21b6c8f294bc9cc50a153cd264b18a94e47b40 100644 (file)
@@ -363,6 +363,7 @@ void ppir_node_print_prog(ppir_compiler *comp);
 void ppir_node_replace_child(ppir_node *parent, ppir_node *old_child, ppir_node *new_child);
 void ppir_node_replace_all_succ(ppir_node *dst, ppir_node *src);
 void ppir_node_replace_pred(ppir_dep *dep, ppir_node *new_pred);
+ppir_node *ppir_node_clone_const(ppir_block *block, ppir_node *node);
 
 static inline bool ppir_node_is_root(ppir_node *node)
 {
@@ -468,6 +469,17 @@ static inline ppir_src *ppir_node_get_src(ppir_node *node, int idx)
    return NULL;
 }
 
+static inline ppir_src *ppir_node_get_src_for_pred(ppir_node *node, ppir_node *pred)
+{
+   for (int i = 0; i < ppir_node_get_src_num(node); i++) {
+      ppir_src *src = ppir_node_get_src(node, i);
+      if (src && src->node == pred)
+         return src;
+   }
+
+   return NULL;
+}
+
 static inline void ppir_node_target_assign(ppir_src *src, ppir_node *node)
 {
    ppir_dest *dest = ppir_node_get_dest(node);