[Mesa-dev] [PATCH 2/3] nir: Make nir_foo_first/last_cf_node return a block instead

Jason Ekstrand jason at jlekstrand.net
Thu Oct 6 03:37:47 UTC 2016


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 <jason at jlekstrand.net>
---
 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 +++--
 .../drivers/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 13ba989..098e1b2 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 a122f12..8a9ccf2 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 1ff7a53..380e8aa 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 1bf4bf6..9c5349a 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 1490e68..53c92ec 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 6a73d73..29543d6 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 60af715..bd73f04 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 6e1395c..b781fa7 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 81c6716..84add52 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.5.0.400.gff86faf



More information about the mesa-dev mailing list