nir: Add a parallel copy instruction type
authorJason Ekstrand <jason.ekstrand@intel.com>
Fri, 31 Oct 2014 04:04:15 +0000 (21:04 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Thu, 15 Jan 2015 15:19:00 +0000 (07:19 -0800)
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
src/glsl/nir/nir.c
src/glsl/nir/nir.h
src/glsl/nir/nir_print.c

index 4100f97..b64ec40 100644 (file)
@@ -481,6 +481,18 @@ nir_phi_instr_create(void *mem_ctx)
    return instr;
 }
 
+nir_parallel_copy_instr *
+nir_parallel_copy_instr_create(void *mem_ctx)
+{
+   nir_parallel_copy_instr *instr = ralloc(mem_ctx, nir_parallel_copy_instr);
+   instr_init(&instr->instr, nir_instr_type_parallel_copy);
+
+   instr->at_end = false;
+   exec_list_make_empty(&instr->copies);
+
+   return instr;
+}
+
 nir_ssa_undef_instr *
 nir_ssa_undef_instr_create(void *mem_ctx)
 {
@@ -1383,6 +1395,18 @@ visit_phi_dest(nir_phi_instr *instr, nir_foreach_dest_cb cb, void *state)
    return cb(&instr->dest, state);
 }
 
+static bool
+visit_parallel_copy_dest(nir_parallel_copy_instr *instr,
+                         nir_foreach_dest_cb cb, void *state)
+{
+   foreach_list_typed(nir_parallel_copy_copy, copy, node, &instr->copies) {
+      if (!cb(&copy->dest, state))
+         return false;
+   }
+
+   return true;
+}
+
 bool
 nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state)
 {
@@ -1397,7 +1421,9 @@ nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state)
       return visit_load_const_dest(nir_instr_as_load_const(instr), cb, state);
    case nir_instr_type_phi:
       return visit_phi_dest(nir_instr_as_phi(instr), cb, state);
-      break;
+   case nir_instr_type_parallel_copy:
+      return visit_parallel_copy_dest(nir_instr_as_parallel_copy(instr),
+                                      cb, state);
 
    case nir_instr_type_ssa_undef:
    case nir_instr_type_call:
@@ -1532,6 +1558,18 @@ visit_phi_src(nir_phi_instr *instr, nir_foreach_src_cb cb, void *state)
    return true;
 }
 
+static bool
+visit_parallel_copy_src(nir_parallel_copy_instr *instr,
+                        nir_foreach_src_cb cb, void *state)
+{
+   foreach_list_typed(nir_parallel_copy_copy, copy, node, &instr->copies) {
+      if (!visit_src(&copy->src, cb, state))
+         return false;
+   }
+
+   return true;
+}
+
 typedef struct {
    void *state;
    nir_foreach_src_cb cb;
@@ -1576,6 +1614,11 @@ nir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state)
       if (!visit_phi_src(nir_instr_as_phi(instr), cb, state))
          return false;
       break;
+   case nir_instr_type_parallel_copy:
+      if (!visit_parallel_copy_src(nir_instr_as_parallel_copy(instr),
+                                   cb, state))
+         return false;
+      break;
    case nir_instr_type_jump:
    case nir_instr_type_ssa_undef:
       return true;
index 5933b5d..6c1f668 100644 (file)
@@ -396,6 +396,7 @@ typedef enum {
    nir_instr_type_jump,
    nir_instr_type_ssa_undef,
    nir_instr_type_phi,
+   nir_instr_type_parallel_copy,
 } nir_instr_type;
 
 typedef struct {
@@ -933,6 +934,24 @@ typedef struct {
    nir_dest dest;
 } nir_phi_instr;
 
+typedef struct {
+   struct exec_node node;
+   nir_src src;
+   nir_dest dest;
+} nir_parallel_copy_copy;
+
+typedef struct {
+   nir_instr instr;
+
+   /* Indicates that this is the parallel copy at the end of the block.
+    * When isolating phi nodes, we create 2 parallel copies in most blocks;
+    * this flag helps tell them apart.
+    */
+   bool at_end;
+
+   struct exec_list copies;
+} nir_parallel_copy_instr;
+
 #define nir_instr_as_alu(_instr) exec_node_data(nir_alu_instr, _instr, instr)
 #define nir_instr_as_call(_instr) exec_node_data(nir_call_instr, _instr, instr)
 #define nir_instr_as_jump(_instr) exec_node_data(nir_jump_instr, _instr, instr)
@@ -946,6 +965,8 @@ typedef struct {
    exec_node_data(nir_ssa_undef_instr, _instr, instr)
 #define nir_instr_as_phi(_instr) \
    exec_node_data(nir_phi_instr, _instr, instr)
+#define nir_instr_as_parallel_copy(_instr) \
+   exec_node_data(nir_parallel_copy_instr, _instr, instr)
 
 
 /*
@@ -1251,6 +1272,8 @@ nir_tex_instr *nir_tex_instr_create(void *mem_ctx, unsigned num_srcs);
 
 nir_phi_instr *nir_phi_instr_create(void *mem_ctx);
 
+nir_parallel_copy_instr *nir_parallel_copy_instr_create(void *mem_ctx);
+
 nir_ssa_undef_instr *nir_ssa_undef_instr_create(void *mem_ctx);
 
 nir_deref_var *nir_deref_var_create(void *mem_ctx, nir_variable *var);
index 6f2a2da..335eaaf 100644 (file)
@@ -606,6 +606,23 @@ print_phi_instr(nir_phi_instr *instr, FILE *fp)
 }
 
 static void
+print_parallel_copy_instr(nir_parallel_copy_instr *instr, FILE *fp)
+{
+   bool first = true;
+   fprintf(fp, "pcopy: ");
+   foreach_list_typed(nir_parallel_copy_copy, copy, node, &instr->copies) {
+      if (!first)
+         fprintf(fp, "; ");
+
+      print_dest(&copy->dest, fp);
+      fprintf(fp, " = ");
+      print_src(&copy->src, fp);
+
+      first = false;
+   }
+}
+
+static void
 print_instr(nir_instr *instr, print_var_state *state, unsigned tabs, FILE *fp)
 {
    print_tabs(tabs, fp);
@@ -643,6 +660,10 @@ print_instr(nir_instr *instr, print_var_state *state, unsigned tabs, FILE *fp)
       print_phi_instr(nir_instr_as_phi(instr), fp);
       break;
 
+   case nir_instr_type_parallel_copy:
+      print_parallel_copy_instr(nir_instr_as_parallel_copy(instr), fp);
+      break;
+
    default:
       unreachable("Invalid instruction type");
       break;