X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fnir%2Fnir_opt_conditional_discard.c;h=3d5c255ee73a3bbf2651fa3673700cb63ee80343;hb=ce6f66242ad33be84c0a34519f18bdc15c195950;hp=2fde1799a8d48a78548d1b2115691c060cc055a5;hpb=b16dff2d88302e5113598a818d2f92f8af02cd79;p=mesa.git diff --git a/src/compiler/nir/nir_opt_conditional_discard.c b/src/compiler/nir/nir_opt_conditional_discard.c index 2fde1799a8d..3d5c255ee73 100644 --- a/src/compiler/nir/nir_opt_conditional_discard.c +++ b/src/compiler/nir/nir_opt_conditional_discard.c @@ -26,14 +26,14 @@ /** @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); } } }