lima/ppir: simplify load uni/temp op lowering and scheduling
authorErico Nunes <nunes.erico@gmail.com>
Sun, 21 Jul 2019 23:27:11 +0000 (01:27 +0200)
committerErico Nunes <nunes.erico@gmail.com>
Sun, 4 Aug 2019 11:38:19 +0000 (13:38 +0200)
The load uniform/temporary operations output only to a pipeline
register, which must be consumed by another op in the same instruction
later.
The current implementation delays the decision of who will consume this
result to until the scheduling step. If the consumer node is not able to
use the pipeline register, a mov node may have to be created, during the
scheduler step.

As part of the ppir scheduler simplification, and now that the ppir
scheduler supports pipeline register dependencies, this can be
simplified by always creating a single mov node outputting to a normal
register that can be used directly by all consumers.

Signed-off-by: Erico Nunes <nunes.erico@gmail.com>
Reviewed-by: Vasily Khoruzhick <anarsoul@gmail.com>
Reviewed-by: Qiang Yu <yuq825@gmail.com>
src/gallium/drivers/lima/ir/pp/lower.c
src/gallium/drivers/lima/ir/pp/node_to_instr.c

index 97837f4c19814f73a8a40aa62bfe90cd9f03b8ab..2244fc7dc3138802d89c290852a6371ce2ad31c2 100644 (file)
@@ -87,6 +87,33 @@ static bool ppir_lower_swap_args(ppir_block *block, ppir_node *node)
    return true;
 }
 
+static bool ppir_lower_load(ppir_block *block, ppir_node *node)
+{
+   ppir_node *move = ppir_node_create(block, ppir_op_mov, -1 , 0);
+   if (unlikely(!move))
+      return false;
+
+   ppir_alu_node *alu = ppir_node_to_alu(move);
+
+   ppir_dest *dest = ppir_node_get_dest(node);
+   alu->dest = *dest;
+
+   ppir_node_replace_all_succ(move, node);
+
+   dest->type = ppir_target_pipeline;
+   dest->pipeline = ppir_pipeline_reg_uniform;
+
+   alu->num_src = 1;
+   ppir_node_target_assign(&alu->src[0], dest);
+   for (int i = 0; i < 4; i++)
+      alu->src->swizzle[i] = i;
+
+   ppir_node_add_dep(move, node);
+   list_addtail(&move->list, &node->list);
+
+   return true;
+}
+
 static bool ppir_lower_texture(ppir_block *block, ppir_node *node)
 {
    ppir_load_texture_node *load_tex = ppir_node_to_load_texture(node);
@@ -336,6 +363,8 @@ static bool (*ppir_lower_funcs[ppir_op_num])(ppir_block *, ppir_node *) = {
    [ppir_op_trunc] = ppir_lower_trunc,
    [ppir_op_sat] = ppir_lower_sat,
    [ppir_op_branch] = ppir_lower_branch,
+   [ppir_op_load_uniform] = ppir_lower_load,
+   [ppir_op_load_temp] = ppir_lower_load,
 };
 
 bool ppir_lower_prog(ppir_compiler *comp)
index 711fe2153b41e3cdb81dce3a677a66e25aed514f..f4b3114852f6da1b995750b840431fdbac826d83 100644 (file)
@@ -121,15 +121,6 @@ static bool insert_to_each_succ_instr(ppir_block *block, ppir_node *node)
       dup->instr = instr;
       dup->instr_pos = node->instr_pos;
       ppir_node_replace_pred(dep, dup);
-
-      if ((node->op == ppir_op_load_uniform) || (node->op == ppir_op_load_temp)) {
-         ppir_load_node *load = ppir_node_to_load(node);
-         ppir_load_node *dup_load = ppir_node_to_load(dup);
-         dup_load->dest = load->dest;
-         dup_load->index = load->index;
-         dup_load->num_components = load->num_components;
-         instr->slots[node->instr_pos] = dup;
-      }
    }
 
    list_splicetail(&dup_list, &node->list);
@@ -190,31 +181,10 @@ static bool ppir_do_one_node_to_instr(ppir_block *block, ppir_node *node, ppir_n
       break;
    }
    case ppir_node_type_load:
-      if ((node->op == ppir_op_load_uniform) || (node->op == ppir_op_load_temp)) {
-         /* merge pred load_uniform into succ instr can save a reg
-          * by using pipeline reg */
-         if (!insert_to_each_succ_instr(block, node))
-            return false;
-
-         ppir_load_node *load = ppir_node_to_load(node);
-         load->dest.type = ppir_target_pipeline;
-         load->dest.pipeline = ppir_pipeline_reg_uniform;
-      }
-      else if (node->op == ppir_op_load_temp) {
-         /* merge pred load_temp into succ instr can save a reg
-          * by using pipeline reg */
-         if (!insert_to_each_succ_instr(block, node))
-            return false;
-
-         ppir_load_node *load = ppir_node_to_load(node);
-         load->dest.type = ppir_target_pipeline;
-         load->dest.pipeline = ppir_pipeline_reg_uniform;
-      }
-      else if (node->op == ppir_op_load_varying ||
-               node->op == ppir_op_load_fragcoord ||
-               node->op == ppir_op_load_pointcoord ||
-               node->op == ppir_op_load_frontface) {
-         /* delay the load varying dup to scheduler */
+      if (node->op == ppir_op_load_varying ||
+          node->op == ppir_op_load_fragcoord ||
+          node->op == ppir_op_load_pointcoord ||
+          node->op == ppir_op_load_frontface) {
          if (!create_new_instr(block, node))
             return false;
       }