nir: Add a function to detect if a block is immediately followed by an if
authorJason Ekstrand <jason.ekstrand@intel.com>
Wed, 29 Oct 2014 23:25:51 +0000 (16:25 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Thu, 15 Jan 2015 15:19:00 +0000 (07:19 -0800)
Since we don't actually have an "if" instruction, this is a very common
pattern when iterating over instructions.  This adds a helper function for
it to make things a little less painful.

Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
src/glsl/nir/nir.c
src/glsl/nir/nir.h
src/glsl/nir/nir_from_ssa.c
src/glsl/nir/nir_opt_dce.c

index 25844dc..3c3afef 100644 (file)
@@ -1692,6 +1692,23 @@ nir_foreach_block_reverse(nir_function_impl *impl, nir_foreach_block_cb cb,
    return true;
 }
 
+nir_if *
+nir_block_following_if(nir_block *block)
+{
+   if (exec_node_is_tail_sentinel(&block->cf_node.node))
+      return NULL;
+
+   if (nir_cf_node_is_last(&block->cf_node))
+      return NULL;
+
+   nir_cf_node *next_node = nir_cf_node_next(&block->cf_node);
+
+   if (next_node->type != nir_cf_node_if)
+      return NULL;
+
+   return nir_cf_node_as_if(next_node);
+}
+
 static bool
 index_block(nir_block *block, void *state)
 {
index 2ea7542..84be1d6 100644 (file)
@@ -1277,6 +1277,11 @@ bool nir_foreach_block(nir_function_impl *impl, nir_foreach_block_cb cb,
 bool nir_foreach_block_reverse(nir_function_impl *impl, nir_foreach_block_cb cb,
                                void *state);
 
+/* If the following CF node is an if, this function returns that if.
+ * Otherwise, it returns NULL.
+ */
+nir_if *nir_block_following_if(nir_block *block);
+
 void nir_index_local_regs(nir_function_impl *impl);
 void nir_index_global_regs(nir_shader *shader);
 void nir_index_ssa_defs(nir_function_impl *impl);
index abfee35..c88583a 100644 (file)
@@ -107,12 +107,9 @@ convert_from_ssa_block(nir_block *block, void *void_state)
       }
    }
 
-   if (block->cf_node.node.next != NULL && /* check that we aren't the end node */
-       !nir_cf_node_is_last(&block->cf_node) &&
-       nir_cf_node_next(&block->cf_node)->type == nir_cf_node_if) {
-      nir_if *if_stmt = nir_cf_node_as_if(nir_cf_node_next(&block->cf_node));
-      rewrite_ssa_src(&if_stmt->condition, state);
-   }
+   nir_if *following_if = nir_block_following_if(block);
+   if (following_if)
+      rewrite_ssa_src(&following_if->condition, state);
 
    return true;
 }
index c18ba32..c3bbcb4 100644 (file)
@@ -123,13 +123,11 @@ init_block_cb(nir_block *block, void *_state)
    nir_foreach_instr(block, instr)
       init_instr(instr, worklist);
 
-   if (block->cf_node.node.next != NULL && /* check that we aren't the end node */
-       !nir_cf_node_is_last(&block->cf_node) &&
-       nir_cf_node_next(&block->cf_node)->type == nir_cf_node_if) {
-      nir_if *if_stmt = nir_cf_node_as_if(nir_cf_node_next(&block->cf_node));
-      if (if_stmt->condition.is_ssa &&
-          !if_stmt->condition.ssa->parent_instr->live)
-         worklist_push(worklist, if_stmt->condition.ssa->parent_instr);
+   nir_if *following_if = nir_block_following_if(block);
+   if (following_if) {
+      if (following_if->condition.is_ssa &&
+          !following_if->condition.ssa->parent_instr->live)
+         worklist_push(worklist, following_if->condition.ssa->parent_instr);
    }
 
    return true;