[Mesa-dev] [PATCH 11/13] nir/nir: Use a linked list instead of a has set for use/def sets

Jason Ekstrand jason at jlekstrand.net
Thu Apr 30 19:37:44 PDT 2015


On Apr 30, 2015 7:37 PM, "Connor Abbott" <cwabbott0 at gmail.com> wrote:
>
> On Tue, Apr 28, 2015 at 12:03 AM, Jason Ekstrand <jason at jlekstrand.net>
wrote:
> > This commit switches us from the current setup of using hash sets for
> > use/def sets to using linked lists.  Doing so should save us quite a
bit of
> > memory because we aren't carrying around 3 hash sets per register and 2
per
> > SSA value.  It should also save us CPU time because adding/removing
things
> > from use/def sets is 4 pointer manipulations instead of a hash lookup.
> >
> > On the code complexity side of things, some things are now much easier
and
> > others are a bit harder.  One of the operations we perform constantly in
> > optimization passes is to replace one source with another.  Due to the
fact
> > that an instruction can use the same SSA value multiple times, we had to
> > iterate through the sources of the instruction and determine if the use
we
> > were replacing was the only one before removing it from the set of uses.
> > With this patch, uses are per-source not per-instruction so we can just
> > remove it safely.  On the other hand, trying to iterate over all of the
> > instructions that use a given value is more difficult.  Fortunately, the
> > two places we do that are the ffma peephole where it doesn't matter and
GCM
> > where we already gracefully handle duplicates visits to an instruction.
> >
> > Another aspect here is that using linked lists in this way can be
tricky to
> > get right.  With sets, things were quite forgiving and the worst that
> > happened if you didn't properly remove a use was that it would get
caught
> > in the validator.  With linked lists, it can lead to linked list
corruption
> > which can be harder to track.  However, we do just as much validation of
> > the linked lists as we did of the sets so the validator should still
catch
> > these problems.  While working on this series, the vast majority of the
> > bugs I had to fix were caught by assertions.  I don't think the lists
are
> > going to be that much worse than the sets.
> > ---
> >  src/glsl/nir/nir.c          | 228
+++++++++++++++-----------------------------
> >  src/glsl/nir/nir.h          |  45 +++++++--
> >  src/glsl/nir/nir_validate.c | 158 +++++++++++++++---------------
> >  3 files changed, 194 insertions(+), 237 deletions(-)
> >
> > diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c
> > index b8f5dd4..be13c90 100644
> > --- a/src/glsl/nir/nir.c
> > +++ b/src/glsl/nir/nir.c
> > @@ -58,12 +58,9 @@ reg_create(void *mem_ctx, struct exec_list *list)
> >     nir_register *reg = ralloc(mem_ctx, nir_register);
> >
> >     reg->parent_instr = NULL;
> > -   reg->uses = _mesa_set_create(reg, _mesa_hash_pointer,
> > -                                _mesa_key_pointer_equal);
> > -   reg->defs = _mesa_set_create(reg, _mesa_hash_pointer,
> > -                                _mesa_key_pointer_equal);
> > -   reg->if_uses = _mesa_set_create(reg, _mesa_hash_pointer,
> > -                                   _mesa_key_pointer_equal);
> > +   list_inithead(&reg->uses);
> > +   list_inithead(&reg->defs);
> > +   list_inithead(&reg->if_uses);
> >
> >     reg->num_components = 0;
> >     reg->num_array_elems = 0;
> > @@ -1070,11 +1067,14 @@ update_if_uses(nir_cf_node *node)
> >
> >     nir_if *if_stmt = nir_cf_node_as_if(node);
> >
> > -   struct set *if_uses_set = if_stmt->condition.is_ssa ?
> > -                             if_stmt->condition.ssa->if_uses :
> > -                             if_stmt->condition.reg.reg->uses;
> > -
> > -   _mesa_set_add(if_uses_set, if_stmt);
> > +   if_stmt->condition.parent_if = if_stmt;
> > +   if (if_stmt->condition.is_ssa) {
> > +      list_addtail(&if_stmt->condition.use_link,
> > +                   &if_stmt->condition.ssa->if_uses);
> > +   } else {
> > +      list_addtail(&if_stmt->condition.use_link,
> > +                   &if_stmt->condition.reg.reg->if_uses);
> > +   }
> >  }
> >
> >  void
> > @@ -1227,16 +1227,7 @@ cleanup_cf_node(nir_cf_node *node)
> >        foreach_list_typed(nir_cf_node, child, node, &if_stmt->else_list)
> >           cleanup_cf_node(child);
> >
> > -      struct set *if_uses;
> > -      if (if_stmt->condition.is_ssa) {
> > -         if_uses = if_stmt->condition.ssa->if_uses;
> > -      } else {
> > -         if_uses = if_stmt->condition.reg.reg->if_uses;
> > -      }
> > -
> > -      struct set_entry *entry = _mesa_set_search(if_uses, if_stmt);
> > -      assert(entry);
> > -      _mesa_set_remove(if_uses, entry);
> > +      list_del(&if_stmt->condition.use_link);
> >        break;
> >     }
> >
> > @@ -1293,9 +1284,9 @@ add_use_cb(nir_src *src, void *state)
> >  {
> >     nir_instr *instr = state;
> >
> > -   struct set *uses_set = src->is_ssa ? src->ssa->uses :
src->reg.reg->uses;
> > -
> > -   _mesa_set_add(uses_set, instr);
> > +   src->parent_instr = instr;
> > +   list_addtail(&src->use_link,
> > +                src->is_ssa ? &src->ssa->uses : &src->reg.reg->uses);
> >
> >     return true;
> >  }
> > @@ -1320,8 +1311,10 @@ add_reg_def_cb(nir_dest *dest, void *state)
> >  {
> >     nir_instr *instr = state;
> >
> > -   if (!dest->is_ssa)
> > -      _mesa_set_add(dest->reg.reg->defs, instr);
> > +   if (!dest->is_ssa) {
> > +      dest->reg.parent_instr = instr;
> > +      list_addtail(&dest->reg.def_link, &dest->reg.reg->defs);
> > +   }
> >
> >     return true;
> >  }
> > @@ -1436,13 +1429,7 @@ nir_instr_insert_after_cf_list(struct exec_list
*list, nir_instr *after)
> >  static bool
> >  remove_use_cb(nir_src *src, void *state)
> >  {
> > -   nir_instr *instr = state;
> > -
> > -   struct set *uses_set = src->is_ssa ? src->ssa->uses :
src->reg.reg->uses;
> > -
> > -   struct set_entry *entry = _mesa_set_search(uses_set, instr);
> > -   if (entry)
> > -      _mesa_set_remove(uses_set, entry);
> > +   list_del(&src->use_link);
> >
> >     return true;
> >  }
> > @@ -1450,16 +1437,8 @@ remove_use_cb(nir_src *src, void *state)
> >  static bool
> >  remove_def_cb(nir_dest *dest, void *state)
> >  {
> > -   nir_instr *instr = state;
> > -
> > -   if (dest->is_ssa)
> > -      return true;
> > -
> > -   nir_register *reg = dest->reg.reg;
> > -
> > -   struct set_entry *entry = _mesa_set_search(reg->defs, instr);
> > -   if (entry)
> > -      _mesa_set_remove(reg->defs, entry);
> > +   if (!dest->is_ssa)
> > +      list_del(&dest->reg.def_link);
> >
> >     return true;
> >  }
> > @@ -1834,86 +1813,65 @@ nir_srcs_equal(nir_src src1, nir_src src2)
> >  }
> >
> >  static bool
> > -src_does_not_use_def(nir_src *src, void *void_def)
> > +src_is_valid(const nir_src *src)
> >  {
> > -   nir_ssa_def *def = void_def;
> > -
> > -   if (src->is_ssa) {
> > -      return src->ssa != def;
> > -   } else {
> > -      return true;
> > -   }
> > +   return src->is_ssa ? (src->ssa != NULL) : (src->reg.reg != NULL);
> >  }
> >
> > -static bool
> > -src_does_not_use_reg(nir_src *src, void *void_reg)
> > +static void
> > +src_remove_all_uses(nir_src *src)
> >  {
> > -   nir_register *reg = void_reg;
> > +   for (; src; src = src->is_ssa ? NULL : src->reg.indirect) {
> > +      if (!src_is_valid(src))
> > +         continue;
> >
> > -   if (src->is_ssa) {
> > -      return true;
> > -   } else {
> > -      return src->reg.reg != reg;
> > +      list_del(&src->use_link);
> >     }
> >  }
> >
> > -void
> > -nir_instr_rewrite_src(nir_instr *instr, nir_src *src, nir_src new_src)
> > -{
> > -   nir_src old_src = *src;
> > -   *src = new_src;
> > -
> > -   for (nir_src *iter_src = &old_src; iter_src;
> > -        iter_src = iter_src->is_ssa ? NULL : iter_src->reg.indirect) {
> > -      if (iter_src->is_ssa) {
> > -         nir_ssa_def *ssa = iter_src->ssa;
> > -         if (ssa && nir_foreach_src(instr, src_does_not_use_def, ssa))
{
> > -            struct set_entry *entry = _mesa_set_search(ssa->uses,
instr);
> > -            assert(entry);
> > -            _mesa_set_remove(ssa->uses, entry);
> > -         }
> > +static void
> > +src_add_all_uses(nir_src *src, nir_instr *parent_instr, nir_if
*parent_if)
> > +{
> > +   for (; src; src = src->is_ssa ? NULL : src->reg.indirect) {
> > +      if (!src_is_valid(src))
> > +         continue;
> > +
> > +      if (parent_instr) {
> > +         src->parent_instr = parent_instr;
> > +         if (src->is_ssa)
> > +            list_addtail(&src->use_link, &src->ssa->uses);
> > +         else
> > +            list_addtail(&src->use_link, &src->reg.reg->uses);
> >        } else {
> > -         nir_register *reg = iter_src->reg.reg;
> > -         if (reg && nir_foreach_src(instr, src_does_not_use_reg, reg))
{
> > -            struct set_entry *entry = _mesa_set_search(reg->uses,
instr);
> > -            assert(entry);
> > -            _mesa_set_remove(reg->uses, entry);
> > -         }
> > +         assert(parent_if);
> > +         src->parent_if = parent_if;
> > +         if (src->is_ssa)
> > +            list_addtail(&src->use_link, &src->ssa->if_uses);
> > +         else
> > +            list_addtail(&src->use_link, &src->reg.reg->if_uses);
> >        }
> >     }
> > +}
> >
> > -   for (nir_src *iter_src = &new_src; iter_src;
> > -        iter_src = iter_src->is_ssa ? NULL : iter_src->reg.indirect) {
> > -      if (iter_src->is_ssa) {
> > -         if (iter_src->ssa)
> > -            _mesa_set_add(iter_src->ssa->uses, instr);
> > -      } else {
> > -         if (iter_src->reg.reg)
> > -            _mesa_set_add(iter_src->reg.reg->uses, instr);
> > -      }
> > -   }
> > +void
> > +nir_instr_rewrite_src(nir_instr *instr, nir_src *src, nir_src new_src)
> > +{
> > +   assert(!src_is_valid(src) || src->parent_instr == instr);
> > +
> > +   src_remove_all_uses(src);
> > +   *src = new_src;
> > +   src_add_all_uses(src, instr, NULL);
> >  }
> >
> >  void
> >  nir_if_rewrite_condition(nir_if *if_stmt, nir_src new_src)
> >  {
> > -   for (nir_src *src = &if_stmt->condition; src;
> > -        src = src->is_ssa ? NULL : src->reg.indirect) {
> > -      struct set *uses = src->is_ssa ? src->ssa->if_uses
> > -                                     : src->reg.reg->if_uses;
> > -      struct set_entry *entry = _mesa_set_search(uses, if_stmt);
> > -      assert(entry);
> > -      _mesa_set_remove(uses, entry);
> > -   }
> > -
> > -   if_stmt->condition = new_src;
> > +   nir_src *src = &if_stmt->condition;
> > +   assert(!src_is_valid(src) || src->parent_if == if_stmt);
> >
> > -   for (nir_src *src = &if_stmt->condition; src;
> > -        src = src->is_ssa ? NULL : src->reg.indirect) {
> > -      struct set *uses = src->is_ssa ? src->ssa->if_uses
> > -                                     : src->reg.reg->if_uses;
> > -      _mesa_set_add(uses, if_stmt);
> > -   }
> > +   src_remove_all_uses(src);
> > +   *src = new_src;
> > +   src_add_all_uses(src, NULL, if_stmt);
> >  }
> >
> >  void
> > @@ -1922,10 +1880,8 @@ nir_ssa_def_init(nir_instr *instr, nir_ssa_def
*def,
> >  {
> >     def->name = name;
> >     def->parent_instr = instr;
> > -   def->uses = _mesa_set_create(instr, _mesa_hash_pointer,
> > -                                _mesa_key_pointer_equal);
> > -   def->if_uses = _mesa_set_create(instr, _mesa_hash_pointer,
> > -                                   _mesa_key_pointer_equal);
> > +   list_inithead(&def->uses);
> > +   list_inithead(&def->if_uses);
> >     def->num_components = num_components;
> >
> >     if (instr->block) {
> > @@ -1946,57 +1902,23 @@ nir_ssa_dest_init(nir_instr *instr, nir_dest
*dest,
> >     nir_ssa_def_init(instr, &dest->ssa, num_components, name);
> >  }
> >
> > -struct ssa_def_rewrite_state {
> > -   void *mem_ctx;
> > -   nir_ssa_def *old;
> > -   nir_src new_src;
> > -};
> > -
> > -static bool
> > -ssa_def_rewrite_uses_src(nir_src *src, void *void_state)
> > -{
> > -   struct ssa_def_rewrite_state *state = void_state;
> > -
> > -   if (src->is_ssa && src->ssa == state->old)
> > -      nir_src_copy(src, &state->new_src, state->mem_ctx);
> > -
> > -   return true;
> > -}
> > -
> >  void
> >  nir_ssa_def_rewrite_uses(nir_ssa_def *def, nir_src new_src, void
*mem_ctx)
> >  {
> > -   struct ssa_def_rewrite_state state;
> > -   state.mem_ctx = mem_ctx;
> > -   state.old = def;
> > -   state.new_src = new_src;
> > -
> >     assert(!new_src.is_ssa || def != new_src.ssa);
> >
> > -   struct set *new_uses, *new_if_uses;
> > -   if (new_src.is_ssa) {
> > -      new_uses = new_src.ssa->uses;
> > -      new_if_uses = new_src.ssa->if_uses;
> > -   } else {
> > -      new_uses = new_src.reg.reg->uses;
> > -      new_if_uses = new_src.reg.reg->if_uses;
> > -   }
> > -
> > -   struct set_entry *entry;
> > -   set_foreach(def->uses, entry) {
> > -      nir_instr *instr = (nir_instr *)entry->key;
> > -
> > -      _mesa_set_remove(def->uses, entry);
> > -      nir_foreach_src(instr, ssa_def_rewrite_uses_src, &state);
> > -      _mesa_set_add(new_uses, instr);
> > +   nir_foreach_use_safe(def, use_src) {
> > +      nir_instr *src_parent_instr = use_src->parent_instr;
> > +      list_del(&use_src->use_link);
> > +      nir_src_copy(use_src, &new_src, mem_ctx);
> > +      src_add_all_uses(use_src, src_parent_instr, NULL);
> >     }
> >
> > -   set_foreach(def->if_uses, entry) {
> > -      nir_if *if_use = (nir_if *)entry->key;
> > -
> > -      _mesa_set_remove(def->if_uses, entry);
> > -      nir_src_copy(&if_use->condition, &new_src, mem_ctx);
> > -      _mesa_set_add(new_if_uses, if_use);
> > +   nir_foreach_if_use_safe(def, use_src) {
> > +      nir_if *src_parent_if = use_src->parent_if;
> > +      list_del(&use_src->use_link);
> > +      nir_src_copy(use_src, &new_src, mem_ctx);
> > +      src_add_all_uses(use_src, NULL, src_parent_if);
> >     }
> >  }
> >
> > diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h
> > index aaf1c57..ac027b0 100644
> > --- a/src/glsl/nir/nir.h
> > +++ b/src/glsl/nir/nir.h
> > @@ -30,6 +30,7 @@
> >  #include "util/hash_table.h"
> >  #include "../list.h"
> >  #include "GL/gl.h" /* GLenum */
> > +#include "util/list.h"
> >  #include "util/ralloc.h"
> >  #include "util/set.h"
> >  #include "util/bitset.h"
> > @@ -397,13 +398,13 @@ typedef struct {
> >     struct nir_instr *parent_instr;
> >
> >     /** set of nir_instr's where this register is used (read from) */
> > -   struct set *uses;
> > +   struct list_head uses;
> >
> >     /** set of nir_instr's where this register is defined (written to)
*/
> > -   struct set *defs;
> > +   struct list_head defs;
> >
> >     /** set of nir_if's where this register is used as a condition */
> > -   struct set *if_uses;
> > +   struct list_head if_uses;
> >  } nir_register;
> >
> >  typedef enum {
> > @@ -462,10 +463,10 @@ typedef struct {
> >     nir_instr *parent_instr;
> >
> >     /** set of nir_instr's where this register is used (read from) */
> > -   struct set *uses;
> > +   struct list_head uses;
> >
> >     /** set of nir_if's where this register is used as a condition */
> > -   struct set *if_uses;
> > +   struct list_head if_uses;
> >
> >     uint8_t num_components;
> >  } nir_ssa_def;
> > @@ -481,6 +482,9 @@ typedef struct {
> >  } nir_reg_src;
> >
> >  typedef struct {
> > +   nir_instr *parent_instr;
> > +   struct list_head def_link;
> > +
> >     nir_register *reg;
> >     struct nir_src *indirect; /** < NULL for no indirect offset */
> >     unsigned base_offset;
> > @@ -488,8 +492,17 @@ typedef struct {
> >     /* TODO def-use chain goes here */
> >  } nir_reg_dest;
> >
> > +struct nir_if;
> > +
> >  typedef struct nir_src {
> >     union {
> > +      nir_instr *parent_instr;
> > +      struct nir_if *parent_if;
> > +   };
> > +
> > +   struct list_head use_link;
>
> So I was thinking about this, and I realized that putting the list
> link here would mean that having SSA-only sources, like my experiments
> with making derefs instructions, would be a massive pain. Making a
> separate nir_ssa_src to put the use_link and parent_instr/parent_if in
> seems like a lot more churn, but would it be harder/even more churn to
> do it after this series rather than as a part of it? I don't think it
> necessitates re-doing everything or giving up entirely, but I thought
> it would be useful to note. I guess we could always use the full
> nir_src and then do an assert(is_ssa) in the validator.

We could also put it in nir_reg_src and nir_ssa_src.  Since the list is
embedded in a ssa value, we know what kind of source it is.  It would mean
that we would have to split up the iterators though. Not a big deal.

> > +
> > +   union {
> >        nir_reg_src reg;
> >        nir_ssa_def *ssa;
> >     };
> > @@ -497,7 +510,19 @@ typedef struct nir_src {
> >     bool is_ssa;
> >  } nir_src;
> >
> > -#define NIR_SRC_INIT (nir_src) { { { NULL } } }
> > +#define NIR_SRC_INIT (nir_src) { { NULL } }
> > +
> > +#define nir_foreach_use(reg_or_ssa_def, src) \
> > +   list_for_each_entry(nir_src, src, &(reg_or_ssa_def)->uses, use_link)
> > +
> > +#define nir_foreach_use_safe(reg_or_ssa_def, src) \
> > +   list_for_each_entry_safe(nir_src, src, &(reg_or_ssa_def)->uses,
use_link)
> > +
> > +#define nir_foreach_if_use(reg_or_ssa_def, src) \
> > +   list_for_each_entry(nir_src, src, &(reg_or_ssa_def)->if_uses,
use_link)
> > +
> > +#define nir_foreach_if_use_safe(reg_or_ssa_def, src) \
> > +   list_for_each_entry_safe(nir_src, src, &(reg_or_ssa_def)->if_uses,
use_link)
> >
> >  typedef struct {
> >     union {
> > @@ -510,6 +535,12 @@ typedef struct {
> >
> >  #define NIR_DEST_INIT (nir_dest) { { { NULL } } }
> >
> > +#define nir_foreach_def(reg, dest) \
> > +   list_for_each_entry(nir_dest, dest, &(reg)->defs, reg.def_link)
> > +
> > +#define nir_foreach_def_safe(reg, dest) \
> > +   list_for_each_entry_safe(nir_dest, dest, &(reg)->defs, reg.def_link)
> > +
> >  static inline nir_src
> >  nir_src_for_ssa(nir_ssa_def *def)
> >  {
> > @@ -1208,7 +1239,7 @@ nir_block_last_instr(nir_block *block)
> >  #define nir_foreach_instr_safe(block, instr) \
> >     foreach_list_typed_safe(nir_instr, instr, node,
&(block)->instr_list)
> >
> > -typedef struct {
> > +typedef struct nir_if {
> >     nir_cf_node cf_node;
> >     nir_src condition;
> >
> > diff --git a/src/glsl/nir/nir_validate.c b/src/glsl/nir/nir_validate.c
> > index 35a853d..da92ed9 100644
> > --- a/src/glsl/nir/nir_validate.c
> > +++ b/src/glsl/nir/nir_validate.c
> > @@ -97,50 +97,47 @@ typedef struct {
> >  static void validate_src(nir_src *src, validate_state *state);
> >
> >  static void
> > -validate_reg_src(nir_reg_src *src, validate_state *state)
> > +validate_reg_src(nir_src *src, validate_state *state)
> >  {
> > -   assert(src->reg != NULL);
> > +   assert(src->reg.reg != NULL);
> >
> >     struct hash_entry *entry;
> > -   entry = _mesa_hash_table_search(state->regs, src->reg);
> > +   entry = _mesa_hash_table_search(state->regs, src->reg.reg);
> >     assert(entry);
> >
> >     reg_validate_state *reg_state = (reg_validate_state *) entry->data;
> >
> >     if (state->instr) {
> > -      _mesa_set_add(reg_state->uses, state->instr);
> > -
> > -      assert(_mesa_set_search(src->reg->uses, state->instr));
> > +      _mesa_set_add(reg_state->uses, src);
> >     } else {
> >        assert(state->if_stmt);
> > -      _mesa_set_add(reg_state->if_uses, state->if_stmt);
> > -
> > -      assert(_mesa_set_search(src->reg->if_uses, state->if_stmt));
> > +      _mesa_set_add(reg_state->if_uses, src);
> >     }
> >
> > -   if (!src->reg->is_global) {
> > +   if (!src->reg.reg->is_global) {
> >        assert(reg_state->where_defined == state->impl &&
> >               "using a register declared in a different function");
> >     }
> >
> > -   assert((src->reg->num_array_elems == 0 ||
> > -          src->base_offset < src->reg->num_array_elems) &&
> > +   assert((src->reg.reg->num_array_elems == 0 ||
> > +          src->reg.base_offset < src->reg.reg->num_array_elems) &&
> >            "definitely out-of-bounds array access");
> >
> > -   if (src->indirect) {
> > -      assert(src->reg->num_array_elems != 0);
> > -      assert((src->indirect->is_ssa || src->indirect->reg.indirect ==
NULL) &&
> > +   if (src->reg.indirect) {
> > +      assert(src->reg.reg->num_array_elems != 0);
> > +      assert((src->reg.indirect->is_ssa ||
> > +              src->reg.indirect->reg.indirect == NULL) &&
> >               "only one level of indirection allowed");
> > -      validate_src(src->indirect, state);
> > +      validate_src(src->reg.indirect, state);
> >     }
> >  }
> >
> >  static void
> > -validate_ssa_src(nir_ssa_def *def, validate_state *state)
> > +validate_ssa_src(nir_src *src, validate_state *state)
> >  {
> > -   assert(def != NULL);
> > +   assert(src->ssa != NULL);
> >
> > -   struct hash_entry *entry = _mesa_hash_table_search(state->ssa_defs,
def);
> > +   struct hash_entry *entry = _mesa_hash_table_search(state->ssa_defs,
src->ssa);
> >
> >     assert(entry);
> >
> > @@ -150,14 +147,10 @@ validate_ssa_src(nir_ssa_def *def, validate_state
*state)
> >            "using an SSA value defined in a different function");
> >
> >     if (state->instr) {
> > -      _mesa_set_add(def_state->uses, state->instr);
> > -
> > -      assert(_mesa_set_search(def->uses, state->instr));
> > +      _mesa_set_add(def_state->uses, src);
> >     } else {
> >        assert(state->if_stmt);
> > -      _mesa_set_add(def_state->if_uses, state->if_stmt);
> > -
> > -      assert(_mesa_set_search(def->if_uses, state->if_stmt));
> > +      _mesa_set_add(def_state->if_uses, src);
> >     }
> >
> >     /* TODO validate that the use is dominated by the definition */
> > @@ -166,10 +159,15 @@ validate_ssa_src(nir_ssa_def *def, validate_state
*state)
> >  static void
> >  validate_src(nir_src *src, validate_state *state)
> >  {
> > +   if (state->instr)
> > +      assert(src->parent_instr == state->instr);
> > +   else
> > +      assert(src->parent_if == state->if_stmt);
> > +
> >     if (src->is_ssa)
> > -      validate_ssa_src(src->ssa, state);
> > +      validate_ssa_src(src, state);
> >     else
> > -      validate_reg_src(&src->reg, state);
> > +      validate_reg_src(src, state);
> >  }
> >
> >  static void
> > @@ -201,8 +199,7 @@ validate_reg_dest(nir_reg_dest *dest,
validate_state *state)
> >  {
> >     assert(dest->reg != NULL);
> >
> > -   struct set_entry *entry = _mesa_set_search(dest->reg->defs,
state->instr);
> > -   assert(entry && "definition not in nir_register.defs");
> > +   assert(dest->parent_instr == state->instr);
> >
> >     struct hash_entry *entry2;
> >     entry2 = _mesa_hash_table_search(state->regs, dest->reg);
> > @@ -210,7 +207,7 @@ validate_reg_dest(nir_reg_dest *dest,
validate_state *state)
> >     assert(entry2);
> >
> >     reg_validate_state *reg_state = (reg_validate_state *) entry2->data;
> > -   _mesa_set_add(reg_state->defs, state->instr);
> > +   _mesa_set_add(reg_state->defs, dest);
> >
> >     if (!dest->reg->is_global) {
> >        assert(reg_state->where_defined == state->impl &&
> > @@ -240,6 +237,9 @@ validate_ssa_def(nir_ssa_def *def, validate_state
*state)
> >
> >     assert(def->num_components <= 4);
> >
> > +   list_validate(&def->uses);
> > +   list_validate(&def->if_uses);
> > +
> >     ssa_def_validate_state *def_state = ralloc(state->ssa_defs,
> >                                                ssa_def_validate_state);
> >     def_state->where_defined = state->impl;
> > @@ -701,6 +701,10 @@ prevalidate_reg_decl(nir_register *reg, bool
is_global, validate_state *state)
> >     assert(!BITSET_TEST(state->regs_found, reg->index));
> >     BITSET_SET(state->regs_found, reg->index);
> >
> > +   list_validate(&reg->uses);
> > +   list_validate(&reg->defs);
> > +   list_validate(&reg->if_uses);
> > +
> >     reg_validate_state *reg_state = ralloc(state->regs,
reg_validate_state);
> >     reg_state->uses = _mesa_set_create(reg_state, _mesa_hash_pointer,
> >                                        _mesa_key_pointer_equal);
> > @@ -721,47 +725,47 @@ postvalidate_reg_decl(nir_register *reg,
validate_state *state)
> >
> >     reg_validate_state *reg_state = (reg_validate_state *) entry->data;
> >
> > -   if (reg_state->uses->entries != reg->uses->entries) {
> > +   nir_foreach_use(reg, src) {
> > +      struct set_entry *entry = _mesa_set_search(reg_state->uses, src);
> > +      assert(entry);
> > +      _mesa_set_remove(reg_state->uses, entry);
> > +   }
> > +
> > +   if (reg_state->uses->entries != 0) {
> >        printf("extra entries in register uses:\n");
> >        struct set_entry *entry;
> > -      set_foreach(reg->uses, entry) {
> > -         struct set_entry *entry2 =
> > -            _mesa_set_search(reg_state->uses, entry->key);
> > -
> > -         if (entry2 == NULL) {
> > -            printf("%p\n", entry->key);
> > -         }
> > -      }
> > +      set_foreach(reg_state->uses, entry)
> > +         printf("%p\n", entry->key);
> >
> >        abort();
> >     }
> >
> > -   if (reg_state->if_uses->entries != reg->if_uses->entries) {
> > +   nir_foreach_if_use(reg, src) {
> > +      struct set_entry *entry = _mesa_set_search(reg_state->if_uses,
src);
> > +      assert(entry);
> > +      _mesa_set_remove(reg_state->if_uses, entry);
> > +   }
> > +
> > +   if (reg_state->if_uses->entries != 0) {
> >        printf("extra entries in register if_uses:\n");
> >        struct set_entry *entry;
> > -      set_foreach(reg->if_uses, entry) {
> > -         struct set_entry *entry2 =
> > -            _mesa_set_search(reg_state->if_uses, entry->key);
> > -
> > -         if (entry2 == NULL) {
> > -            printf("%p\n", entry->key);
> > -         }
> > -      }
> > +      set_foreach(reg_state->if_uses, entry)
> > +         printf("%p\n", entry->key);
> >
> >        abort();
> >     }
> >
> > -   if (reg_state->defs->entries != reg->defs->entries) {
> > +   nir_foreach_def(reg, src) {
> > +      struct set_entry *entry = _mesa_set_search(reg_state->defs, src);
> > +      assert(entry);
> > +      _mesa_set_remove(reg_state->defs, entry);
> > +   }
> > +
> > +   if (reg_state->defs->entries != 0) {
> >        printf("extra entries in register defs:\n");
> >        struct set_entry *entry;
> > -      set_foreach(reg->defs, entry) {
> > -         struct set_entry *entry2 =
> > -            _mesa_set_search(reg_state->defs, entry->key);
> > -
> > -         if (entry2 == NULL) {
> > -            printf("%p\n", entry->key);
> > -         }
> > -      }
> > +      set_foreach(reg_state->defs, entry)
> > +         printf("%p\n", entry->key);
> >
> >        abort();
> >     }
> > @@ -790,32 +794,32 @@ postvalidate_ssa_def(nir_ssa_def *def, void
*void_state)
> >     struct hash_entry *entry = _mesa_hash_table_search(state->ssa_defs,
def);
> >     ssa_def_validate_state *def_state = (ssa_def_validate_state
*)entry->data;
> >
> > -   if (def_state->uses->entries != def->uses->entries) {
> > -      printf("extra entries in SSA def uses:\n");
> > -      struct set_entry *entry;
> > -      set_foreach(def->uses, entry) {
> > -         struct set_entry *entry2 =
> > -            _mesa_set_search(def_state->uses, entry->key);
> > +   nir_foreach_use(def, src) {
> > +      struct set_entry *entry = _mesa_set_search(def_state->uses, src);
> > +      assert(entry);
> > +      _mesa_set_remove(def_state->uses, entry);
> > +   }
> >
> > -         if (entry2 == NULL) {
> > -            printf("%p\n", entry->key);
> > -         }
> > -      }
> > +   if (def_state->uses->entries != 0) {
> > +      printf("extra entries in register uses:\n");
> > +      struct set_entry *entry;
> > +      set_foreach(def_state->uses, entry)
> > +         printf("%p\n", entry->key);
> >
> >        abort();
> >     }
> >
> > -   if (def_state->if_uses->entries != def->if_uses->entries) {
> > -      printf("extra entries in SSA def uses:\n");
> > -      struct set_entry *entry;
> > -      set_foreach(def->if_uses, entry) {
> > -         struct set_entry *entry2 =
> > -            _mesa_set_search(def_state->if_uses, entry->key);
> > +   nir_foreach_if_use(def, src) {
> > +      struct set_entry *entry = _mesa_set_search(def_state->if_uses,
src);
> > +      assert(entry);
> > +      _mesa_set_remove(def_state->if_uses, entry);
> > +   }
> >
> > -         if (entry2 == NULL) {
> > -            printf("%p\n", entry->key);
> > -         }
> > -      }
> > +   if (def_state->if_uses->entries != 0) {
> > +      printf("extra entries in register uses:\n");
> > +      struct set_entry *entry;
> > +      set_foreach(def_state->if_uses, entry)
> > +         printf("%p\n", entry->key);
> >
> >        abort();
> >     }
> > --
> > 2.3.6
> >
> > _______________________________________________
> > mesa-dev mailing list
> > mesa-dev at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/mesa-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20150430/df93bb6e/attachment-0001.html>


More information about the mesa-dev mailing list