<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Dec 17, 2014 at 5:30 PM, Connor Abbott <span dir="ltr"><<a href="mailto:cwabbott0@gmail.com" target="_blank">cwabbott0@gmail.com</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Tue, Dec 16, 2014 at 1:05 AM, Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>> wrote:<br>
> ---<br>
>  src/glsl/nir/nir_from_ssa.c              | 40 ++++++++++++++++++++-----<br>
>  src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 50 +++++++++++++++++++++-----------<br>
>  2 files changed, 65 insertions(+), 25 deletions(-)<br>
><br>
> diff --git a/src/glsl/nir/nir_from_ssa.c b/src/glsl/nir/nir_from_ssa.c<br>
> index 62a54fe..9311bda 100644<br>
<br>
</span>It would be nice if you could squash all the following nir_from_ssa.c<br>
changes into "nir: Add a better out-of-ssa pass", since nir_from_ssa.c<br>
already has some stuff about special-casing SSA constants so this is<br>
rather confusing.<br></blockquote><div><br></div><div>Certainly, this could be split into two patches:  The first one makes i965 ssa-const safe, and the second doesn't lower load_const SSA values.  However, for the sake of the history, I'd like to keep it seperate from from_ssa.  Also, load_const is never mentioned in nir_from_ssa before this patch, so I'm not sure what you mean by "already have special-casing".<br></div><div>--Jason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="h5"><br>
> --- a/src/glsl/nir/nir_from_ssa.c<br>
> +++ b/src/glsl/nir/nir_from_ssa.c<br>
> @@ -469,6 +469,12 @@ get_register_for_ssa_def(nir_ssa_def *def, struct from_ssa_state *state)<br>
>     if (entry) {<br>
>        return (nir_register *)entry->data;<br>
>     } else {<br>
> +      /* We leave load_const SSA values alone.  They act as immediates to<br>
> +       * the backend.  If it got coalesced into a phi, that's ok.<br>
> +       */<br>
> +      if (def->parent_instr->type == nir_instr_type_load_const)<br>
> +         return NULL;<br>
> +<br>
>        nir_register *reg = nir_local_reg_create(state->impl);<br>
>        reg->name = def->name;<br>
>        reg->num_components = def->num_components;<br>
> @@ -486,12 +492,18 @@ rewrite_ssa_src(nir_src *src, void *void_state)<br>
>     struct from_ssa_state *state = void_state;<br>
><br>
>     if (src->is_ssa) {<br>
> -      /* We don't need to remove it from the uses set because that is going<br>
> -       * away.  We just need to add it to the one for the register. */<br>
>        nir_register *reg = get_register_for_ssa_def(src->ssa, state);<br>
> +<br>
> +      if (reg == NULL) {<br>
> +         assert(src->ssa->parent_instr->type == nir_instr_type_load_const);<br>
> +         return true;<br>
> +      }<br>
> +<br>
>        memset(src, 0, sizeof *src);<br>
>        src->reg.reg = reg;<br>
><br>
> +      /* We don't need to remove it from the uses set because that is going<br>
> +       * away.  We just need to add it to the one for the register. */<br>
>        _mesa_set_add(reg->uses, _mesa_hash_pointer(state->instr), state->instr);<br>
>     }<br>
><br>
> @@ -504,10 +516,16 @@ rewrite_ssa_dest(nir_dest *dest, void *void_state)<br>
>     struct from_ssa_state *state = void_state;<br>
><br>
>     if (dest->is_ssa) {<br>
> +      nir_register *reg = get_register_for_ssa_def(&dest->ssa, state);<br>
> +<br>
> +      if (reg == NULL) {<br>
> +         assert(dest->ssa.parent_instr->type == nir_instr_type_load_const);<br>
> +         return true;<br>
> +      }<br>
> +<br>
>        _mesa_set_destroy(dest->ssa.uses, NULL);<br>
>        _mesa_set_destroy(dest->ssa.if_uses, NULL);<br>
><br>
> -      nir_register *reg = get_register_for_ssa_def(&dest->ssa, state);<br>
>        memset(dest, 0, sizeof *dest);<br>
>        dest->reg.reg = reg;<br>
><br>
> @@ -534,7 +552,6 @@ resolve_registers_block(nir_block *block, void *void_state)<br>
>            instr->type == nir_instr_type_phi) {<br>
>           nir_instr_remove(instr);<br>
>           ralloc_steal(state->dead_ctx, instr);<br>
> -         continue;<br>
>        }<br>
>     }<br>
>     state->instr = NULL;<br>
> @@ -543,11 +560,18 @@ resolve_registers_block(nir_block *block, void *void_state)<br>
>     if (following_if && following_if->condition.is_ssa) {<br>
>        nir_register *reg = get_register_for_ssa_def(following_if->condition.ssa,<br>
>                                                     state);<br>
> -      memset(&following_if->condition, 0, sizeof following_if->condition);<br>
> -      following_if->condition.reg.reg = reg;<br>
> +      if (reg) {<br>
> +         memset(&following_if->condition, 0, sizeof following_if->condition);<br>
> +         following_if->condition.reg.reg = reg;<br>
><br>
> -      _mesa_set_add(reg->if_uses, _mesa_hash_pointer(following_if),<br>
> -                    following_if);<br>
> +         _mesa_set_add(reg->if_uses, _mesa_hash_pointer(following_if),<br>
> +                       following_if);<br>
> +      } else {<br>
> +         /* FIXME: We really shouldn't hit this.  We should be doing<br>
> +          * constant control flow propagation.<br>
> +          */<br>
> +         assert(following_if->condition.ssa->parent_instr->type == nir_instr_type_load_const);<br>
> +      }<br>
>     }<br>
><br>
>     return true;<br>
> diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
> index 3ec2fa6..019d649 100644<br>
> --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
> +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
> @@ -981,25 +981,37 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)<br>
>  fs_reg<br>
>  fs_visitor::get_nir_src(nir_src src)<br>
>  {<br>
> -   fs_reg reg;<br>
> -   if (src.reg.reg->is_global)<br>
> -      reg = nir_globals[src.reg.reg->index];<br>
> -   else<br>
> -      reg = nir_locals[src.reg.reg->index];<br>
> +   if (src.is_ssa) {<br>
> +      assert(src.ssa->parent_instr->type == nir_instr_type_load_const);<br>
> +      nir_load_const_instr *load = nir_instr_as_load_const(src.ssa->parent_instr);<br>
> +      fs_reg reg(GRF, virtual_grf_alloc(src.ssa->num_components),<br>
> +                 BRW_REGISTER_TYPE_D);<br>
><br>
> -   /* to avoid floating-point denorm flushing problems, set the type by<br>
> -    * default to D - instructions that need floating point semantics will set<br>
> -    * this to F if they need to<br>
> -    */<br>
> -   reg.type = BRW_REGISTER_TYPE_D;<br>
> -   reg.reg_offset = src.reg.base_offset;<br>
> -   if (src.reg.indirect) {<br>
> -      reg.reladdr = new(mem_ctx) fs_reg();<br>
> -      *reg.reladdr = retype(get_nir_src(*src.reg.indirect),<br>
> -                            BRW_REGISTER_TYPE_D);<br>
> -   }<br>
> +      for (unsigned i = 0; i < src.ssa->num_components; ++i)<br>
> +         emit(MOV(offset(reg, i), fs_reg(load->value.i[i])));<br>
><br>
> -   return reg;<br>
> +      return reg;<br>
> +   } else {<br>
> +      fs_reg reg;<br>
> +      if (src.reg.reg->is_global)<br>
> +         reg = nir_globals[src.reg.reg->index];<br>
> +      else<br>
> +         reg = nir_locals[src.reg.reg->index];<br>
> +<br>
> +      /* to avoid floating-point denorm flushing problems, set the type by<br>
> +       * default to D - instructions that need floating point semantics will set<br>
> +       * this to F if they need to<br>
> +       */<br>
> +      reg.type = BRW_REGISTER_TYPE_D;<br>
> +      reg.reg_offset = src.reg.base_offset;<br>
> +      if (src.reg.indirect) {<br>
> +         reg.reladdr = new(mem_ctx) fs_reg();<br>
> +         *reg.reladdr = retype(get_nir_src(*src.reg.indirect),<br>
> +                               BRW_REGISTER_TYPE_D);<br>
> +      }<br>
> +<br>
> +      return reg;<br>
> +   }<br>
>  }<br>
><br>
>  fs_reg<br>
> @@ -1652,6 +1664,10 @@ fs_visitor::nir_emit_texture(nir_tex_instr *instr)<br>
>  void<br>
>  fs_visitor::nir_emit_load_const(nir_load_const_instr *instr)<br>
>  {<br>
> +   /* Bail on SSA constant loads.  These are used for immediates. */<br>
> +   if (instr->dest.is_ssa)<br>
> +      return;<br>
> +<br>
>     fs_reg dest = get_nir_dest(instr->dest);<br>
>     dest.type = BRW_REGISTER_TYPE_UD;<br>
>     if (instr->array_elems == 0) {<br>
> --<br>
> 2.2.0<br>
><br>
</div></div>> _______________________________________________<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>
</blockquote></div></div></div>