nir: Support vec8/vec16 in nir_lower_bit_size
[mesa.git] / src / compiler / nir / nir_opt_conditional_discard.c
index 2fde1799a8d48a78548d1b2115691c060cc055a5..3d5c255ee73a3bbf2651fa3673700cb63ee80343 100644 (file)
 
 /** @file nir_opt_conditional_discard.c
  *
- * Handles optimization of lowering if (cond) discard to discard_if(cond).
+ * Handles optimization of lowering of
+ *  - if (cond) discard to discard_if(cond) and
+ *  - if (cond) demote to demote_if(cond)
  */
 
 static bool
-nir_opt_conditional_discard_block(nir_block *block, void *mem_ctx)
+nir_opt_conditional_discard_block(nir_builder *b, nir_block *block)
 {
-   nir_builder bld;
-
    if (nir_cf_node_is_first(&block->cf_node))
       return false;
 
@@ -75,31 +75,37 @@ nir_opt_conditional_discard_block(nir_block *block, void *mem_ctx)
    }
 
    /* Get the first instruction in the then block and confirm it is
-    * a discard or a discard_if
+    * a discard or a demote instruction.
     */
    nir_instr *instr = nir_block_first_instr(then_block);
    if (instr->type != nir_instr_type_intrinsic)
       return false;
 
    nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
-   if (intrin->intrinsic != nir_intrinsic_discard &&
-       intrin->intrinsic != nir_intrinsic_discard_if)
+   nir_intrinsic_op op = intrin->intrinsic;
+   assert(if_stmt->condition.is_ssa);
+   nir_ssa_def *cond = if_stmt->condition.ssa;
+   b->cursor = nir_before_cf_node(prev_node);
+
+   switch (intrin->intrinsic) {
+   case nir_intrinsic_discard:
+      op = nir_intrinsic_discard_if;
+      break;
+   case nir_intrinsic_demote:
+      op = nir_intrinsic_demote_if;
+      break;
+   case nir_intrinsic_discard_if:
+   case nir_intrinsic_demote_if:
+      assert(intrin->src[0].is_ssa);
+      cond = nir_iand(b, cond, intrin->src[0].ssa);
+      break;
+   default:
       return false;
-
-   nir_src cond;
-
-   nir_builder_init(&bld, mem_ctx);
-   bld.cursor = nir_before_cf_node(prev_node);
-   if (intrin->intrinsic == nir_intrinsic_discard)
-      cond = if_stmt->condition;
-   else
-      cond = nir_src_for_ssa(nir_iand(&bld,
-                                      nir_ssa_for_src(&bld, if_stmt->condition, 1),
-                                      nir_ssa_for_src(&bld, intrin->src[0], 1)));
+   }
 
    nir_intrinsic_instr *discard_if =
-      nir_intrinsic_instr_create(mem_ctx, nir_intrinsic_discard_if);
-   nir_src_copy(&discard_if->src[0], &cond, discard_if);
+      nir_intrinsic_instr_create(b->shader, op);
+   discard_if->src[0] = nir_src_for_ssa(cond);
 
    nir_instr_insert_before_cf(prev_node, &discard_if->instr);
    nir_instr_remove(&intrin->instr);
@@ -113,11 +119,23 @@ nir_opt_conditional_discard(nir_shader *shader)
 {
    bool progress = false;
 
+   nir_builder builder;
+
    nir_foreach_function(function, shader) {
       if (function->impl) {
-         void *mem_ctx = ralloc_parent(function->impl);
+         nir_builder_init(&builder, function->impl);
+
+         bool impl_progress = false;
          nir_foreach_block_safe(block, function->impl) {
-            progress |= nir_opt_conditional_discard_block(block, mem_ctx);
+            if (nir_opt_conditional_discard_block(&builder, block))
+               impl_progress = true;
+         }
+
+         if (impl_progress) {
+            nir_metadata_preserve(function->impl, nir_metadata_none);
+            progress = true;
+         } else {
+            nir_metadata_preserve(function->impl, nir_metadata_all);
          }
       }
    }