[Mesa-dev] [PATCH v2 07/14] nir/validate: validate successors at the end of a loop

Connor Abbott cwabbott0 at gmail.com
Thu May 21 09:41:02 PDT 2015


I found this useful while debugging some control flow bugs while working
on the dead control flow pass.

Signed-off-by: Connor Abbott <cwabbott0 at gmail.com>
---
 src/glsl/nir/nir_validate.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/src/glsl/nir/nir_validate.c b/src/glsl/nir/nir_validate.c
index da92ed9..0332c7d 100644
--- a/src/glsl/nir/nir_validate.c
+++ b/src/glsl/nir/nir_validate.c
@@ -78,6 +78,9 @@ typedef struct {
    /* the parent of the current cf node being visited */
    nir_cf_node *parent_node;
 
+   /* whether the current loop we're visiting has a break statement */
+   bool has_break;
+
    /* the current function implementation being validated */
    nir_function_impl *impl;
 
@@ -513,6 +516,8 @@ validate_instr(nir_instr *instr, validate_state *state)
       break;
 
    case nir_instr_type_jump:
+      if (nir_instr_as_jump(instr)->type == nir_jump_break)
+         state->has_break = true;
       break;
 
    default:
@@ -641,6 +646,9 @@ validate_if(nir_if *if_stmt, validate_state *state)
 static void
 validate_loop(nir_loop *loop, validate_state *state)
 {
+   bool old_has_break = state->has_break;
+   state->has_break = false;
+
    assert(!exec_node_is_head_sentinel(loop->cf_node.node.prev));
    nir_cf_node *prev_node = nir_cf_node_prev(&loop->cf_node);
    assert(prev_node->type == nir_cf_node_block);
@@ -663,7 +671,20 @@ validate_loop(nir_loop *loop, validate_state *state)
       validate_cf_node(cf_node, state);
    }
 
+   nir_block *last_block = nir_cf_node_as_block(nir_loop_last_cf_node(loop));
+   if (exec_list_is_empty(&last_block->instr_list) ||
+       nir_block_last_instr(last_block)->type != nir_instr_type_jump) {
+      assert(&last_block->successors[0]->cf_node == nir_loop_first_cf_node(loop));
+   }
+   if (state->has_break) {
+      assert(last_block->successors[1] == NULL);
+   } else {
+      nir_block *next = nir_cf_node_as_block(nir_cf_node_next(&loop->cf_node));
+      assert(last_block->successors[1] == next);
+   }
+
    state->parent_node = old_parent;
+   state->has_break = old_has_break;
 }
 
 static void
-- 
2.1.0



More information about the mesa-dev mailing list