diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index 7a6ff0696cb..f88bfe39ba8 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -31,6 +31,7 @@ #include #include "util/half_float.h" #include "util/macros.h" +#include "util/ralloc.h" #include "util/u_math.h" #include "util/u_printf.h" #include "util/u_qsort.h" @@ -729,6 +730,13 @@ nir_function_impl_create(nir_function *function) return impl; } +static void +nir_block_destructor(void *block_) +{ + nir_block *block = block_; + util_dynarray_fini(&block->predecessors); +} + nir_block * nir_block_create(nir_shader *shader) { @@ -737,12 +745,15 @@ nir_block_create(nir_shader *shader) cf_init(&block->cf_node, nir_cf_node_block); block->successors[0] = block->successors[1] = NULL; - _mesa_pointer_set_init(&block->predecessors, block); + util_dynarray_init_from_stack( + &block->predecessors, block->_preds_storage, sizeof(block->_preds_storage)); block->imm_dom = NULL; _mesa_pointer_set_init(&block->dom_frontier, block); exec_list_make_empty(&block->instr_list); + ralloc_set_destructor(block, &nir_block_destructor); + return block; } diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 3af7e197ee8..6b24604946b 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -45,6 +45,7 @@ #include "util/set.h" #include "util/simple_mtx.h" #include "util/sparse_bitset.h" +#include "util/u_dynarray.h" #include "util/u_math.h" #include "nir_defines.h" #include "nir_shader_compiler_options.h" @@ -3261,7 +3262,8 @@ typedef struct nir_block { nir_block *successors[2]; /* Set of nir_block predecessors in the CFG */ - struct set predecessors; + struct util_dynarray predecessors; + nir_block *_preds_storage[2]; /* * this node's immediate dominator in the dominance tree - set to NULL for @@ -3311,57 +3313,48 @@ typedef struct nir_block { struct u_sparse_bitset live_out; } nir_block; -static ALWAYS_INLINE nir_block * -_nir_pred_iter_begin(const nir_block *block, nir_block **iter) +static ALWAYS_INLINE nir_block ** +_nir_pred_iter_begin(const nir_block *block) { - struct set_entry *entry = _mesa_set_next_entry(&block->predecessors, NULL); - *iter = (nir_block *)entry; - return entry ? (nir_block *)entry->key : NULL; + return (nir_block **)util_dynarray_begin(&block->predecessors); } -static ALWAYS_INLINE nir_block * -_nir_pred_iter_end(const nir_block *block) +static ALWAYS_INLINE bool +_nir_pred_iter_end(const nir_block *block, nir_block **iter, nir_block **pred) { - struct set_entry *entry = NULL; - return (nir_block *)entry; + if (iter == (nir_block **)util_dynarray_end(&block->predecessors)) + return false; + *pred = *iter; + return true; } -static ALWAYS_INLINE nir_block * -_nir_pred_iter_advance(const nir_block *block, nir_block **iter) -{ - struct set_entry *entry = (struct set_entry *)*iter; - entry = _mesa_set_next_entry(&block->predecessors, entry); - *iter = (nir_block *)entry; - return entry ? (nir_block *)entry->key : NULL; -} - -#define nir_foreach_pred(pred, block) \ - for (nir_block * pred##_iter, *pred = _nir_pred_iter_begin((block), &pred##_iter); \ - pred##_iter != _nir_pred_iter_end((block)); \ - pred = _nir_pred_iter_advance((block), &pred##_iter)) +#define nir_foreach_pred(pred, block) \ + for (nir_block * pred, **pred##_iter = _nir_pred_iter_begin((block)); \ + _nir_pred_iter_end((block), pred##_iter, &pred); \ + pred##_iter++) static inline size_t nir_block_num_preds(const nir_block *block) { - return block->predecessors.entries; + return util_dynarray_num_elements(&block->predecessors, nir_block *); } static inline bool nir_block_has_pred(const nir_block *block, const nir_block *pred) { - return _mesa_set_search(&block->predecessors, pred); + return pred->successors[0] == block || pred->successors[1] == block; } static inline void nir_block_add_pred(nir_block *block, nir_block *pred) { - _mesa_set_add(&block->predecessors, pred); + util_dynarray_append(&block->predecessors, pred); } static inline void nir_block_remove_pred(nir_block *block, nir_block *pred) { - _mesa_set_remove_key(&block->predecessors, pred); + util_dynarray_delete_unordered(&block->predecessors, nir_block *, pred); } static inline bool diff --git a/src/compiler/nir/nir_control_flow.c b/src/compiler/nir/nir_control_flow.c index 9fc163285d9..292cb07fe90 100644 --- a/src/compiler/nir/nir_control_flow.c +++ b/src/compiler/nir/nir_control_flow.c @@ -162,7 +162,7 @@ replace_pred_succs(nir_block *block, nir_block *new_block, nir_block *exclude) nir_block_add_pred(new_block, pred); } - _mesa_set_clear(&block->predecessors, NULL); + util_dynarray_clear(&block->predecessors); if (found_exclude) nir_block_add_pred(block, exclude); } diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c index a83145e0c6f..3a3dacd0922 100644 --- a/src/compiler/nir/nir_validate.c +++ b/src/compiler/nir/nir_validate.c @@ -1472,8 +1472,10 @@ validate_block_predecessors(nir_block *block, validate_state *state) block->successors[i])); /* And we have to be in our successor's predecessors set */ - validate_assert(state, - nir_block_has_pred(block->successors[i], block)); + bool has_pred = false; + nir_foreach_pred(pred, block->successors[i]) + has_pred |= pred == block; + validate_assert(state, has_pred); validate_phi_srcs(block, block->successors[i], state); } @@ -1482,6 +1484,17 @@ validate_block_predecessors(nir_block *block, validate_state *state) if (block == nir_start_block(state->impl)) validate_assert(state, nir_block_num_preds(block) == 0); + /* Check for duplicate predecessors. */ + nir_foreach_pred(pred, block) { + bool found = false; + nir_foreach_pred(pred2, block) { + if (pred == pred2) { + validate_assert(state, !found); + found = true; + } + } + } + nir_foreach_pred(pred, block) { validate_assert(state, _mesa_set_search(state->blocks, pred)); validate_assert(state, pred->successors[0] == block ||