<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 16, 2014 at 10:58 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"><div class="HOEnZb"><div class="h5">On Tue, Dec 16, 2014 at 1:04 AM, Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>> wrote:<br>
> ---<br>
>  src/glsl/Makefile.sources    |  1 +<br>
>  src/glsl/nir/nir.c           | 19 +++++++---------<br>
>  src/glsl/nir/nir.h           | 21 ++++++++++++++++--<br>
>  src/glsl/nir/nir_dominance.c |  6 ++---<br>
>  src/glsl/nir/nir_metadata.c  | 52 ++++++++++++++++++++++++++++++++++++++++++++<br>
>  5 files changed, 82 insertions(+), 17 deletions(-)<br>
>  create mode 100644 src/glsl/nir/nir_metadata.c<br>
><br>
> diff --git a/src/glsl/Makefile.sources b/src/glsl/Makefile.sources<br>
> index d3b17bd..4eb6320 100644<br>
> --- a/src/glsl/Makefile.sources<br>
> +++ b/src/glsl/Makefile.sources<br>
> @@ -25,6 +25,7 @@ NIR_FILES = \<br>
>         $(GLSL_SRCDIR)/nir/nir_lower_system_values.c \<br>
>         $(GLSL_SRCDIR)/nir/nir_lower_variables_scalar.c \<br>
>         $(GLSL_SRCDIR)/nir/nir_lower_vec_to_movs.c \<br>
> +       $(GLSL_SRCDIR)/nir/nir_metadata.c \<br>
>         $(GLSL_SRCDIR)/nir/nir_opcodes.c \<br>
>         $(GLSL_SRCDIR)/nir/nir_opcodes.h \<br>
>         $(GLSL_SRCDIR)/nir/nir_opt_copy_propagate.c \<br>
> diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c<br>
> index 3dd9e5a..0124799 100644<br>
> --- a/src/glsl/nir/nir.c<br>
> +++ b/src/glsl/nir/nir.c<br>
> @@ -106,6 +106,7 @@ nir_function_create(nir_shader *shader, const char *name)<br>
>     exec_list_push_tail(&shader->functions, &func->node);<br>
>     exec_list_make_empty(&func->overload_list);<br>
>     func->name = name;<br>
> +   func->shader = shader;<br>
><br>
>     return func;<br>
>  }<br>
> @@ -243,8 +244,7 @@ nir_function_impl_create(nir_function_overload *overload)<br>
>     impl->return_var = NULL;<br>
>     impl->reg_alloc = 0;<br>
>     impl->ssa_alloc = 0;<br>
> -   impl->block_index_dirty = true;<br>
> -   impl->dominance_dirty = true;<br>
> +   impl->valid_metadata = nir_metadata_none;<br>
><br>
>     /* create start & end blocks */<br>
>     nir_block *start_block = nir_block_create(mem_ctx);<br>
> @@ -815,7 +815,7 @@ handle_jump(nir_block *block)<br>
>     unlink_block_successors(block);<br>
><br>
>     nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node);<br>
> -   impl->dominance_dirty = true;<br>
> +   nir_metadata_dirty(impl, nir_metadata_none);<br>
><br>
>     if (jump_instr->type == nir_jump_break ||<br>
>         jump_instr->type == nir_jump_continue) {<br>
> @@ -912,7 +912,7 @@ handle_remove_jump(nir_block *block, nir_jump_type type)<br>
>     }<br>
><br>
>     nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node);<br>
> -   impl->dominance_dirty = true;<br>
> +   nir_metadata_dirty(impl, nir_metadata_none);<br>
>  }<br>
><br>
>  /**<br>
> @@ -1019,8 +1019,7 @@ nir_cf_node_insert_after(nir_cf_node *node, nir_cf_node *after)<br>
>     }<br>
><br>
>     nir_function_impl *impl = nir_cf_node_get_function(node);<br>
> -   impl->block_index_dirty = true;<br>
> -   impl->dominance_dirty = true;<br>
> +   nir_metadata_dirty(impl, nir_metadata_none);<br>
>  }<br>
><br>
>  void<br>
> @@ -1062,8 +1061,7 @@ nir_cf_node_insert_before(nir_cf_node *node, nir_cf_node *before)<br>
>     }<br>
><br>
>     nir_function_impl *impl = nir_cf_node_get_function(node);<br>
> -   impl->block_index_dirty = true;<br>
> -   impl->dominance_dirty = true;<br>
> +   nir_metadata_dirty(impl, nir_metadata_none);<br>
>  }<br>
><br>
>  void<br>
> @@ -1109,7 +1107,7 @@ void<br>
>  nir_cf_node_remove(nir_cf_node *node)<br>
>  {<br>
>     nir_function_impl *impl = nir_cf_node_get_function(node);<br>
> -   impl->block_index_dirty = true;<br>
> +   nir_metadata_dirty(impl, nir_metadata_none);<br>
><br>
>     if (node->type == nir_cf_node_block) {<br>
>        /*<br>
> @@ -1673,13 +1671,12 @@ nir_index_blocks(nir_function_impl *impl)<br>
>  {<br>
>     unsigned index = 0;<br>
><br>
> -   if (!impl->block_index_dirty)<br>
> +   if (impl->valid_metadata & nir_metadata_block_index)<br>
>        return;<br>
><br>
>     nir_foreach_block(impl, index_block, &index);<br>
><br>
>     impl->num_blocks = index;<br>
> -   impl->block_index_dirty = false;<br>
>  }<br>
><br>
>  static void<br>
> diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h<br>
> index c9146c0..8d5f6b8 100644<br>
> --- a/src/glsl/nir/nir.h<br>
> +++ b/src/glsl/nir/nir.h<br>
> @@ -33,6 +33,7 @@<br>
>  #include "GL/gl.h" /* GLenum */<br>
>  #include "util/ralloc.h"<br>
>  #include "main/mtypes.h"<br>
> +#include "main/bitset.h"<br>
>  #include "nir_types.h"<br>
>  #include <stdio.h><br>
><br>
> @@ -45,6 +46,7 @@ extern "C" {<br>
><br>
>  struct nir_function_overload;<br>
>  struct nir_function;<br>
> +struct nir_shader;<br>
><br>
><br>
>  /**<br>
> @@ -1037,6 +1039,16 @@ typedef struct {<br>
>  #define nir_loop_last_cf_node(loop) \<br>
>     exec_node_data(nir_cf_node, exec_list_get_tail(&(loop)->body), node)<br>
><br>
> +/**<br>
> + * Various bits of metadata that can may be created or required by<br>
> + * optimization and analysis passes<br>
> + */<br>
> +typedef enum {<br>
> +   nir_metadata_none = 0x0,<br>
> +   nir_metadata_block_index = 0x1,<br>
> +   nir_metadata_dominance = 0x2,<br>
> +} nir_metadata;<br>
<br>
</div></div>Bikeshed: I'm a little concerned here about using an enum to represent<br>
a bit flag. An enum is supposed to represent a value that can equal<br>
one of several things, but this isn't what's going on here. I think<br>
that more pedantic compilers like Clang (and perhaps GCC with<br>
-Wpedantic) might even generate warnings, since things like:<br>
<br>
nir_metadata_block_index | nir_metadata_dominance<br>
<br>
are technically undefined as per the C spec because the resulting<br>
value isn't an element of the enum IIRC (I'm too lazy to verify this,<br>
though). So overall it seems pretty sketchy, and you don't get most of<br>
the good things that come with enums like better type safety anyways<br>
since you're masking together values like they're integers.<br></blockquote><div><br></div><div>In ANSI C, enums are just integers with the guarantee that it has enough bits to hold the biggest value.  You can OR them, add them, or even multiply if you wish.  I don't know that this is allowed in C++ and *maybe* it's changed in C99 or C11, but it is allowed in ANSI C.  Having them be enums also has the nice little benefit that they generate debug symbols and GDB is smart enough to look for bitfield combinations and show you "nir_metadata_block_index | nir_metadata_dominance" which is pretty nifty...<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Also, this is inconsistent with the NIR intrinsic info bitfield, which<br>
uses #define's for the reasons outlined above. So if you have a strong<br>
argument why we should use an enum here, then we should change that to<br>
use an enum too.<br>
<div><div class="h5"><br>
> +<br>
>  typedef struct {<br>
>     nir_cf_node cf_node;<br>
><br>
> @@ -1069,8 +1081,7 @@ typedef struct {<br>
>     /* total number of basic blocks, only valid when block_index_dirty = false */<br>
>     unsigned num_blocks;<br>
><br>
> -   bool block_index_dirty;<br>
> -   bool dominance_dirty;<br>
> +   nir_metadata valid_metadata;<br>
>  } nir_function_impl;<br>
><br>
>  #define nir_cf_node_next(_node) \<br>
> @@ -1126,6 +1137,7 @@ typedef struct nir_function {<br>
><br>
>     struct exec_list overload_list;<br>
>     const char *name;<br>
> +   struct nir_shader *shader;<br>
>  } nir_function;<br>
><br>
>  #define nir_function_first_overload(func) \<br>
> @@ -1209,6 +1221,11 @@ void nir_cf_node_insert_end(struct exec_list *list, nir_cf_node *node);<br>
>  /** removes a control flow node, doing any cleanup necessary */<br>
>  void nir_cf_node_remove(nir_cf_node *node);<br>
><br>
> +/** requests that the given pieces of metadata be generated */<br>
> +void nir_metadata_require(nir_function_impl *impl, nir_metadata required);<br>
> +/** dirties all but the preserved metadata */<br>
> +void nir_metadata_dirty(nir_function_impl *impl, nir_metadata preserved);<br>
> +<br>
>  /** creates an instruction with default swizzle/writemask/etc. with NULL registers */<br>
>  nir_alu_instr *nir_alu_instr_create(void *mem_ctx, nir_op op);<br>
><br>
> diff --git a/src/glsl/nir/nir_dominance.c b/src/glsl/nir/nir_dominance.c<br>
> index 988a3fc..7684784 100644<br>
> --- a/src/glsl/nir/nir_dominance.c<br>
> +++ b/src/glsl/nir/nir_dominance.c<br>
> @@ -181,10 +181,10 @@ calc_dom_children(nir_function_impl* impl)<br>
>  void<br>
>  nir_calc_dominance_impl(nir_function_impl *impl)<br>
>  {<br>
> -   if (!impl->dominance_dirty)<br>
> +   if (impl->valid_metadata & nir_metadata_dominance)<br>
>        return;<br>
><br>
> -   nir_index_blocks(impl);<br>
> +   nir_metadata_require(impl, nir_metadata_block_index);<br>
><br>
>     dom_state state;<br>
>     state.impl = impl;<br>
> @@ -202,8 +202,6 @@ nir_calc_dominance_impl(nir_function_impl *impl)<br>
>     impl->start_block->imm_dom = NULL;<br>
><br>
>     calc_dom_children(impl);<br>
> -<br>
> -   impl->dominance_dirty = false;<br>
>  }<br>
><br>
>  void<br>
> diff --git a/src/glsl/nir/nir_metadata.c b/src/glsl/nir/nir_metadata.c<br>
> new file mode 100644<br>
> index 0000000..070cb74<br>
> --- /dev/null<br>
> +++ b/src/glsl/nir/nir_metadata.c<br>
> @@ -0,0 +1,52 @@<br>
> +/*<br>
> + * Copyright © 2014 Intel Corporation<br>
> + *<br>
> + * Permission is hereby granted, free of charge, to any person obtaining a<br>
> + * copy of this software and associated documentation files (the "Software"),<br>
> + * to deal in the Software without restriction, including without limitation<br>
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
> + * and/or sell copies of the Software, and to permit persons to whom the<br>
> + * Software is furnished to do so, subject to the following conditions:<br>
> + *<br>
> + * The above copyright notice and this permission notice (including the next<br>
> + * paragraph) shall be included in all copies or substantial portions of the<br>
> + * Software.<br>
> + *<br>
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br>
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING<br>
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS<br>
> + * IN THE SOFTWARE.<br>
> + *<br>
> + * Authors:<br>
> + *    Jason Ekstrand (<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>)<br>
> + */<br>
> +<br>
> +#include "nir.h"<br>
> +<br>
> +/*<br>
> + * Handles management of the metadata.<br>
> + */<br>
> +<br>
> +void<br>
> +nir_metadata_require(nir_function_impl *impl, nir_metadata required)<br>
> +{<br>
> +#define NEEDS_UPDATE(X) ((required & ~impl->valid_metadata) & (X))<br>
> +<br>
> +   if (NEEDS_UPDATE(nir_metadata_block_index))<br>
> +      nir_index_blocks(impl);<br>
> +   if (NEEDS_UPDATE(nir_metadata_dominance))<br>
> +      nir_calc_dominance_impl(impl);<br>
> +<br>
> +#undef NEEDS_UPDATE<br>
> +<br>
> +   impl->valid_metadata |= required;<br>
> +}<br>
> +<br>
> +void<br>
> +nir_metadata_dirty(nir_function_impl *impl, nir_metadata preserved)<br>
> +{<br>
> +   impl->valid_metadata &= preserved;<br>
> +}<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>