<div dir="ltr">Except for the minor stale comment and assuming you checked that we don't call nir_create_local_reg() anymore,<div><br></div><div>Reviewed-by: Connor Abbott <<a href="mailto:cwabbott0@gmail.com">cwabbott0@gmail.com</a>><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 16, 2014 at 1:11 AM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">With this commit, the GLSL IR -> NIR pass generates NIR in more-or-less SSA<br>
form.  It's SSA in the sense that it doesn't have any registers, but it<br>
isn't really useful SSA because it still has a pile of load/store<br>
intrinsics that we will need to get rid of.<br>
---<br>
 src/glsl/nir/glsl_to_nir.cpp | 246 ++++++++++++++++++++-----------------------<br>
 1 file changed, 117 insertions(+), 129 deletions(-)<br>
<br>
diff --git a/src/glsl/nir/glsl_to_nir.cpp b/src/glsl/nir/glsl_to_nir.cpp<br>
index 6870bd2..f85b50e 100644<br>
--- a/src/glsl/nir/glsl_to_nir.cpp<br>
+++ b/src/glsl/nir/glsl_to_nir.cpp<br>
@@ -618,15 +618,13 @@ nir_visitor::visit(ir_call *ir)<br>
          assert(0);<br>
       }<br>
<br>
-      nir_register *reg = nir_local_reg_create(impl);<br>
-      reg->num_components = 1;<br>
-<br>
       nir_intrinsic_instr *instr = nir_intrinsic_instr_create(shader, op);<br>
       ir_dereference *param =<br>
          (ir_dereference *) ir->actual_parameters.get_head();<br>
       param->accept(this);<br>
       instr->variables[0] = this->deref_head;<br>
-      instr->dest.reg.reg = reg;<br>
+      instr->dest.is_ssa = true;<br>
+      nir_ssa_def_init(&instr->instr, &instr->dest.ssa, 1, NULL);<br>
<br>
       nir_instr_insert_after_cf_list(this->cf_node_list, &instr->instr);<br>
<br>
@@ -635,7 +633,8 @@ nir_visitor::visit(ir_call *ir)<br>
<br>
       ir->return_deref->accept(this);<br>
       store_instr->variables[0] = this->deref_head;<br>
-      store_instr->src[0].reg.reg = reg;<br>
+      store_instr->src[0].is_ssa = true;<br>
+      store_instr->src[0].ssa = &instr->dest.ssa;<br>
<br>
       nir_instr_insert_after_cf_list(this->cf_node_list, &store_instr->instr);<br>
<br>
@@ -665,121 +664,124 @@ nir_visitor::visit(ir_call *ir)<br>
 void<br>
 nir_visitor::visit(ir_assignment *ir)<br>
 {<br>
-   if (ir->write_mask != (1 << ir->lhs->type->vector_elements) - 1 &&<br>
-       ir->write_mask != 0) {<br>
+   unsigned num_components = ir->lhs->type->vector_elements;<br>
+<br>
+   if ((ir->rhs->as_dereference() || ir->rhs->as_constant()) &&<br>
+       (ir->write_mask == (1 << num_components) - 1 || ir->write_mask == 0)) {<br>
+      /* We're doing a plane-as-can-be copy, so emit a copy_var */<br></blockquote><div><br></div><div>plain-as-can-be</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      nir_intrinsic_instr *copy =<br>
+         nir_intrinsic_instr_create(this->shader, nir_intrinsic_copy_var);<br>
+<br>
+      ir->lhs->accept(this);<br>
+      copy->variables[0] = this->deref_head;<br>
+<br>
+      ir->rhs->accept(this);<br>
+      copy->variables[1] = this->deref_head;<br>
+<br>
+<br>
+      if (ir->condition) {<br>
+         nir_if *if_stmt = nir_if_create(this->shader);<br>
+         if_stmt->condition = evaluate_rvalue(ir->condition);<br>
+         nir_cf_node_insert_end(this->cf_node_list, &if_stmt->cf_node);<br>
+         nir_instr_insert_after_cf_list(&if_stmt->then_list, &copy->instr);<br>
+      } else {<br>
+         nir_instr_insert_after_cf_list(this->cf_node_list, &copy->instr);<br>
+      }<br>
+      return;<br>
+   }<br>
+<br>
+   assert(ir->rhs->type->is_scalar() || ir->rhs->type->is_vector());<br>
+<br>
+   ir->lhs->accept(this);<br>
+   nir_deref_var *lhs_deref = this->deref_head;<br>
+   nir_src src = evaluate_rvalue(ir->rhs);<br>
+<br>
+   if (ir->write_mask != (1 << num_components) - 1 && ir->write_mask != 0) {<br>
       /*<br>
        * We have no good way to update only part of a variable, so just load<br>
-       * the LHS into a register, do a writemasked move, and then store it<br>
+       * the LHS and do a vec operation to combine the old with the new, and<br>
+       * then store it<br>
        * back into the LHS. Copy propagation should get rid of the mess.<br>
        */<br>
<br>
-      ir->lhs->accept(this);<br>
-      nir_deref_var *lhs_deref = this->deref_head;<br>
-      nir_register *reg = nir_local_reg_create(this->impl);<br>
-      reg->num_components = ir->lhs->type->vector_elements;<br>
-<br>
-      nir_intrinsic_op op;<br>
+      nir_intrinsic_op load_op;<br>
       switch (ir->lhs->type->vector_elements) {<br>
-         case 1: op = nir_intrinsic_load_var_vec1; break;<br>
-         case 2: op = nir_intrinsic_load_var_vec2; break;<br>
-         case 3: op = nir_intrinsic_load_var_vec3; break;<br>
-         case 4: op = nir_intrinsic_load_var_vec4; break;<br>
-         default: assert(0); break;<br>
+         case 1: load_op = nir_intrinsic_load_var_vec1; break;<br>
+         case 2: load_op = nir_intrinsic_load_var_vec2; break;<br>
+         case 3: load_op = nir_intrinsic_load_var_vec3; break;<br>
+         case 4: load_op = nir_intrinsic_load_var_vec4; break;<br>
+         default: unreachable("Invalid number of components"); break;<br>
       }<br>
<br>
-      nir_intrinsic_instr *load = nir_intrinsic_instr_create(this->shader, op);<br>
-      load->dest.reg.reg = reg;<br>
+      nir_intrinsic_instr *load = nir_intrinsic_instr_create(this->shader,<br>
+                                                             load_op);<br>
+      load->dest.is_ssa = true;<br>
+      nir_ssa_def_init(&load->instr, &load->dest.ssa,<br>
+                       num_components, NULL);<br>
       load->variables[0] = lhs_deref;<br>
       nir_instr_insert_after_cf_list(this->cf_node_list, &load->instr);<br>
<br>
-      nir_alu_instr *move =<br>
-         nir_alu_instr_create(this->shader,<br>
-                              supports_ints ? nir_op_fmov : nir_op_imov);<br>
-      move->dest.dest.reg.reg = reg;<br>
-      move->dest.write_mask = ir->write_mask;<br>
-      move->src[0].src = evaluate_rvalue(ir->rhs);<br>
-<br>
-      /*<br>
-       * GLSL IR will give us the input to the write-masked assignment in a<br>
-       * single packed vector, whereas we expect each input component to be in<br>
-       * the same channel as the writemask. So, for example, if the writemask<br>
-       * is xzw, then we have to swizzle x -> x, y -> z, and z -> w.<br>
+      nir_op vec_op;<br>
+      switch (ir->lhs->type->vector_elements) {<br>
+         case 1: vec_op = nir_op_imov; break;<br>
+         case 2: vec_op = nir_op_vec2; break;<br>
+         case 3: vec_op = nir_op_vec3; break;<br>
+         case 4: vec_op = nir_op_vec4; break;<br>
+         default: unreachable("Invalid number of components"); break;<br>
+      }<br>
+      nir_alu_instr *vec = nir_alu_instr_create(this->shader, vec_op);<br>
+      vec->dest.dest.is_ssa = true;<br>
+      nir_ssa_def_init(&vec->instr, &vec->dest.dest.ssa,<br>
+                       num_components, NULL);<br>
+      vec->dest.write_mask = (1 << num_components) - 1;<br>
+<br>
+      /* GLSL IR will give us the input to the write-masked assignment<br>
+       * in a single packed vector, whereas we expect each input<br>
+       * component to be in the same channel as the writemask. So, for<br>
+       * example, if the writemask is xzw, then we have to swizzle x -><br>
+       * x, y -> z, and z -> w.<br>
        */<br></blockquote><div><br></div><div>This comment is stale now, since we have to do the unpacking for a different reason (we're interleaving the old and the new vectors).</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
-<br>
       unsigned component = 0;<br>
-      for (unsigned i = 0; i < 4; i++) {<br>
-         if ((ir->write_mask >> i) & 1) {<br>
-            move->src[0].swizzle[i] = component++;<br>
+      for (unsigned i = 0; i < ir->lhs->type->vector_elements; i++) {<br>
+         if (ir->write_mask & (1 << i)) {<br>
+            vec->src[i].src = src;<br>
+            vec->src[i].swizzle[0] = component++;<br>
          } else {<br>
-            move->src[0].swizzle[i] = 0;<br>
+            vec->src[i].src.is_ssa = true;<br>
+            vec->src[i].src.ssa = &load->dest.ssa;<br>
+            vec->src[i].swizzle[0] = i;<br>
          }<br>
       }<br>
<br>
-      if (ir->condition != NULL) {<br>
-         move->has_predicate = true;<br>
-         move->predicate = evaluate_rvalue(ir->condition);<br>
-      }<br>
-<br>
-      nir_instr_insert_after_cf_list(this->cf_node_list, &move->instr);<br>
+      nir_instr_insert_after_cf_list(this->cf_node_list, &vec->instr);<br>
<br>
-      switch (ir->lhs->type->vector_elements) {<br>
-         case 1: op = nir_intrinsic_store_var_vec1; break;<br>
-         case 2: op = nir_intrinsic_store_var_vec2; break;<br>
-         case 3: op = nir_intrinsic_store_var_vec3; break;<br>
-         case 4: op = nir_intrinsic_store_var_vec4; break;<br>
-         default: assert(0); break;<br>
-      }<br>
-<br>
-      nir_intrinsic_instr *store = nir_intrinsic_instr_create(this->shader, op);<br>
-      nir_deref *store_deref = nir_copy_deref(this->shader, &lhs_deref->deref);<br>
-      store->variables[0] = nir_deref_as_var(store_deref);<br>
-      store->src[0].reg.reg = reg;<br>
-      nir_instr_insert_after_cf_list(this->cf_node_list, &store->instr);<br>
-      return;<br>
-   }<br>
-<br>
-   if (ir->rhs->as_dereference() || ir->rhs->as_constant()) {<br>
-      /* we're copying structs or arrays, so emit a copy_var */<br>
-      nir_intrinsic_instr *copy =<br>
-         nir_intrinsic_instr_create(this->shader, nir_intrinsic_copy_var);<br>
-<br>
-      ir->lhs->accept(this);<br>
-      copy->variables[0] = this->deref_head;<br>
-<br>
-      ir->rhs->accept(this);<br>
-      copy->variables[1] = this->deref_head;<br>
-<br>
-      if (ir->condition != NULL) {<br>
-         copy->has_predicate = true;<br>
-         copy->predicate = evaluate_rvalue(ir->condition);<br>
-      }<br>
-      nir_instr_insert_after_cf_list(this->cf_node_list, &copy->instr);<br>
-      return;<br>
+      src.is_ssa = true;<br>
+      src.ssa = &vec->dest.dest.ssa;<br>
    }<br>
<br>
-   assert(ir->rhs->type->is_scalar() || ir->rhs->type->is_vector());<br>
-<br>
-   nir_intrinsic_op op;<br>
+   nir_intrinsic_op store_op;<br>
    switch (ir->lhs->type->vector_elements) {<br>
-      case 1: op = nir_intrinsic_store_var_vec1; break;<br>
-      case 2: op = nir_intrinsic_store_var_vec2; break;<br>
-      case 3: op = nir_intrinsic_store_var_vec3; break;<br>
-      case 4: op = nir_intrinsic_store_var_vec4; break;<br>
-      default: assert(0); break;<br>
+      case 1: store_op = nir_intrinsic_store_var_vec1; break;<br>
+      case 2: store_op = nir_intrinsic_store_var_vec2; break;<br>
+      case 3: store_op = nir_intrinsic_store_var_vec3; break;<br>
+      case 4: store_op = nir_intrinsic_store_var_vec4; break;<br>
+      default: unreachable("Invalid number of components"); break;<br>
    }<br>
<br>
-   nir_intrinsic_instr *store = nir_intrinsic_instr_create(this->shader, op);<br>
-<br>
-   ir->lhs->accept(this);<br>
-   store->variables[0] = this->deref_head;<br>
-   store->src[0] = evaluate_rvalue(ir->rhs);<br>
-<br>
-   if (ir->condition != NULL) {<br>
-      store->has_predicate = true;<br>
-      store->predicate = evaluate_rvalue(ir->condition);<br>
+   nir_intrinsic_instr *store = nir_intrinsic_instr_create(this->shader,<br>
+                                                           store_op);<br>
+   nir_deref *store_deref = nir_copy_deref(this->shader, &lhs_deref->deref);<br>
+   store->variables[0] = nir_deref_as_var(store_deref);<br>
+   store->src[0] = src;<br>
+<br>
+   if (ir->condition) {<br>
+      nir_if *if_stmt = nir_if_create(this->shader);<br>
+      if_stmt->condition = evaluate_rvalue(ir->condition);<br>
+      nir_cf_node_insert_end(this->cf_node_list, &if_stmt->cf_node);<br>
+      nir_instr_insert_after_cf_list(&if_stmt->then_list, &store->instr);<br>
+   } else {<br>
+      nir_instr_insert_after_cf_list(this->cf_node_list, &store->instr);<br>
    }<br>
-<br>
-   nir_instr_insert_after_cf_list(this->cf_node_list, &store->instr);<br>
 }<br>
<br>
 /*<br>
@@ -829,8 +831,8 @@ nir_visitor::add_instr(nir_instr *instr, unsigned num_components)<br>
 {<br>
    nir_dest *dest = get_instr_dest(instr);<br>
<br>
-   dest->reg.reg = nir_local_reg_create(this->impl);<br>
-   dest->reg.reg->num_components = num_components;<br>
+   dest->is_ssa = true;<br>
+   nir_ssa_def_init(instr, &dest->ssa, num_components, NULL);<br>
<br>
    nir_instr_insert_after_cf_list(this->cf_node_list, instr);<br>
    this->result = instr;<br>
@@ -846,43 +848,27 @@ nir_visitor::evaluate_rvalue(ir_rvalue* ir)<br>
        * must emit a variable load.<br>
        */<br>
<br>
-      nir_intrinsic_op op;<br>
+      nir_intrinsic_op load_op;<br>
       switch (ir->type->vector_elements) {<br>
-         case 1:<br>
-            op = nir_intrinsic_load_var_vec1;<br>
-            break;<br>
-         case 2:<br>
-            op = nir_intrinsic_load_var_vec2;<br>
-            break;<br>
-         case 3:<br>
-            op = nir_intrinsic_load_var_vec3;<br>
-            break;<br>
-         case 4:<br>
-            op = nir_intrinsic_load_var_vec4;<br>
-            break;<br>
+      case 1: load_op = nir_intrinsic_load_var_vec1; break;<br>
+      case 2: load_op = nir_intrinsic_load_var_vec2; break;<br>
+      case 3: load_op = nir_intrinsic_load_var_vec3; break;<br>
+      case 4: load_op = nir_intrinsic_load_var_vec4; break;<br>
+      default: unreachable("Invalid number of components");<br>
       }<br>
<br>
       nir_intrinsic_instr *load_instr =<br>
-         nir_intrinsic_instr_create(this->shader, op);<br>
+         nir_intrinsic_instr_create(this->shader, load_op);<br>
       load_instr->variables[0] = this->deref_head;<br>
       add_instr(&load_instr->instr, ir->type->vector_elements);<br>
    }<br>
<br>
-   /*<br>
-    * instr doesn't have a destination right now, give it one and then set up<br>
-    * the source so that it points to it.<br>
-    *<br>
-    * TODO: once we support SSA plumb through a use_ssa boolean and use SSA<br>
-    * here instead of creating a register.<br>
-    */<br>
    nir_dest *dest = get_instr_dest(this->result);<br>
-   assert(dest->reg.reg);<br>
-   nir_src src;<br>
<br>
-   src.is_ssa = false;<br>
-   src.reg.base_offset = 0;<br>
-   src.reg.indirect = NULL;<br>
-   src.reg.reg = dest->reg.reg;<br>
+   assert(dest->is_ssa);<br>
+   nir_src src;<br>
+   src.is_ssa = true;<br>
+   src.ssa = &dest->ssa;<br>
<br>
    return src;<br>
 }<br>
@@ -964,13 +950,15 @@ nir_visitor::visit(ir_expression *ir)<br>
          nir_load_const_instr *const_zero = nir_load_const_instr_create(shader);<br>
          const_zero->num_components = 1;<br>
          const_zero->value.u[0] = 0;<br>
-         const_zero->dest.reg.reg = nir_local_reg_create(this->impl);<br>
-         const_zero->dest.reg.reg->num_components = 1;<br>
+         const_zero->dest.is_ssa = true;<br>
+         nir_ssa_def_init(&const_zero->instr, &const_zero->dest.ssa, 1, NULL);<br>
          nir_instr_insert_after_cf_list(this->cf_node_list, &const_zero->instr);<br>
<br>
          nir_alu_instr *compare = nir_alu_instr_create(shader, nir_op_ine);<br>
-         compare->src[0].src.reg.reg = load->dest.reg.reg;<br>
-         compare->src[1].src.reg.reg = const_zero->dest.reg.reg;<br>
+         compare->src[0].src.is_ssa = true;<br>
+         compare->src[0].src.ssa = &load->dest.ssa;<br>
+         compare->src[1].src.is_ssa = true;<br>
+         compare->src[1].src.ssa = &const_zero->dest.ssa;<br>
          for (unsigned i = 0; i < ir->type->vector_elements; i++)<br>
             compare->src[1].swizzle[i] = 0;<br>
          compare->dest.write_mask = (1 << ir->type->vector_elements) - 1;<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.2.0<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div></div>