summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/nir')
-rw-r--r--src/compiler/nir/nir_validate.c128
1 files changed, 50 insertions, 78 deletions
diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c
index 3b3244b317e..8278176564f 100644
--- a/src/compiler/nir/nir_validate.c
+++ b/src/compiler/nir/nir_validate.c
@@ -52,15 +52,6 @@ typedef struct {
} reg_validate_state;
typedef struct {
- /*
- * equivalent to the uses in nir_ssa_def, but built up by the validator.
- * At the end, we verify that the sets have the same entries.
- */
- struct set *uses, *if_uses;
- nir_function_impl *where_defined;
-} ssa_def_validate_state;
-
-typedef struct {
void *mem_ctx;
/* map of register -> validation state (struct above) */
@@ -90,8 +81,8 @@ typedef struct {
/* the current function implementation being validated */
nir_function_impl *impl;
- /* map of SSA value -> function implementation where it is defined */
- struct hash_table *ssa_defs;
+ /* Set of seen SSA sources */
+ struct set *ssa_srcs;
/* bitset of ssa definitions we have found; used to check uniqueness */
BITSET_WORD *ssa_defs_found;
@@ -174,30 +165,29 @@ validate_reg_src(nir_src *src, validate_state *state,
}
}
+#define SET_PTR_BIT(ptr, bit) \
+ (void *)(((uintptr_t)(ptr)) | (((uintptr_t)1) << bit))
+
static void
validate_ssa_src(nir_src *src, validate_state *state,
unsigned bit_sizes, unsigned num_components)
{
validate_assert(state, src->ssa != NULL);
- struct hash_entry *entry = _mesa_hash_table_search(state->ssa_defs, src->ssa);
-
- validate_assert(state, entry);
-
- if (!entry)
- return;
-
- ssa_def_validate_state *def_state = (ssa_def_validate_state *)entry->data;
-
- validate_assert(state, def_state->where_defined == state->impl &&
- "using an SSA value defined in a different function");
-
+ /* As we walk SSA defs, we add every use to this set. We need to make sure
+ * our use is seen in a use list.
+ */
+ struct set_entry *entry;
if (state->instr) {
- _mesa_set_add(def_state->uses, src);
+ entry = _mesa_set_search(state->ssa_srcs, src);
} else {
- validate_assert(state, state->if_stmt);
- _mesa_set_add(def_state->if_uses, src);
+ entry = _mesa_set_search(state->ssa_srcs, SET_PTR_BIT(src, 0));
}
+ validate_assert(state, entry);
+
+ /* This will let us prove that we've seen all the sources */
+ if (entry)
+ _mesa_set_remove(state->ssa_srcs, entry);
if (bit_sizes)
validate_assert(state, src->ssa->bit_size & bit_sizes);
@@ -288,14 +278,25 @@ validate_ssa_def(nir_ssa_def *def, validate_state *state)
(def->num_components == 16));
list_validate(&def->uses);
- list_validate(&def->if_uses);
+ nir_foreach_use(src, def) {
+ validate_assert(state, src->is_ssa);
+ validate_assert(state, src->ssa == def);
+ bool already_seen = false;
+ _mesa_set_search_and_add(state->ssa_srcs, src, &already_seen);
+ /* A nir_src should only appear once and only in one SSA def use list */
+ validate_assert(state, !already_seen);
+ }
- ssa_def_validate_state *def_state = ralloc(state->ssa_defs,
- ssa_def_validate_state);
- def_state->where_defined = state->impl;
- def_state->uses = _mesa_pointer_set_create(def_state);
- def_state->if_uses = _mesa_pointer_set_create(def_state);
- _mesa_hash_table_insert(state->ssa_defs, def, def_state);
+ list_validate(&def->if_uses);
+ nir_foreach_if_use(src, def) {
+ validate_assert(state, src->is_ssa);
+ validate_assert(state, src->ssa == def);
+ bool already_seen = false;
+ _mesa_set_search_and_add(state->ssa_srcs, SET_PTR_BIT(src, 0),
+ &already_seen);
+ /* A nir_src should only appear once and only in one SSA def use list */
+ validate_assert(state, !already_seen);
+ }
}
static void
@@ -1078,50 +1079,18 @@ validate_var_decl(nir_variable *var, bool is_global, validate_state *state)
state->var = NULL;
}
-static bool
-postvalidate_ssa_def(nir_ssa_def *def, void *void_state)
-{
- validate_state *state = void_state;
-
- struct hash_entry *entry = _mesa_hash_table_search(state->ssa_defs, def);
-
- assume(entry);
- ssa_def_validate_state *def_state = (ssa_def_validate_state *)entry->data;
-
- nir_foreach_use(src, def) {
- struct set_entry *entry = _mesa_set_search(def_state->uses, src);
- validate_assert(state, entry);
- _mesa_set_remove(def_state->uses, entry);
- }
-
- if (def_state->uses->entries != 0) {
- printf("extra entries in SSA def uses:\n");
- set_foreach(def_state->uses, entry)
- printf("%p\n", entry->key);
-
- abort();
- }
-
- nir_foreach_if_use(src, def) {
- struct set_entry *entry = _mesa_set_search(def_state->if_uses, src);
- validate_assert(state, entry);
- _mesa_set_remove(def_state->if_uses, entry);
- }
-
- if (def_state->if_uses->entries != 0) {
- printf("extra entries in SSA def uses:\n");
- set_foreach(def_state->if_uses, entry)
- printf("%p\n", entry->key);
-
- abort();
- }
-
- return true;
-}
-
static void
validate_function_impl(nir_function_impl *impl, validate_state *state)
{
+ /* Resize the ssa_srcs set. It's likely that the size of this set will
+ * never actually hit the number of SSA defs because we remove sources from
+ * the set as we visit them. (It could actually be much larger because
+ * each SSA def can be used more than once.) However, growing it now costs
+ * us very little (the extra memory is already dwarfed by the SSA defs
+ * themselves) and makes collisions much less likely.
+ */
+ _mesa_set_resize(state->ssa_srcs, impl->ssa_alloc);
+
validate_assert(state, impl->function->impl == impl);
validate_assert(state, impl->cf_node.parent == NULL);
@@ -1159,9 +1128,12 @@ validate_function_impl(nir_function_impl *impl, validate_state *state)
postvalidate_reg_decl(reg, state);
}
- nir_foreach_block(block, impl) {
- nir_foreach_instr(instr, block)
- nir_foreach_ssa_def(instr, postvalidate_ssa_def, state);
+ if (state->ssa_srcs->entries != 0) {
+ printf("extra dangling SSA sources:\n");
+ set_foreach(state->ssa_srcs, entry)
+ printf("%p\n", entry->key);
+
+ abort();
}
}
@@ -1179,7 +1151,7 @@ init_validate_state(validate_state *state)
{
state->mem_ctx = ralloc_context(NULL);
state->regs = _mesa_pointer_hash_table_create(state->mem_ctx);
- state->ssa_defs = _mesa_pointer_hash_table_create(state->mem_ctx);
+ state->ssa_srcs = _mesa_pointer_set_create(state->mem_ctx);
state->ssa_defs_found = NULL;
state->regs_found = NULL;
state->var_defs = _mesa_pointer_hash_table_create(state->mem_ctx);