mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 00:38:48 +02:00
nir: use a u_dynarray for block predecessors
A set is large and expensive to iterate.
This is faster (overall fossilize-replay difference):
Difference at 95.0% confidence
-250 +/- 28.9257
-2.04849% +/- 0.235211%
(Student's t, pooled s = 34.1626)
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Reviewed-by: Georg Lehmann <dadschoorse@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40242>
This commit is contained in:
parent
99c5f48da9
commit
01516746eb
4 changed files with 48 additions and 31 deletions
|
|
@ -31,6 +31,7 @@
|
|||
#include <math.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue