From 2ed17d46de045404042f13c6591895a1cf31b167 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Wed, 5 Oct 2016 19:08:57 -0700 Subject: [PATCH] nir: Make nir_foo_first/last_cf_node return a block instead One of NIR's invariants is that control flow lists always start and end with blocks. There's no good reason why we should return a cf_node from these functions since we know that it's always a block. Making it a block lets us remove a bunch of code. Signed-off-by: Jason Ekstrand Reviewed-by: Connor Abbott --- src/compiler/nir/nir.c | 20 ++--- src/compiler/nir/nir.h | 82 ++++++++++--------- src/compiler/nir/nir_control_flow.c | 43 +++------- src/compiler/nir/nir_lower_indirect_derefs.c | 4 +- src/compiler/nir/nir_opt_dead_cf.c | 5 +- src/compiler/nir/nir_opt_peephole_select.c | 11 +-- src/compiler/nir/nir_validate.c | 18 ++-- .../freedreno/ir3/ir3_nir_lower_if_else.c | 11 +-- src/gallium/drivers/vc4/vc4_program.c | 6 +- 9 files changed, 84 insertions(+), 116 deletions(-) diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index 13ba989af4b..098e1b2759e 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -1646,10 +1646,10 @@ nir_block_cf_tree_next(nir_block *block) case nir_cf_node_if: { /* Are we at the end of the if? Go to the beginning of the else */ nir_if *if_stmt = nir_cf_node_as_if(parent); - if (&block->cf_node == nir_if_last_then_node(if_stmt)) - return nir_cf_node_as_block(nir_if_first_else_node(if_stmt)); + if (block == nir_if_last_then_block(if_stmt)) + return nir_if_first_else_block(if_stmt); - assert(&block->cf_node == nir_if_last_else_node(if_stmt)); + assert(block == nir_if_last_else_block(if_stmt)); /* fall through */ } @@ -1682,10 +1682,10 @@ nir_block_cf_tree_prev(nir_block *block) case nir_cf_node_if: { /* Are we at the beginning of the else? Go to the end of the if */ nir_if *if_stmt = nir_cf_node_as_if(parent); - if (&block->cf_node == nir_if_first_else_node(if_stmt)) - return nir_cf_node_as_block(nir_if_last_then_node(if_stmt)); + if (block == nir_if_first_else_block(if_stmt)) + return nir_if_last_then_block(if_stmt); - assert(&block->cf_node == nir_if_first_then_node(if_stmt)); + assert(block == nir_if_first_then_block(if_stmt)); /* fall through */ } @@ -1710,12 +1710,12 @@ nir_block *nir_cf_node_cf_tree_first(nir_cf_node *node) case nir_cf_node_if: { nir_if *if_stmt = nir_cf_node_as_if(node); - return nir_cf_node_as_block(nir_if_first_then_node(if_stmt)); + return nir_if_first_then_block(if_stmt); } case nir_cf_node_loop: { nir_loop *loop = nir_cf_node_as_loop(node); - return nir_cf_node_as_block(nir_loop_first_cf_node(loop)); + return nir_loop_first_block(loop); } case nir_cf_node_block: { @@ -1737,12 +1737,12 @@ nir_block *nir_cf_node_cf_tree_last(nir_cf_node *node) case nir_cf_node_if: { nir_if *if_stmt = nir_cf_node_as_if(node); - return nir_cf_node_as_block(nir_if_last_else_node(if_stmt)); + return nir_if_last_else_block(if_stmt); } case nir_cf_node_loop: { nir_loop *loop = nir_cf_node_as_loop(node); - return nir_cf_node_as_block(nir_loop_last_cf_node(loop)); + return nir_loop_last_block(loop); } case nir_cf_node_block: { diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index a122f12d079..8a9ccf28971 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -1537,52 +1537,12 @@ typedef struct nir_if { struct exec_list else_list; /** < list of nir_cf_node */ } nir_if; -static inline nir_cf_node * -nir_if_first_then_node(nir_if *if_stmt) -{ - struct exec_node *head = exec_list_get_head(&if_stmt->then_list); - return exec_node_data(nir_cf_node, head, node); -} - -static inline nir_cf_node * -nir_if_last_then_node(nir_if *if_stmt) -{ - struct exec_node *tail = exec_list_get_tail(&if_stmt->then_list); - return exec_node_data(nir_cf_node, tail, node); -} - -static inline nir_cf_node * -nir_if_first_else_node(nir_if *if_stmt) -{ - struct exec_node *head = exec_list_get_head(&if_stmt->else_list); - return exec_node_data(nir_cf_node, head, node); -} - -static inline nir_cf_node * -nir_if_last_else_node(nir_if *if_stmt) -{ - struct exec_node *tail = exec_list_get_tail(&if_stmt->else_list); - return exec_node_data(nir_cf_node, tail, node); -} - typedef struct { nir_cf_node cf_node; struct exec_list body; /** < list of nir_cf_node */ } nir_loop; -static inline nir_cf_node * -nir_loop_first_cf_node(nir_loop *loop) -{ - return exec_node_data(nir_cf_node, exec_list_get_head(&loop->body), node); -} - -static inline nir_cf_node * -nir_loop_last_cf_node(nir_loop *loop) -{ - return exec_node_data(nir_cf_node, exec_list_get_tail(&loop->body), node); -} - /** * Various bits of metadata that can may be created or required by * optimization and analysis passes @@ -1683,6 +1643,48 @@ NIR_DEFINE_CAST(nir_cf_node_as_loop, nir_cf_node, nir_loop, cf_node, NIR_DEFINE_CAST(nir_cf_node_as_function, nir_cf_node, nir_function_impl, cf_node, type, nir_cf_node_function) +static inline nir_block * +nir_if_first_then_block(nir_if *if_stmt) +{ + struct exec_node *head = exec_list_get_head(&if_stmt->then_list); + return nir_cf_node_as_block(exec_node_data(nir_cf_node, head, node)); +} + +static inline nir_block * +nir_if_last_then_block(nir_if *if_stmt) +{ + struct exec_node *tail = exec_list_get_tail(&if_stmt->then_list); + return nir_cf_node_as_block(exec_node_data(nir_cf_node, tail, node)); +} + +static inline nir_block * +nir_if_first_else_block(nir_if *if_stmt) +{ + struct exec_node *head = exec_list_get_head(&if_stmt->else_list); + return nir_cf_node_as_block(exec_node_data(nir_cf_node, head, node)); +} + +static inline nir_block * +nir_if_last_else_block(nir_if *if_stmt) +{ + struct exec_node *tail = exec_list_get_tail(&if_stmt->else_list); + return nir_cf_node_as_block(exec_node_data(nir_cf_node, tail, node)); +} + +static inline nir_block * +nir_loop_first_block(nir_loop *loop) +{ + struct exec_node *head = exec_list_get_head(&loop->body); + return nir_cf_node_as_block(exec_node_data(nir_cf_node, head, node)); +} + +static inline nir_block * +nir_loop_last_block(nir_loop *loop) +{ + struct exec_node *tail = exec_list_get_tail(&loop->body); + return nir_cf_node_as_block(exec_node_data(nir_cf_node, tail, node)); +} + typedef enum { nir_parameter_in, nir_parameter_out, diff --git a/src/compiler/nir/nir_control_flow.c b/src/compiler/nir/nir_control_flow.c index 1ff7a530f25..380e8aa07c9 100644 --- a/src/compiler/nir/nir_control_flow.c +++ b/src/compiler/nir/nir_control_flow.c @@ -114,13 +114,8 @@ link_non_block_to_block(nir_cf_node *node, nir_block *block) nir_if *if_stmt = nir_cf_node_as_if(node); - nir_cf_node *last_then = nir_if_last_then_node(if_stmt); - assert(last_then->type == nir_cf_node_block); - nir_block *last_then_block = nir_cf_node_as_block(last_then); - - nir_cf_node *last_else = nir_if_last_else_node(if_stmt); - assert(last_else->type == nir_cf_node_block); - nir_block *last_else_block = nir_cf_node_as_block(last_else); + nir_block *last_then_block = nir_if_last_then_block(if_stmt); + nir_block *last_else_block = nir_if_last_else_block(if_stmt); if (!block_ends_in_jump(last_then_block)) { unlink_block_successors(last_then_block); @@ -147,13 +142,8 @@ link_block_to_non_block(nir_block *block, nir_cf_node *node) nir_if *if_stmt = nir_cf_node_as_if(node); - nir_cf_node *first_then = nir_if_first_then_node(if_stmt); - assert(first_then->type == nir_cf_node_block); - nir_block *first_then_block = nir_cf_node_as_block(first_then); - - nir_cf_node *first_else = nir_if_first_else_node(if_stmt); - assert(first_else->type == nir_cf_node_block); - nir_block *first_else_block = nir_cf_node_as_block(first_else); + nir_block *first_then_block = nir_if_first_then_block(if_stmt); + nir_block *first_else_block = nir_if_first_else_block(if_stmt); unlink_block_successors(block); link_blocks(block, first_then_block, first_else_block); @@ -168,9 +158,7 @@ link_block_to_non_block(nir_block *block, nir_cf_node *node) nir_loop *loop = nir_cf_node_as_loop(node); - nir_cf_node *loop_header = nir_loop_first_cf_node(loop); - assert(loop_header->type == nir_cf_node_block); - nir_block *loop_header_block = nir_cf_node_as_block(loop_header); + nir_block *loop_header_block = nir_loop_first_block(loop); unlink_block_successors(block); link_blocks(block, loop_header_block, NULL); @@ -319,9 +307,7 @@ block_add_normal_succs(nir_block *block) } else if (parent->type == nir_cf_node_loop) { nir_loop *loop = nir_cf_node_as_loop(parent); - nir_cf_node *head = nir_loop_first_cf_node(loop); - assert(head->type == nir_cf_node_block); - nir_block *head_block = nir_cf_node_as_block(head); + nir_block *head_block = nir_loop_first_block(loop); link_blocks(block, head_block, NULL); insert_phi_undef(head_block, block); @@ -335,22 +321,15 @@ block_add_normal_succs(nir_block *block) if (next->type == nir_cf_node_if) { nir_if *next_if = nir_cf_node_as_if(next); - nir_cf_node *first_then = nir_if_first_then_node(next_if); - assert(first_then->type == nir_cf_node_block); - nir_block *first_then_block = nir_cf_node_as_block(first_then); - - nir_cf_node *first_else = nir_if_first_else_node(next_if); - assert(first_else->type == nir_cf_node_block); - nir_block *first_else_block = nir_cf_node_as_block(first_else); + nir_block *first_then_block = nir_if_first_then_block(next_if); + nir_block *first_else_block = nir_if_first_else_block(next_if); link_blocks(block, first_then_block, first_else_block); } else { assert(next->type == nir_cf_node_loop); nir_loop *next_loop = nir_cf_node_as_loop(next); - nir_cf_node *first = nir_loop_first_cf_node(next_loop); - assert(first->type == nir_cf_node_block); - nir_block *first_block = nir_cf_node_as_block(first); + nir_block *first_block = nir_loop_first_block(next_loop); link_blocks(block, first_block, NULL); insert_phi_undef(first_block, block); @@ -490,9 +469,7 @@ nir_handle_add_jump(nir_block *block) nir_loop *loop = nearest_loop(&block->cf_node); if (jump_instr->type == nir_jump_continue) { - nir_cf_node *first_node = nir_loop_first_cf_node(loop); - assert(first_node->type == nir_cf_node_block); - nir_block *first_block = nir_cf_node_as_block(first_node); + nir_block *first_block = nir_loop_first_block(loop); link_blocks(block, first_block, NULL); } else { nir_cf_node *after = nir_cf_node_next(&loop->cf_node); diff --git a/src/compiler/nir/nir_lower_indirect_derefs.c b/src/compiler/nir/nir_lower_indirect_derefs.c index 1bf4bf66795..9c5349a772d 100644 --- a/src/compiler/nir/nir_lower_indirect_derefs.c +++ b/src/compiler/nir/nir_lower_indirect_derefs.c @@ -80,12 +80,12 @@ emit_indirect_load_store(nir_builder *b, nir_intrinsic_instr *orig_instr, then_dest->num_components, bit_size, NULL); nir_phi_src *src0 = ralloc(phi, nir_phi_src); - src0->pred = nir_cf_node_as_block(nir_if_last_then_node(if_stmt)); + src0->pred = nir_if_last_then_block(if_stmt); src0->src = nir_src_for_ssa(then_dest); exec_list_push_tail(&phi->srcs, &src0->node); nir_phi_src *src1 = ralloc(phi, nir_phi_src); - src1->pred = nir_cf_node_as_block(nir_if_last_else_node(if_stmt)); + src1->pred = nir_if_last_else_block(if_stmt); src1->src = nir_src_for_ssa(else_dest); exec_list_push_tail(&phi->srcs, &src1->node); diff --git a/src/compiler/nir/nir_opt_dead_cf.c b/src/compiler/nir/nir_opt_dead_cf.c index 1490e6832a2..53c92ecc286 100644 --- a/src/compiler/nir/nir_opt_dead_cf.c +++ b/src/compiler/nir/nir_opt_dead_cf.c @@ -87,9 +87,8 @@ opt_constant_if(nir_if *if_stmt, bool condition) * point to the correct source. */ nir_block *after = nir_cf_node_as_block(nir_cf_node_next(&if_stmt->cf_node)); - nir_block *last_block = - nir_cf_node_as_block(condition ? nir_if_last_then_node(if_stmt) - : nir_if_last_else_node(if_stmt)); + nir_block *last_block = condition ? nir_if_last_then_block(if_stmt) + : nir_if_last_else_block(if_stmt); nir_foreach_instr_safe(instr, after) { if (instr->type != nir_instr_type_phi) diff --git a/src/compiler/nir/nir_opt_peephole_select.c b/src/compiler/nir/nir_opt_peephole_select.c index 6a73d737077..29543d6be7a 100644 --- a/src/compiler/nir/nir_opt_peephole_select.c +++ b/src/compiler/nir/nir_opt_peephole_select.c @@ -157,17 +157,14 @@ nir_opt_peephole_select_block(nir_block *block, void *mem_ctx, unsigned limit) return false; nir_if *if_stmt = nir_cf_node_as_if(prev_node); - nir_cf_node *then_node = nir_if_first_then_node(if_stmt); - nir_cf_node *else_node = nir_if_first_else_node(if_stmt); + nir_block *then_block = nir_if_first_then_block(if_stmt); + nir_block *else_block = nir_if_first_else_block(if_stmt); /* We can only have one block in each side ... */ - if (nir_if_last_then_node(if_stmt) != then_node || - nir_if_last_else_node(if_stmt) != else_node) + if (nir_if_last_then_block(if_stmt) != then_block || + nir_if_last_else_block(if_stmt) != else_block) return false; - nir_block *then_block = nir_cf_node_as_block(then_node); - nir_block *else_block = nir_cf_node_as_block(else_node); - /* ... and those blocks must only contain "allowed" instructions. */ unsigned count = 0; if (!block_check_for_allowed_instrs(then_block, &count, limit != 0) || diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c index 60af71550ba..bd73f0437f2 100644 --- a/src/compiler/nir/nir_validate.c +++ b/src/compiler/nir/nir_validate.c @@ -705,8 +705,7 @@ validate_block(nir_block *block, validate_state *state) } case nir_jump_continue: { - nir_block *first = - nir_cf_node_as_block(nir_loop_first_cf_node(state->loop)); + nir_block *first = nir_loop_first_block(state->loop); validate_assert(state, block->successors[0] == first); break; } @@ -723,8 +722,7 @@ validate_block(nir_block *block, validate_state *state) if (next == NULL) { switch (state->parent_node->type) { case nir_cf_node_loop: { - nir_block *first = - nir_cf_node_as_block(nir_loop_first_cf_node(state->loop)); + nir_block *first = nir_loop_first_block(state->loop); validate_assert(state, block->successors[0] == first); /* due to the hack for infinite loops, block->successors[1] may * point to the block after the loop. @@ -751,15 +749,15 @@ validate_block(nir_block *block, validate_state *state) } else { if (next->type == nir_cf_node_if) { nir_if *if_stmt = nir_cf_node_as_if(next); - validate_assert(state, &block->successors[0]->cf_node == - nir_if_first_then_node(if_stmt)); - validate_assert(state, &block->successors[1]->cf_node == - nir_if_first_else_node(if_stmt)); + validate_assert(state, block->successors[0] == + nir_if_first_then_block(if_stmt)); + validate_assert(state, block->successors[1] == + nir_if_first_else_block(if_stmt)); } else { validate_assert(state, next->type == nir_cf_node_loop); nir_loop *loop = nir_cf_node_as_loop(next); - validate_assert(state, &block->successors[0]->cf_node == - nir_loop_first_cf_node(loop)); + validate_assert(state, block->successors[0] == + nir_loop_first_block(loop)); validate_assert(state, block->successors[1] == NULL); } } diff --git a/src/gallium/drivers/freedreno/ir3/ir3_nir_lower_if_else.c b/src/gallium/drivers/freedreno/ir3/ir3_nir_lower_if_else.c index 6e1395c9001..b781fa7663f 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_nir_lower_if_else.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_nir_lower_if_else.c @@ -224,17 +224,14 @@ lower_if_else_block(nir_block *block, nir_builder *b, void *mem_ctx) return false; nir_if *if_stmt = nir_cf_node_as_if(prev_node); - nir_cf_node *then_node = nir_if_first_then_node(if_stmt); - nir_cf_node *else_node = nir_if_first_else_node(if_stmt); + nir_block *then_block = nir_if_first_then_block(if_stmt); + nir_block *else_block = nir_if_first_else_block(if_stmt); /* We can only have one block in each side ... */ - if (nir_if_last_then_node(if_stmt) != then_node || - nir_if_last_else_node(if_stmt) != else_node) + if (nir_if_last_then_block(if_stmt) != then_block || + nir_if_last_else_block(if_stmt) != else_block) return false; - nir_block *then_block = nir_cf_node_as_block(then_node); - nir_block *else_block = nir_cf_node_as_block(else_node); - /* ... and those blocks must only contain "allowed" instructions. */ if (!block_check_for_allowed_instrs(then_block) || !block_check_for_allowed_instrs(else_block)) diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c index 81c67168c18..84add5253ff 100644 --- a/src/gallium/drivers/vc4/vc4_program.c +++ b/src/gallium/drivers/vc4/vc4_program.c @@ -1777,11 +1777,9 @@ ntq_emit_if(struct vc4_compile *c, nir_if *if_stmt) return; } - nir_cf_node *nir_first_else_node = nir_if_first_else_node(if_stmt); - nir_cf_node *nir_last_else_node = nir_if_last_else_node(if_stmt); - nir_block *nir_else_block = nir_cf_node_as_block(nir_first_else_node); + nir_block *nir_else_block = nir_if_first_else_block(if_stmt); bool empty_else_block = - (nir_first_else_node == nir_last_else_node && + (nir_else_block == nir_if_last_else_block(if_stmt) && exec_list_is_empty(&nir_else_block->instr_list)); struct qblock *then_block = qir_new_block(c); -- 2.30.2