mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 07:08:04 +02:00
nir: add and use block predecessor helpers
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com> Acked-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
705158562a
commit
463e3643f2
42 changed files with 160 additions and 156 deletions
|
|
@ -172,6 +172,8 @@ ForEachMacros:
|
|||
- nir_foreach_block_reverse_safe
|
||||
- nir_foreach_block_safe
|
||||
|
||||
- nir_foreach_pred
|
||||
|
||||
- nir_precomp_foreach_arg
|
||||
- nir_precomp_foreach_variant_param
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ sanitize_cf_list(nir_function_impl* impl, struct exec_list* cf_list)
|
|||
* from the loop header are live. Handle this without complicating the ACO IR by creating a
|
||||
* dummy break.
|
||||
*/
|
||||
if (nir_cf_node_cf_tree_next(&loop->cf_node)->predecessors.entries == 0) {
|
||||
if (nir_block_num_preds(nir_cf_node_cf_tree_next(&loop->cf_node)) == 0) {
|
||||
nir_builder b = nir_builder_create(impl);
|
||||
b.cursor = nir_after_block_before_jump(nir_loop_last_block(loop));
|
||||
|
||||
|
|
|
|||
|
|
@ -944,7 +944,7 @@ visit_loop(isel_context* ctx, nir_loop* loop)
|
|||
loop_context lc;
|
||||
begin_loop(ctx, &lc);
|
||||
ctx->cf_info.parent_loop.has_divergent_break =
|
||||
loop->divergent_break && nir_loop_first_block(loop)->predecessors.entries > 1;
|
||||
loop->divergent_break && nir_block_num_preds(nir_loop_first_block(loop)) > 1;
|
||||
ctx->cf_info.in_divergent_cf |= ctx->cf_info.parent_loop.has_divergent_break;
|
||||
|
||||
visit_cf_list(ctx, &loop->body);
|
||||
|
|
|
|||
|
|
@ -167,9 +167,8 @@ gather_tail_call_instrs_block(nir_function *caller, const struct nir_block *bloc
|
|||
_mesa_set_add(tail_calls, instr);
|
||||
}
|
||||
|
||||
set_foreach (&block->predecessors, pred) {
|
||||
gather_tail_call_instrs_block(caller, pred->key, tail_calls);
|
||||
}
|
||||
nir_foreach_pred (pred, block)
|
||||
gather_tail_call_instrs_block(caller, pred, tail_calls);
|
||||
}
|
||||
|
||||
struct lower_param_info {
|
||||
|
|
|
|||
|
|
@ -715,7 +715,7 @@ nir_function_impl_create_bare(nir_shader *shader)
|
|||
exec_list_push_tail(&impl->body, &start_block->cf_node.node);
|
||||
|
||||
start_block->successors[0] = end_block;
|
||||
_mesa_set_add(&end_block->predecessors, start_block);
|
||||
nir_block_add_pred(end_block, start_block);
|
||||
return impl;
|
||||
}
|
||||
|
||||
|
|
@ -791,7 +791,7 @@ nir_loop_create(nir_shader *shader)
|
|||
body->cf_node.parent = &loop->cf_node;
|
||||
|
||||
body->successors[0] = body;
|
||||
_mesa_set_add(&body->predecessors, body);
|
||||
nir_block_add_pred(body, body);
|
||||
|
||||
exec_list_make_empty(&loop->continue_list);
|
||||
|
||||
|
|
@ -2151,16 +2151,14 @@ compare_block_index(const void *p1, const void *p2)
|
|||
nir_block **
|
||||
nir_block_get_predecessors_sorted(const nir_block *block, void *mem_ctx)
|
||||
{
|
||||
nir_block **preds =
|
||||
ralloc_array(mem_ctx, nir_block *, block->predecessors.entries);
|
||||
unsigned count = nir_block_num_preds(block);
|
||||
nir_block **preds = ralloc_array(mem_ctx, nir_block *, count);
|
||||
|
||||
unsigned i = 0;
|
||||
set_foreach(&block->predecessors, entry)
|
||||
preds[i++] = (nir_block *)entry->key;
|
||||
assert(i == block->predecessors.entries);
|
||||
nir_foreach_pred(pred, block)
|
||||
preds[i++] = pred;
|
||||
|
||||
qsort(preds, block->predecessors.entries, sizeof(nir_block *),
|
||||
compare_block_index);
|
||||
qsort(preds, count, sizeof(nir_block *), compare_block_index);
|
||||
|
||||
return preds;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3311,6 +3311,59 @@ 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)
|
||||
{
|
||||
struct set_entry *entry = _mesa_set_next_entry(&block->predecessors, NULL);
|
||||
*iter = (nir_block *)entry;
|
||||
return entry ? (nir_block *)entry->key : NULL;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE nir_block *
|
||||
_nir_pred_iter_end(const nir_block *block)
|
||||
{
|
||||
struct set_entry *entry = NULL;
|
||||
return (nir_block *)entry;
|
||||
}
|
||||
|
||||
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))
|
||||
|
||||
static inline size_t
|
||||
nir_block_num_preds(const nir_block *block)
|
||||
{
|
||||
return block->predecessors.entries;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
nir_block_has_pred(const nir_block *block, const nir_block *pred)
|
||||
{
|
||||
return _mesa_set_search(&block->predecessors, pred);
|
||||
}
|
||||
|
||||
static inline void
|
||||
nir_block_add_pred(nir_block *block, nir_block *pred)
|
||||
{
|
||||
_mesa_set_add(&block->predecessors, pred);
|
||||
}
|
||||
|
||||
static inline void
|
||||
nir_block_remove_pred(nir_block *block, nir_block *pred)
|
||||
{
|
||||
_mesa_set_remove_key(&block->predecessors, pred);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
nir_block_is_reachable(nir_block *b)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -45,32 +45,16 @@
|
|||
*/
|
||||
/*@{*/
|
||||
|
||||
static inline void
|
||||
block_add_pred(nir_block *block, nir_block *pred)
|
||||
{
|
||||
_mesa_set_add(&block->predecessors, pred);
|
||||
}
|
||||
|
||||
static inline void
|
||||
block_remove_pred(nir_block *block, nir_block *pred)
|
||||
{
|
||||
struct set_entry *entry = _mesa_set_search(&block->predecessors, pred);
|
||||
|
||||
assert(entry);
|
||||
|
||||
_mesa_set_remove(&block->predecessors, entry);
|
||||
}
|
||||
|
||||
static void
|
||||
link_blocks(nir_block *pred, nir_block *succ1, nir_block *succ2)
|
||||
{
|
||||
pred->successors[0] = succ1;
|
||||
if (succ1 != NULL)
|
||||
block_add_pred(succ1, pred);
|
||||
nir_block_add_pred(succ1, pred);
|
||||
|
||||
pred->successors[1] = succ2;
|
||||
if (succ2 != NULL)
|
||||
block_add_pred(succ2, pred);
|
||||
nir_block_add_pred(succ2, pred);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -84,7 +68,7 @@ unlink_blocks(nir_block *pred, nir_block *succ)
|
|||
pred->successors[1] = NULL;
|
||||
}
|
||||
|
||||
block_remove_pred(succ, pred);
|
||||
nir_block_remove_pred(succ, pred);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -169,8 +153,8 @@ replace_successor(nir_block *block, nir_block *old_succ, nir_block *new_succ)
|
|||
block->successors[1] = new_succ;
|
||||
}
|
||||
|
||||
block_remove_pred(old_succ, block);
|
||||
block_add_pred(new_succ, block);
|
||||
nir_block_remove_pred(old_succ, block);
|
||||
nir_block_add_pred(new_succ, block);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -188,10 +172,8 @@ split_block_beginning(nir_block *block)
|
|||
new_block->cf_node.parent = block->cf_node.parent;
|
||||
exec_node_insert_node_before(&block->cf_node.node, &new_block->cf_node.node);
|
||||
|
||||
set_foreach(&block->predecessors, entry) {
|
||||
nir_block *pred = (nir_block *)entry->key;
|
||||
nir_foreach_pred(pred, block)
|
||||
replace_successor(pred, block, new_block);
|
||||
}
|
||||
|
||||
/* Any phi nodes must stay part of the new block, or else their
|
||||
* sources will be messed up.
|
||||
|
|
@ -437,9 +419,8 @@ nir_loop_add_continue_construct(nir_loop *loop)
|
|||
/* change predecessors and successors */
|
||||
nir_block *header = nir_loop_first_block(loop);
|
||||
nir_block *preheader = nir_block_cf_tree_prev(header);
|
||||
assert(header->predecessors.entries <= 2);
|
||||
set_foreach(&header->predecessors, entry) {
|
||||
nir_block *pred = (nir_block *)entry->key;
|
||||
assert(nir_block_num_preds(header) <= 2);
|
||||
nir_foreach_pred(pred, header) {
|
||||
if (pred != preheader)
|
||||
replace_successor(pred, header, cont);
|
||||
}
|
||||
|
|
@ -455,12 +436,10 @@ nir_loop_remove_continue_construct(nir_loop *loop)
|
|||
/* change predecessors and successors */
|
||||
nir_block *header = nir_loop_first_block(loop);
|
||||
nir_block *cont = nir_loop_first_continue_block(loop);
|
||||
assert(cont->predecessors.entries <= 2);
|
||||
set_foreach(&cont->predecessors, entry) {
|
||||
nir_block *pred = (nir_block *)entry->key;
|
||||
assert(nir_block_num_preds(cont) <= 2);
|
||||
nir_foreach_pred(pred, cont)
|
||||
replace_successor(pred, cont, header);
|
||||
}
|
||||
block_remove_pred(header, cont);
|
||||
nir_block_remove_pred(header, cont);
|
||||
|
||||
exec_node_remove(&cont->cf_node.node);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1511,7 +1511,7 @@ visit_loop(nir_loop *loop, struct divergence_state *state)
|
|||
/* setup loop state */
|
||||
struct divergence_state loop_state = *state;
|
||||
loop_state.loop = loop;
|
||||
loop_state.loop_all_invariant = loop_header->predecessors.entries == 1;
|
||||
loop_state.loop_all_invariant = nir_block_num_preds(loop_header) == 1;
|
||||
loop_state.divergent_cf = false;
|
||||
loop_state.divergent_loop_continue = false;
|
||||
loop_state.divergent_loop_break = false;
|
||||
|
|
|
|||
|
|
@ -73,9 +73,7 @@ static bool
|
|||
calc_dominance(nir_block *block)
|
||||
{
|
||||
nir_block *new_idom = NULL;
|
||||
set_foreach(&block->predecessors, entry) {
|
||||
nir_block *pred = (nir_block *)entry->key;
|
||||
|
||||
nir_foreach_pred(pred, block) {
|
||||
if (pred->imm_dom) {
|
||||
if (new_idom)
|
||||
new_idom = intersect(pred, new_idom);
|
||||
|
|
@ -95,10 +93,8 @@ calc_dominance(nir_block *block)
|
|||
static bool
|
||||
calc_dom_frontier(nir_block *block)
|
||||
{
|
||||
if (block->predecessors.entries > 1) {
|
||||
set_foreach(&block->predecessors, entry) {
|
||||
nir_block *runner = (nir_block *)entry->key;
|
||||
|
||||
if (nir_block_num_preds(block) > 1) {
|
||||
nir_foreach_pred(runner, block) {
|
||||
/* Skip unreachable predecessors */
|
||||
if (runner->imm_dom == NULL)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -1006,8 +1006,7 @@ place_phi_read(nir_builder *b, nir_def *reg,
|
|||
if (_mesa_set_search(visited_blocks, block) == NULL) {
|
||||
/* Try to go up the single-successor tree */
|
||||
bool all_single_successors = true;
|
||||
set_foreach(&block->predecessors, entry) {
|
||||
nir_block *pred = (nir_block *)entry->key;
|
||||
nir_foreach_pred(pred, block) {
|
||||
if (pred->successors[0] && pred->successors[1]) {
|
||||
all_single_successors = false;
|
||||
break;
|
||||
|
|
@ -1022,9 +1021,8 @@ place_phi_read(nir_builder *b, nir_def *reg,
|
|||
*/
|
||||
_mesa_set_add(visited_blocks, block);
|
||||
|
||||
set_foreach(&block->predecessors, entry) {
|
||||
place_phi_read(b, reg, def, (nir_block *)entry->key, visited_blocks);
|
||||
}
|
||||
nir_foreach_pred(pred, block)
|
||||
place_phi_read(b, reg, def, pred, visited_blocks);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,9 +70,7 @@ nir_gs_count_vertices_and_primitives(const nir_shader *shader,
|
|||
/* set_vertex_and_primitive_count intrinsics only appear in predecessors of the
|
||||
* end block. So we don't need to walk all of them.
|
||||
*/
|
||||
set_foreach(&impl->end_block->predecessors, entry) {
|
||||
nir_block *block = (nir_block *)entry->key;
|
||||
|
||||
nir_foreach_pred(block, impl->end_block) {
|
||||
nir_foreach_instr_reverse(instr, block) {
|
||||
nir_intrinsic_instr *intrin = as_set_vertex_and_primitive_count(instr);
|
||||
if (!intrin)
|
||||
|
|
|
|||
|
|
@ -171,8 +171,7 @@ nir_live_defs_impl(nir_function_impl *impl)
|
|||
* changed, add the predecessor to the work list so that we ensure
|
||||
* that the new information is used.
|
||||
*/
|
||||
set_foreach(&block->predecessors, entry) {
|
||||
nir_block *pred = (nir_block *)entry->key;
|
||||
nir_foreach_pred(pred, block) {
|
||||
if (propagate_across_edge(pred, block, &state))
|
||||
nir_block_worklist_push_tail(&state.worklist, pred);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -409,7 +409,7 @@ nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables, bool use_vars,
|
|||
* if there is a good way to sanity check this, but for now the
|
||||
* users of this pass don't support sub-routines.
|
||||
*/
|
||||
assert(impl->end_block->predecessors.entries == 1);
|
||||
assert(nir_block_num_preds(impl->end_block) == 1);
|
||||
b.cursor = nir_after_impl(impl);
|
||||
|
||||
struct lower_clip_state state = { NULL };
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ simplify_loop(nir_loop *loop)
|
|||
nir_instr_remove(nir_block_last_instr(last));
|
||||
|
||||
/* If the loop has only the trivial continue, there is nothing to do. */
|
||||
if (!nir_block_ends_in_jump(last) && cont->predecessors.entries == 1)
|
||||
if (!nir_block_ends_in_jump(last) && nir_block_num_preds(cont) == 1)
|
||||
return;
|
||||
|
||||
struct loop_simplify_state state;
|
||||
|
|
@ -240,7 +240,7 @@ lower_loop_continue_block(nir_builder *b, nir_loop *loop)
|
|||
nir_cf_list extracted;
|
||||
nir_cf_list_extract(&extracted, &loop->continue_list);
|
||||
|
||||
if (nir_loop_first_continue_block(loop)->predecessors.entries == 0) {
|
||||
if (nir_block_num_preds(nir_loop_first_continue_block(loop)) == 0) {
|
||||
/* This loop doesn't continue at all. Delete the continue construct. */
|
||||
nir_cf_delete(&extracted);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
*/
|
||||
|
||||
#include "compiler/nir/nir_builder.h"
|
||||
#include "util/set.h"
|
||||
#include "nir.h"
|
||||
|
||||
/**
|
||||
|
|
@ -70,8 +69,8 @@ move_out_of_loop(nir_builder *b, nir_intrinsic_instr *instr)
|
|||
b->cursor = nir_before_cf_node(node);
|
||||
nir_def *false_val = nir_imm_false(b);
|
||||
nir_block *after_loop = nir_cf_node_cf_tree_next(node);
|
||||
set_foreach(&after_loop->predecessors, entry) {
|
||||
nir_phi_instr_add_src(phi_instr, (nir_block *)entry->key, false_val);
|
||||
nir_foreach_pred(pred, after_loop) {
|
||||
nir_phi_instr_add_src(phi_instr, pred, false_val);
|
||||
}
|
||||
|
||||
/* Break if terminate. */
|
||||
|
|
|
|||
|
|
@ -268,8 +268,7 @@ append_set_vertex_and_primitive_count(nir_block *end_block, struct state *state)
|
|||
/* Insert the new intrinsic in all of the predecessors of the end block,
|
||||
* but before any jump instructions (return).
|
||||
*/
|
||||
set_foreach(&end_block->predecessors, entry) {
|
||||
nir_block *pred = (nir_block *)entry->key;
|
||||
nir_foreach_pred(pred, end_block) {
|
||||
b->cursor = nir_after_block_before_jump(pred);
|
||||
|
||||
for (unsigned stream = 0; stream < NIR_MAX_XFB_STREAMS; ++stream) {
|
||||
|
|
@ -319,9 +318,7 @@ append_set_vertex_and_primitive_count(nir_block *end_block, struct state *state)
|
|||
static bool
|
||||
a_block_needs_set_vertex_and_primitive_count(nir_block *end_block, bool per_stream)
|
||||
{
|
||||
set_foreach(&end_block->predecessors, entry) {
|
||||
nir_block *pred = (nir_block *)entry->key;
|
||||
|
||||
nir_foreach_pred(pred, end_block) {
|
||||
for (unsigned stream = 0; stream < NIR_MAX_XFB_STREAMS; ++stream) {
|
||||
/* When it's not per-stream, we only need to write one variable. */
|
||||
if (!per_stream && stream != 0)
|
||||
|
|
|
|||
|
|
@ -137,8 +137,7 @@ emit_output_copies_impl(struct lower_io_state *state, nir_function_impl *impl)
|
|||
/* For all other shader types, we need to do the copies right before
|
||||
* the jumps to the end block.
|
||||
*/
|
||||
set_foreach(&impl->end_block->predecessors, block_entry) {
|
||||
struct nir_block *block = (void *)block_entry->key;
|
||||
nir_foreach_pred(block, impl->end_block) {
|
||||
b.cursor = nir_after_block_before_jump(block);
|
||||
emit_copies(&b, &state->new_outputs, &state->old_outputs, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ lower_returns_in_if(nir_if *if_stmt, struct lower_returns_state *state)
|
|||
static bool
|
||||
lower_returns_in_block(nir_block *block, struct lower_returns_state *state)
|
||||
{
|
||||
if (block->predecessors.entries == 0 &&
|
||||
if (nir_block_num_preds(block) == 0 &&
|
||||
block != nir_start_block(state->builder.impl)) {
|
||||
/* This block is unreachable. Delete it and everything after it. */
|
||||
nir_cf_list list;
|
||||
|
|
|
|||
|
|
@ -181,9 +181,8 @@ dce_cf_list(struct exec_list *cf_list, BITSET_WORD *defs_live,
|
|||
/* Fast path if the loop has no continues: we can remove instructions
|
||||
* as we mark the others live.
|
||||
*/
|
||||
struct set *predecessors = &nir_loop_first_block(loop)->predecessors;
|
||||
if (predecessors->entries == 1 &&
|
||||
_mesa_set_next_entry(predecessors, NULL)->key == inner_state.preheader) {
|
||||
nir_block *header = nir_loop_first_block(loop);
|
||||
if (nir_block_num_preds(header) == 1 && nir_block_has_pred(header, inner_state.preheader)) {
|
||||
progress |= dce_cf_list(&loop->body, defs_live, parent_loop, dead_instrs);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -369,7 +369,7 @@ dead_cf_list(struct exec_list *list, bool *list_ends_in_jump)
|
|||
progress |= dead_cf_list(&loop->body, &dummy);
|
||||
|
||||
nir_block *next = nir_cf_node_as_block(nir_cf_node_next(cur));
|
||||
if (next->predecessors.entries == 0 &&
|
||||
if (nir_block_num_preds(next) == 0 &&
|
||||
(!exec_list_is_empty(&next->instr_list) ||
|
||||
!exec_node_is_tail_sentinel(next->cf_node.node.next))) {
|
||||
nir_remove_after_cf_node(cur);
|
||||
|
|
|
|||
|
|
@ -42,11 +42,11 @@ find_continue_block(nir_loop *loop)
|
|||
nir_block *prev_block =
|
||||
nir_cf_node_as_block(nir_cf_node_prev(&loop->cf_node));
|
||||
|
||||
assert(header_block->predecessors.entries == 2);
|
||||
assert(nir_block_num_preds(header_block) == 2);
|
||||
|
||||
set_foreach(&header_block->predecessors, pred_entry) {
|
||||
if (pred_entry->key != prev_block)
|
||||
return (nir_block *)pred_entry->key;
|
||||
nir_foreach_pred(pred, header_block) {
|
||||
if (pred != prev_block)
|
||||
return pred;
|
||||
}
|
||||
|
||||
UNREACHABLE("Continue block not found!");
|
||||
|
|
@ -143,13 +143,13 @@ opt_peel_loop_initial_if(nir_loop *loop)
|
|||
nir_cf_node_as_block(nir_cf_node_prev(&loop->cf_node));
|
||||
|
||||
/* It would be insane if this were not true */
|
||||
assert(_mesa_set_search(&header_block->predecessors, prev_block));
|
||||
assert(nir_block_has_pred(header_block, prev_block));
|
||||
|
||||
/* The loop must have exactly one continue block which could be a block
|
||||
* ending in a continue instruction or the "natural" continue from the
|
||||
* last block in the loop back to the top.
|
||||
*/
|
||||
if (header_block->predecessors.entries != 2)
|
||||
if (nir_block_num_preds(header_block) != 2)
|
||||
return false;
|
||||
|
||||
nir_cf_node *if_node = nir_cf_node_next(&header_block->cf_node);
|
||||
|
|
@ -375,13 +375,13 @@ opt_split_alu_of_phi(nir_builder *b, nir_loop *loop, nir_opt_if_options options)
|
|||
nir_cf_node_as_block(nir_cf_node_prev(&loop->cf_node));
|
||||
|
||||
/* It would be insane if this were not true */
|
||||
assert(_mesa_set_search(&header_block->predecessors, prev_block));
|
||||
assert(nir_block_has_pred(header_block, prev_block));
|
||||
|
||||
/* The loop must have exactly one continue block which could be a block
|
||||
* ending in a continue instruction or the "natural" continue from the
|
||||
* last block in the loop back to the top.
|
||||
*/
|
||||
if (header_block->predecessors.entries != 2)
|
||||
if (nir_block_num_preds(header_block) != 2)
|
||||
return false;
|
||||
|
||||
nir_block *continue_block = find_continue_block(loop);
|
||||
|
|
@ -611,13 +611,13 @@ opt_simplify_bcsel_of_phi(nir_builder *b, nir_loop *loop)
|
|||
nir_cf_node_as_block(nir_cf_node_prev(&loop->cf_node));
|
||||
|
||||
/* It would be insane if this were not true */
|
||||
assert(_mesa_set_search(&header_block->predecessors, prev_block));
|
||||
assert(nir_block_has_pred(header_block, prev_block));
|
||||
|
||||
/* The loop must have exactly one continue block which could be a block
|
||||
* ending in a continue instruction or the "natural" continue from the
|
||||
* last block in the loop back to the top.
|
||||
*/
|
||||
if (header_block->predecessors.entries != 2)
|
||||
if (nir_block_num_preds(header_block) != 2)
|
||||
return false;
|
||||
|
||||
/* We can move any bcsel that can guaranteed to execut on every iteration
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ static bool
|
|||
should_optimize_loop(nir_loop *loop)
|
||||
{
|
||||
/* Ignore loops without back-edge */
|
||||
if (nir_loop_first_block(loop)->predecessors.entries == 1)
|
||||
if (nir_block_num_preds(nir_loop_first_block(loop)) == 1)
|
||||
return false;
|
||||
|
||||
nir_foreach_block_in_cf_node(block, &loop->cf_node) {
|
||||
|
|
|
|||
|
|
@ -1865,15 +1865,13 @@ add_entries_from_predecessor(struct vectorize_ctx *ctx, nir_block *block)
|
|||
|
||||
/* If this isn't reorderable, we would have to consider the loop back-edges to safely use
|
||||
* it, in case there is an interfering store in the loop. */
|
||||
bool has_continue = block->predecessors.entries > 1 ||
|
||||
_mesa_set_next_entry(&block->predecessors, NULL)->key != preheader;
|
||||
bool has_continue = nir_block_num_preds(block) > 1 || !nir_block_has_pred(block, preheader);
|
||||
if (entry && !(entry->access & ACCESS_CAN_REORDER) && has_continue)
|
||||
entry = NULL;
|
||||
} else {
|
||||
/* If all predecessor entries are the same, the entry dominates the block. */
|
||||
bool first_entry = true;
|
||||
set_foreach(&block->predecessors, set_entry) {
|
||||
nir_block *pred = (nir_block *)set_entry->key;
|
||||
nir_foreach_pred(pred, block) {
|
||||
if (!first_entry && entry != ctx->per_block_ctx[pred->index].last_entry[i]) {
|
||||
entry = NULL;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ opt_loop_merge_break_continue(nir_if *nif)
|
|||
nir_block *after_if = nir_cf_node_cf_tree_next(&nif->cf_node);
|
||||
|
||||
/* The block after the IF must have no predecessors and be empty. */
|
||||
if (after_if->predecessors.entries > 0 || !is_block_empty(after_if))
|
||||
if (nir_block_num_preds(after_if) > 0 || !is_block_empty(after_if))
|
||||
return false;
|
||||
|
||||
nir_block *last_then = nir_if_last_then_block(nif);
|
||||
|
|
@ -209,7 +209,7 @@ static bool
|
|||
opt_loop_last_block(nir_block *block, bool is_trivial_continue, bool is_trivial_break)
|
||||
{
|
||||
/* If this block has no predecessors, let nir_opt_dead_cf() do the cleanup */
|
||||
if (block->predecessors.entries == 0)
|
||||
if (nir_block_num_preds(block) == 0)
|
||||
return false;
|
||||
|
||||
bool progress = false;
|
||||
|
|
@ -379,7 +379,7 @@ opt_loop_peel_initial_break(nir_loop *loop)
|
|||
nir_block *exit_block = nir_cf_node_cf_tree_next(&loop->cf_node);
|
||||
|
||||
/* The loop must have exactly one continue block. */
|
||||
if (header_block->predecessors.entries != 2)
|
||||
if (nir_block_num_preds(header_block) != 2)
|
||||
return false;
|
||||
|
||||
nir_cf_node *if_node = nir_cf_node_next(&header_block->cf_node);
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ nir_opt_remove_phis(nir_shader *shader)
|
|||
bool
|
||||
nir_remove_single_src_phis_block(nir_block *block)
|
||||
{
|
||||
assert(block->predecessors.entries <= 1);
|
||||
assert(nir_block_num_preds(block) <= 1);
|
||||
bool progress = false;
|
||||
nir_foreach_phi_safe(phi, block) {
|
||||
nir_def *def = NULL;
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ get_innermost_loop(nir_cf_node *node)
|
|||
for (; node != NULL; node = node->parent) {
|
||||
if (node->type == nir_cf_node_loop) {
|
||||
nir_loop *loop = nir_cf_node_as_loop(node);
|
||||
if (nir_loop_first_block(loop)->predecessors.entries > 1)
|
||||
if (nir_block_num_preds(nir_loop_first_block(loop)) > 1)
|
||||
return loop;
|
||||
}
|
||||
}
|
||||
|
|
@ -342,7 +342,7 @@ adjust_block_for_loops(nir_block *use_block, nir_block *def_block,
|
|||
|
||||
nir_cf_node *next = nir_cf_node_next(&cur_block->cf_node);
|
||||
if (next && next->type == nir_cf_node_loop &&
|
||||
nir_block_cf_tree_next(cur_block)->predecessors.entries > 1) {
|
||||
nir_block_num_preds(nir_block_cf_tree_next(cur_block)) > 1) {
|
||||
nir_loop *following_loop = nir_cf_node_as_loop(next);
|
||||
if (loop_contains_block(following_loop, use_block)) {
|
||||
use_block = cur_block;
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ nir_phi_builder_finish(struct nir_phi_builder *pb)
|
|||
/* XXX: Constructing the array this many times seems expensive. */
|
||||
nir_block **preds = nir_block_get_predecessors_sorted(phi->instr.block, pb);
|
||||
|
||||
for (unsigned i = 0; i < phi->instr.block->predecessors.entries; i++) {
|
||||
for (unsigned i = 0; i < nir_block_num_preds(phi->instr.block); i++) {
|
||||
nir_phi_instr_add_src(phi, preds[i],
|
||||
nir_phi_builder_value_get_block_def(val, preds[i]));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2286,7 +2286,7 @@ print_phi_instr(nir_phi_instr *instr, print_state *state)
|
|||
nir_block **preds =
|
||||
state->preds ? state->preds : nir_block_get_predecessors_sorted(instr->instr.block, NULL);
|
||||
|
||||
for (unsigned i = 0; i < instr->instr.block->predecessors.entries; i++) {
|
||||
for (unsigned i = 0; i < nir_block_num_preds(instr->instr.block); i++) {
|
||||
nir_phi_src *src = nir_phi_get_src_from_block(instr, preds[i]);
|
||||
if (i != 0)
|
||||
fprintf(fp, ", ");
|
||||
|
|
@ -2425,7 +2425,7 @@ static void
|
|||
print_block_preds(nir_block *block, print_state *state)
|
||||
{
|
||||
FILE *fp = state->fp;
|
||||
for (unsigned i = 0; i < block->predecessors.entries; i++) {
|
||||
for (unsigned i = 0; i < nir_block_num_preds(block); i++) {
|
||||
fprintf(fp, " b%u", state->preds[i]->index);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ convert_loop_exit_for_ssa(nir_def *def, void *void_state)
|
|||
/* Create a phi node with as many sources pointing to the same ssa_def as
|
||||
* the block has predecessors.
|
||||
*/
|
||||
uint32_t num_exits = state->block_after_loop->predecessors.entries;
|
||||
uint32_t num_exits = nir_block_num_preds(state->block_after_loop);
|
||||
for (uint32_t i = 0; i < num_exits; i++) {
|
||||
nir_phi_instr_add_src(phi, state->exit_blocks[i], def);
|
||||
}
|
||||
|
|
@ -342,7 +342,7 @@ convert_to_lcssa(nir_cf_node *cf_node, lcssa_state *state)
|
|||
* The variance then depends on all (nested) break conditions.
|
||||
* We don't consider this, but assume all not_invariant.
|
||||
*/
|
||||
if (nir_loop_first_block(loop)->predecessors.entries == 1)
|
||||
if (nir_block_num_preds(nir_loop_first_block(loop)) == 1)
|
||||
goto end;
|
||||
|
||||
nir_foreach_block_in_cf_node(block, cf_node) {
|
||||
|
|
|
|||
|
|
@ -1227,7 +1227,7 @@ validate_phi_instr(nir_phi_instr *instr, validate_state *state)
|
|||
|
||||
exec_list_validate(&instr->srcs);
|
||||
validate_assert(state, exec_list_length(&instr->srcs) ==
|
||||
state->block->predecessors.entries);
|
||||
nir_block_num_preds(state->block));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1473,17 +1473,16 @@ validate_block_predecessors(nir_block *block, validate_state *state)
|
|||
|
||||
/* And we have to be in our successor's predecessors set */
|
||||
validate_assert(state,
|
||||
_mesa_set_search(&block->successors[i]->predecessors, block));
|
||||
nir_block_has_pred(block->successors[i], block));
|
||||
|
||||
validate_phi_srcs(block, block->successors[i], state);
|
||||
}
|
||||
|
||||
/* The start block cannot have any predecessors */
|
||||
if (block == nir_start_block(state->impl))
|
||||
validate_assert(state, block->predecessors.entries == 0);
|
||||
validate_assert(state, nir_block_num_preds(block) == 0);
|
||||
|
||||
set_foreach(&block->predecessors, entry) {
|
||||
const nir_block *pred = entry->key;
|
||||
nir_foreach_pred(pred, block) {
|
||||
validate_assert(state, _mesa_set_search(state->blocks, pred));
|
||||
validate_assert(state, pred->successors[0] == block ||
|
||||
pred->successors[1] == block);
|
||||
|
|
@ -1631,7 +1630,7 @@ validate_loop(nir_loop *loop, validate_state *state)
|
|||
validate_assert(state, next_node->type == nir_cf_node_block);
|
||||
|
||||
validate_assert(state, !exec_list_is_empty(&loop->body));
|
||||
validate_assert(state, nir_loop_first_block(loop)->predecessors.entries <= 2);
|
||||
validate_assert(state, nir_block_num_preds(nir_loop_first_block(loop)) <= 2);
|
||||
|
||||
nir_cf_node *old_parent = state->parent_node;
|
||||
state->parent_node = &loop->cf_node;
|
||||
|
|
|
|||
|
|
@ -81,13 +81,13 @@ TEST_F(nir_cf_test, delete_break_in_loop)
|
|||
EXPECT_EQ(NULL, block_2->successors[1]);
|
||||
EXPECT_EQ(NULL, block_3->successors[0]);
|
||||
EXPECT_EQ(NULL, block_3->successors[1]);
|
||||
EXPECT_EQ(0, block_0->predecessors.entries);
|
||||
EXPECT_EQ(1, block_1->predecessors.entries);
|
||||
EXPECT_EQ(1, block_2->predecessors.entries);
|
||||
EXPECT_EQ(1, block_3->predecessors.entries);
|
||||
EXPECT_TRUE(_mesa_set_search(&block_1->predecessors, block_0));
|
||||
EXPECT_TRUE(_mesa_set_search(&block_2->predecessors, block_1));
|
||||
EXPECT_TRUE(_mesa_set_search(&block_3->predecessors, block_2));
|
||||
EXPECT_EQ(0, nir_block_num_preds(block_0));
|
||||
EXPECT_EQ(1, nir_block_num_preds(block_1));
|
||||
EXPECT_EQ(1, nir_block_num_preds(block_2));
|
||||
EXPECT_EQ(1, nir_block_num_preds(block_3));
|
||||
EXPECT_TRUE(nir_block_has_pred(block_1, block_0));
|
||||
EXPECT_TRUE(nir_block_has_pred(block_2, block_1));
|
||||
EXPECT_TRUE(nir_block_has_pred(block_3, block_2));
|
||||
|
||||
/* Now remove the break. */
|
||||
nir_instr_remove(&jump->instr);
|
||||
|
|
@ -119,14 +119,14 @@ TEST_F(nir_cf_test, delete_break_in_loop)
|
|||
EXPECT_EQ(NULL, block_2->successors[1]);
|
||||
EXPECT_EQ(NULL, block_3->successors[0]);
|
||||
EXPECT_EQ(NULL, block_3->successors[1]);
|
||||
EXPECT_EQ(0, block_0->predecessors.entries);
|
||||
EXPECT_EQ(2, block_1->predecessors.entries);
|
||||
EXPECT_EQ(0, block_2->predecessors.entries);
|
||||
EXPECT_EQ(1, block_3->predecessors.entries);
|
||||
EXPECT_TRUE(_mesa_set_search(&block_1->predecessors, block_0));
|
||||
EXPECT_TRUE(_mesa_set_search(&block_1->predecessors, block_1));
|
||||
EXPECT_FALSE(_mesa_set_search(&block_2->predecessors, block_1));
|
||||
EXPECT_TRUE(_mesa_set_search(&block_3->predecessors, block_2));
|
||||
EXPECT_EQ(0, nir_block_num_preds(block_0));
|
||||
EXPECT_EQ(2, nir_block_num_preds(block_1));
|
||||
EXPECT_EQ(0, nir_block_num_preds(block_2));
|
||||
EXPECT_EQ(1, nir_block_num_preds(block_3));
|
||||
EXPECT_TRUE(nir_block_has_pred(block_1, block_0));
|
||||
EXPECT_TRUE(nir_block_has_pred(block_1, block_1));
|
||||
EXPECT_FALSE(nir_block_has_pred(block_2, block_1));
|
||||
EXPECT_TRUE(nir_block_has_pred(block_3, block_2));
|
||||
|
||||
nir_metadata_require(b->impl, nir_metadata_dominance);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4842,14 +4842,13 @@ has_nontrivial_continue(nir_loop *nloop)
|
|||
* is more than one backedge from inside the loop (so more than 2 total
|
||||
* edges) then one must be a nontrivial continue.
|
||||
*/
|
||||
if (nstart->predecessors.entries > 2)
|
||||
if (nir_block_num_preds(nstart) > 2)
|
||||
return true;
|
||||
|
||||
/* Check whether the one backedge is a nontrivial continue. This can happen
|
||||
* if the loop ends with a break.
|
||||
*/
|
||||
set_foreach (&nstart->predecessors, entry) {
|
||||
nir_block *pred = (nir_block*)entry->key;
|
||||
nir_foreach_pred (pred, nstart) {
|
||||
if (pred == nir_loop_last_block(nloop) ||
|
||||
pred == nir_cf_node_as_block(nir_cf_node_prev(&nloop->cf_node)))
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -1057,7 +1057,7 @@ ir3_nir_lower_gs(nir_shader *shader)
|
|||
* them to this new if statement, rather than emitting this code at every
|
||||
* return statement.
|
||||
*/
|
||||
assert(impl->end_block->predecessors.entries == 1);
|
||||
assert(nir_block_num_preds(impl->end_block) == 1);
|
||||
nir_block *block = nir_impl_last_block(impl);
|
||||
b.cursor = nir_after_block_before_jump(block);
|
||||
|
||||
|
|
|
|||
|
|
@ -448,10 +448,8 @@ ntt_live_regs(struct ntt_compile *c, nir_function_impl *impl)
|
|||
~bs->livein[i]);
|
||||
if (new_livein) {
|
||||
bs->livein[i] |= new_livein;
|
||||
set_foreach(&block->predecessors, entry) {
|
||||
nir_block *pred = (void *)entry->key;
|
||||
nir_foreach_pred(pred, block)
|
||||
nir_block_worklist_push_tail(&state.worklist, pred);
|
||||
}
|
||||
|
||||
if (new_livein & state.blocks[block->index].defin[i])
|
||||
c->liveness[i].start = MIN2(c->liveness[i].start, ntt_block->start_ip);
|
||||
|
|
|
|||
|
|
@ -223,8 +223,7 @@ etna_live_defs(nir_function_impl *impl, struct live_def *defs, unsigned *live_ma
|
|||
* changed, add the predecessor to the work list so that we ensure
|
||||
* that the new information is used.
|
||||
*/
|
||||
set_foreach(&block->predecessors, entry) {
|
||||
nir_block *pred = (nir_block *)entry->key;
|
||||
nir_foreach_pred(pred, block) {
|
||||
if (propagate_across_edge(pred, block, &state))
|
||||
nir_block_worklist_push_tail(&state.worklist, pred);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1578,7 +1578,7 @@ Converter::visit(nir_cf_node *node)
|
|||
bool
|
||||
Converter::visit(nir_block *block)
|
||||
{
|
||||
if (!block->predecessors.entries && exec_list_is_empty(&block->instr_list))
|
||||
if (!nir_block_num_preds(block) && exec_list_is_empty(&block->instr_list))
|
||||
return true;
|
||||
|
||||
BasicBlock *bb = convert(block);
|
||||
|
|
|
|||
|
|
@ -2568,7 +2568,7 @@ clamp_layer_output(nir_shader *vs, nir_shader *fs, unsigned *next_location)
|
|||
nir_builder b;
|
||||
nir_function_impl *impl = nir_shader_get_entrypoint(vs);
|
||||
b = nir_builder_at(nir_after_impl(impl));
|
||||
assert(impl->end_block->predecessors.entries == 1);
|
||||
assert(nir_block_num_preds(impl->end_block) == 1);
|
||||
clamp_layer_output_emit(&b, var);
|
||||
nir_progress(true, impl, nir_metadata_control_flow);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,9 +153,8 @@ brw_nir_lower_intersection_shader(nir_shader *intersection,
|
|||
nir_local_variable_create(impl, glsl_bool_type(), "ray_commit");
|
||||
nir_store_var(b, commit, nir_imm_false(b), 0x1);
|
||||
|
||||
assert(impl->end_block->predecessors.entries == 1);
|
||||
set_foreach(&impl->end_block->predecessors, block_entry) {
|
||||
struct nir_block *block = (void *)block_entry->key;
|
||||
assert(nir_block_num_preds(impl->end_block) == 1);
|
||||
nir_foreach_pred(block, impl->end_block) {
|
||||
b->cursor = nir_after_block_before_jump(block);
|
||||
nir_push_if(b, nir_load_var(b, commit));
|
||||
{
|
||||
|
|
|
|||
|
|
@ -53,8 +53,7 @@ brw_nir_lower_shader_returns(nir_shader *shader)
|
|||
|
||||
nir_builder b = nir_builder_create(impl);
|
||||
|
||||
set_foreach(&impl->end_block->predecessors, block_entry) {
|
||||
struct nir_block *block = (void *)block_entry->key;
|
||||
nir_foreach_pred(block, impl->end_block) {
|
||||
b.cursor = nir_after_block_before_jump(block);
|
||||
|
||||
switch (shader->info.stage) {
|
||||
|
|
@ -63,7 +62,7 @@ brw_nir_lower_shader_returns(nir_shader *shader)
|
|||
* it ends, we retire the bindless stack ID and no further shaders
|
||||
* will be executed.
|
||||
*/
|
||||
assert(impl->end_block->predecessors.entries == 1);
|
||||
assert(nir_block_num_preds(impl->end_block) == 1);
|
||||
brw_nir_btd_retire(&b);
|
||||
break;
|
||||
|
||||
|
|
@ -86,7 +85,7 @@ brw_nir_lower_shader_returns(nir_shader *shader)
|
|||
* action at the end. They simply return back to the previous shader
|
||||
* in the call stack.
|
||||
*/
|
||||
assert(impl->end_block->predecessors.entries == 1);
|
||||
assert(nir_block_num_preds(impl->end_block) == 1);
|
||||
brw_nir_btd_return(&b);
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -101,12 +101,12 @@ intel_nir_apply_tcs_quads_workaround(nir_shader *nir)
|
|||
* the end block. We want to process the original set, so to be safe,
|
||||
* save it off to an array first.
|
||||
*/
|
||||
const unsigned num_end_preds = impl->end_block->predecessors.entries;
|
||||
const unsigned num_end_preds = nir_block_num_preds(impl->end_block);
|
||||
nir_block *end_preds[num_end_preds];
|
||||
unsigned i = 0;
|
||||
|
||||
set_foreach(&impl->end_block->predecessors, entry) {
|
||||
end_preds[i++] = (nir_block *) entry->key;
|
||||
nir_foreach_pred(pred, impl->end_block) {
|
||||
end_preds[i++] = pred;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_end_preds; i++) {
|
||||
|
|
|
|||
|
|
@ -238,9 +238,7 @@ block_is_merge(const nir_block *block)
|
|||
return false;
|
||||
|
||||
unsigned num_preds = 0;
|
||||
set_foreach(&block->predecessors, entry) {
|
||||
const nir_block *pred = entry->key;
|
||||
|
||||
nir_foreach_pred(pred, block) {
|
||||
/* We don't care about unreachable blocks */
|
||||
if (pred->imm_dom == NULL)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -69,8 +69,7 @@ append_final_primitive_nv(nir_block *end_block, struct state *state)
|
|||
{
|
||||
nir_builder *b = state->builder;
|
||||
|
||||
set_foreach(&end_block->predecessors, entry) {
|
||||
nir_block *pred = (nir_block *)entry->key;
|
||||
nir_foreach_pred(pred, end_block) {
|
||||
b->cursor = nir_after_block_before_jump(pred);
|
||||
|
||||
nir_def *gs_handle = nir_load_var(b, state->handle_var);
|
||||
|
|
@ -122,4 +121,4 @@ nak_nir_lower_gs_intrinsics(nir_shader *nir)
|
|||
nir_progress(true, impl, nir_metadata_none);
|
||||
|
||||
return state.progress;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue