nir,radv/aco: add and use pass to lower make available/visible barriers
[mesa.git] / src / compiler / nir / nir_control_flow.c
index 3b0a0f1a5b092ef3671daa584eb8c6d5b69fb661..c52d091e848286ba8dc141a927c08595d9fd9ab2 100644 (file)
@@ -189,15 +189,13 @@ 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);
 
-   struct set_entry *entry;
    set_foreach(block->predecessors, entry) {
       nir_block *pred = (nir_block *) entry->key;
       replace_successor(pred, block, new_block);
    }
 
    /* Any phi nodes must stay part of the new block, or else their
-    * sourcse will be messed up. This will reverse the order of the phis, but
-    * order shouldn't matter.
+    * sources will be messed up.
     */
    nir_foreach_instr_safe(instr, block) {
       if (instr->type != nir_instr_type_phi)
@@ -205,7 +203,7 @@ split_block_beginning(nir_block *block)
 
       exec_node_remove(&instr->node);
       instr->block = new_block;
-      exec_list_push_head(&new_block->instr_list, &instr->node);
+      exec_list_push_tail(&new_block->instr_list, &instr->node);
    }
 
    return new_block;
@@ -437,6 +435,23 @@ nearest_loop(nir_cf_node *node)
    return nir_cf_node_as_loop(node);
 }
 
+static void
+remove_phi_src(nir_block *block, nir_block *pred)
+{
+   nir_foreach_instr(instr, block) {
+      if (instr->type != nir_instr_type_phi)
+         break;
+
+      nir_phi_instr *phi = nir_instr_as_phi(instr);
+      nir_foreach_phi_src_safe(src, phi) {
+         if (src->pred == pred) {
+            list_del(&src->src.use_link);
+            exec_node_remove(&src->node);
+         }
+      }
+   }
+}
+
 /*
  * update the CFG after a jump instruction has been added to the end of a block
  */
@@ -447,43 +462,37 @@ nir_handle_add_jump(nir_block *block)
    nir_instr *instr = nir_block_last_instr(block);
    nir_jump_instr *jump_instr = nir_instr_as_jump(instr);
 
+   if (block->successors[0])
+      remove_phi_src(block->successors[0], block);
+   if (block->successors[1])
+      remove_phi_src(block->successors[1], block);
    unlink_block_successors(block);
 
    nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node);
    nir_metadata_preserve(impl, nir_metadata_none);
 
-   if (jump_instr->type == nir_jump_break ||
-       jump_instr->type == nir_jump_continue) {
-      nir_loop *loop = nearest_loop(&block->cf_node);
-
-      if (jump_instr->type == nir_jump_continue) {
-         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);
-         nir_block *after_block = nir_cf_node_as_block(after);
-         link_blocks(block, after_block, NULL);
-      }
-   } else {
-      assert(jump_instr->type == nir_jump_return);
+   switch (jump_instr->type) {
+   case nir_jump_return:
       link_blocks(block, impl->end_block, NULL);
+      break;
+
+   case nir_jump_break: {
+      nir_loop *loop = nearest_loop(&block->cf_node);
+      nir_cf_node *after = nir_cf_node_next(&loop->cf_node);
+      nir_block *after_block = nir_cf_node_as_block(after);
+      link_blocks(block, after_block, NULL);
+      break;
    }
-}
 
-static void
-remove_phi_src(nir_block *block, nir_block *pred)
-{
-   nir_foreach_instr(instr, block) {
-      if (instr->type != nir_instr_type_phi)
-         break;
+   case nir_jump_continue: {
+      nir_loop *loop = nearest_loop(&block->cf_node);
+      nir_block *first_block = nir_loop_first_block(loop);
+      link_blocks(block, first_block, NULL);
+      break;
+   }
 
-      nir_phi_instr *phi = nir_instr_as_phi(instr);
-      nir_foreach_phi_src_safe(src, phi) {
-         if (src->pred == pred) {
-            list_del(&src->src.use_link);
-            exec_node_remove(&src->node);
-         }
-      }
+   default:
+      unreachable("Invalid jump type");
    }
 }