From d7d87df542f8c8705b26e185db71df7bed9a84b7 Mon Sep 17 00:00:00 2001
From: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Date: Mon, 24 Feb 2025 14:57:49 -0500
Subject: [PATCH] Via Coccinelle patch:

    @@
    identifier prog;
    expression impl, metadata;
    @@

    -if (prog) {
    -nir_metadata_preserve(impl, metadata);
    -} else {
    -nir_metadata_preserve(impl, nir_metadata_all);
    -}
    -return prog;
    +return nir_progress(prog, impl, metadata);

    @@
    expression prog_expr, impl, metadata;
    @@

    -if (prog_expr) {
    -nir_metadata_preserve(impl, metadata);
    -return true;
    -} else {
    -nir_metadata_preserve(impl, nir_metadata_all);
    -return false;
    -}
    +bool progress = prog_expr;
    +return nir_progress(progress, impl, metadata);

    @@
    identifier prog;
    expression impl, metadata;
    @@

    -nir_metadata_preserve(impl, prog ? (metadata) : nir_metadata_all);
    -return prog;
    +return nir_progress(prog, impl, metadata);

    @@
    identifier prog;
    expression impl, metadata;
    @@

    -nir_metadata_preserve(impl, prog ? (metadata) : nir_metadata_all);
    +nir_progress(prog, impl, metadata);

    @@
    expression impl, metadata;
    @@

    -nir_metadata_preserve(impl, metadata);
    -return true;
    +return nir_progress(true, impl, metadata);

    @@
    expression impl;
    @@

    -nir_metadata_preserve(impl, nir_metadata_all);
    -return false;
    +return nir_no_progress(impl);

    @@
    identifier other_prog, prog;
    expression impl, metadata;
    @@

    -if (prog) {
    -nir_metadata_preserve(impl, metadata);
    -} else {
    -nir_metadata_preserve(impl, nir_metadata_all);
    -}
    -other_prog |= prog;
    +other_prog = other_prog | nir_progress(prog, impl, metadata);

    @@
    identifier prog;
    expression impl, metadata;
    @@

    -if (prog) {
    -nir_metadata_preserve(impl, metadata);
    -} else {
    -nir_metadata_preserve(impl, nir_metadata_all);
    -}
    +nir_progress(prog, impl, metadata);

    @@
    identifier other_prog, prog;
    expression impl, metadata;
    @@

    -if (prog) {
    -nir_metadata_preserve(impl, metadata);
    -other_prog = true;
    -} else {
    -nir_metadata_preserve(impl, nir_metadata_all);
    -}
    +other_prog = other_prog | nir_progress(prog, impl, metadata);

    @@
    expression prog_expr, impl, metadata;
    identifier prog;
    @@

    -if (prog_expr) {
    -nir_metadata_preserve(impl, metadata);
    -prog = true;
    -} else {
    -nir_metadata_preserve(impl, nir_metadata_all);
    -}
    +bool impl_progress = prog_expr;
    +prog = prog | nir_progress(impl_progress, impl, metadata);

    @@
    identifier other_prog, prog;
    expression impl, metadata;
    @@

    -if (prog) {
    -other_prog = true;
    -nir_metadata_preserve(impl, metadata);
    -} else {
    -nir_metadata_preserve(impl, nir_metadata_all);
    -}
    +other_prog = other_prog | nir_progress(prog, impl, metadata);

    @@
    expression prog_expr, impl, metadata;
    identifier prog;
    @@

    -if (prog_expr) {
    -prog = true;
    -nir_metadata_preserve(impl, metadata);
    -} else {
    -nir_metadata_preserve(impl, nir_metadata_all);
    -}
    +bool impl_progress = prog_expr;
    +prog = prog | nir_progress(impl_progress, impl, metadata);

    @@
    expression prog_expr, impl, metadata;
    @@

    -if (prog_expr) {
    -nir_metadata_preserve(impl, metadata);
    -} else {
    -nir_metadata_preserve(impl, nir_metadata_all);
    -}
    +bool impl_progress = prog_expr;
    +nir_progress(impl_progress, impl, metadata);

    @@
    identifier prog;
    expression impl, metadata;
    @@

    -nir_metadata_preserve(impl, metadata);
    -prog = true;
    +prog = nir_progress(true, impl, metadata);

    @@
    identifier prog;
    expression impl, metadata;
    @@

    -if (prog) {
    -nir_metadata_preserve(impl, metadata);
    -}
    -return prog;
    +return nir_progress(prog, impl, metadata);

    @@
    identifier prog;
    expression impl, metadata;
    @@

    -if (prog) {
    -nir_metadata_preserve(impl, metadata);
    -}
    +nir_progress(prog, impl, metadata);

    @@
    expression impl;
    @@

    -nir_metadata_preserve(impl, nir_metadata_all);
    +nir_no_progress(impl);

    @@
    expression impl, metadata;
    @@

    -nir_metadata_preserve(impl, metadata);
    +nir_progress(true, impl, metadata);
---
 src/amd/common/nir/ac_nir_lower_legacy_gs.c   |  3 +-
 src/amd/common/nir/ac_nir_lower_legacy_vs.c   |  4 +-
 src/amd/common/nir/ac_nir_lower_ngg.c         |  6 +--
 src/amd/common/nir/ac_nir_lower_ngg_gs.c      |  6 +--
 src/amd/common/nir/ac_nir_lower_ngg_mesh.c    |  2 +-
 .../nir/ac_nir_lower_taskmesh_io_to_mem.c     |  2 +-
 .../common/nir/ac_nir_lower_tess_io_to_mem.c  |  2 +-
 src/amd/common/nir/ac_nir_lower_tex.c         |  9 +++--
 src/amd/common/nir/ac_nir_opt_outputs.c       | 10 +----
 .../aco_instruction_selection_setup.cpp       |  2 +-
 .../nir/radv_nir_apply_pipeline_layout.c      |  2 +-
 .../vulkan/nir/radv_nir_export_multiview.c    |  7 +---
 src/amd/vulkan/nir/radv_nir_lower_abi.c       |  2 +-
 .../nir/radv_nir_lower_cooperative_matrix.c   |  8 +---
 .../radv_nir_lower_primitive_shading_rate.c   |  7 +---
 .../vulkan/nir/radv_nir_lower_ray_queries.c   |  2 +-
 src/amd/vulkan/nir/radv_nir_rt_shader.c       | 20 +++-------
 src/amd/vulkan/radv_pipeline_rt.c             |  6 +--
 .../compiler/agx_nir_lower_cull_distance.c    |  3 +-
 .../compiler/agx_nir_lower_discard_zs_emit.c  |  9 +----
 .../compiler/agx_nir_lower_sample_mask.c      |  5 +--
 src/asahi/lib/agx_nir_lower_alpha.c           | 14 ++-----
 src/asahi/lib/agx_nir_lower_gs.c              |  2 +-
 src/asahi/lib/agx_nir_lower_msaa.c            |  2 +-
 src/asahi/lib/agx_nir_lower_tess.c            |  4 +-
 src/asahi/lib/agx_nir_prolog_epilog.c         |  6 +--
 src/asahi/vulkan/hk_shader.c                  |  6 +--
 src/broadcom/compiler/v3d_nir_lower_io.c      |  3 +-
 .../compiler/v3d_nir_lower_line_smooth.c      |  7 +---
 .../compiler/v3d_nir_lower_logic_ops.c        |  8 +---
 src/broadcom/compiler/vir.c                   |  6 +--
 src/compiler/clc/nir_load_libclc.c            |  4 +-
 src/compiler/glsl/gl_nir_linker.c             |  6 +--
 .../gl_nir_lower_blend_equation_advanced.c    |  5 +--
 src/compiler/glsl/gl_nir_lower_buffers.c      |  8 +---
 src/compiler/nir/nir.c                        |  8 +---
 src/compiler/nir/nir_builder.c                |  2 +-
 src/compiler/nir/nir_builder.h                | 37 +++---------------
 src/compiler/nir/nir_control_flow.c           |  6 +--
 src/compiler/nir/nir_deref.c                  | 16 +-------
 src/compiler/nir/nir_divergence_analysis.c    |  4 +-
 src/compiler/nir/nir_from_ssa.c               |  4 +-
 src/compiler/nir/nir_group_loads.c            |  4 +-
 src/compiler/nir/nir_inline_uniforms.c        |  2 +-
 src/compiler/nir/nir_linking_helpers.c        | 15 ++------
 src/compiler/nir/nir_lower_amul.c             |  2 +-
 .../nir/nir_lower_array_deref_of_vec.c        | 10 +----
 src/compiler/nir/nir_lower_atomics_to_ssbo.c  |  2 +-
 src/compiler/nir/nir_lower_bit_size.c         |  8 +---
 src/compiler/nir/nir_lower_bitmap.c           |  2 +-
 src/compiler/nir/nir_lower_clip.c             |  6 +--
 .../nir/nir_lower_clip_cull_distance_arrays.c | 10 +----
 .../nir/nir_lower_const_arrays_to_uniforms.c  |  2 +-
 .../nir/nir_lower_continue_constructs.c       |  4 +-
 src/compiler/nir/nir_lower_double_ops.c       |  8 +---
 src/compiler/nir/nir_lower_flrp.c             |  2 +-
 .../nir/nir_lower_global_vars_to_local.c      |  7 ++--
 src/compiler/nir/nir_lower_goto_ifs.c         |  5 +--
 src/compiler/nir/nir_lower_gs_intrinsics.c    |  2 +-
 src/compiler/nir/nir_lower_indirect_derefs.c  |  7 +---
 src/compiler/nir/nir_lower_int_to_float.c     |  6 +--
 src/compiler/nir/nir_lower_io.c               | 35 ++++-------------
 .../nir/nir_lower_io_arrays_to_elements.c     |  6 +--
 .../nir/nir_lower_io_to_temporaries.c         |  5 +--
 src/compiler/nir/nir_lower_io_to_vector.c     |  6 +--
 .../nir/nir_lower_load_const_to_scalar.c      |  8 +---
 src/compiler/nir/nir_lower_locals_to_regs.c   |  2 +-
 src/compiler/nir/nir_lower_mediump.c          | 38 +++----------------
 src/compiler/nir/nir_lower_memcpy.c           |  8 +---
 src/compiler/nir/nir_lower_memory_model.c     |  8 +---
 src/compiler/nir/nir_lower_multiview.c        |  3 +-
 .../nir/nir_lower_non_uniform_access.c        |  5 +--
 .../nir/nir_lower_passthrough_edgeflags.c     |  2 +-
 src/compiler/nir/nir_lower_patch_vertices.c   |  4 +-
 src/compiler/nir/nir_lower_phis_to_scalar.c   |  2 +-
 src/compiler/nir/nir_lower_pntc_ytransform.c  |  2 +-
 src/compiler/nir/nir_lower_point_size_mov.c   |  2 +-
 .../nir/nir_lower_reg_intrinsics_to_ssa.c     |  6 +--
 src/compiler/nir/nir_lower_returns.c          |  4 +-
 src/compiler/nir/nir_lower_scratch.c          |  8 +---
 src/compiler/nir/nir_lower_shader_calls.c     | 24 ++++--------
 src/compiler/nir/nir_lower_task_shader.c      |  6 +--
 .../nir/nir_lower_terminate_to_demote.c       |  8 +---
 src/compiler/nir/nir_lower_tex.c              |  2 +-
 src/compiler/nir/nir_lower_texcoord_replace.c |  2 +-
 .../nir/nir_lower_variable_initializers.c     | 19 +++-------
 src/compiler/nir/nir_lower_vars_to_ssa.c      |  5 +--
 src/compiler/nir/nir_metadata.c               |  2 +-
 .../nir/nir_move_output_stores_to_end.c       |  4 +-
 .../nir/nir_move_vec_src_uses_to_dest.c       |  2 +-
 src/compiler/nir/nir_opt_access.c             | 18 ++-------
 src/compiler/nir/nir_opt_barriers.c           | 20 +++-------
 src/compiler/nir/nir_opt_call.c               |  3 +-
 src/compiler/nir/nir_opt_combine_stores.c     |  7 +---
 src/compiler/nir/nir_opt_comparison_pre.c     |  8 +---
 src/compiler/nir/nir_opt_copy_prop_vars.c     |  7 +---
 src/compiler/nir/nir_opt_copy_propagate.c     |  8 +---
 src/compiler/nir/nir_opt_cse.c                |  6 +--
 src/compiler/nir/nir_opt_dce.c                |  8 +---
 src/compiler/nir/nir_opt_dead_cf.c            |  4 +-
 src/compiler/nir/nir_opt_dead_write_vars.c    |  8 +---
 src/compiler/nir/nir_opt_find_array_copies.c  |  4 +-
 src/compiler/nir/nir_opt_fragdepth.c          |  6 +--
 src/compiler/nir/nir_opt_gcm.c                |  6 +--
 src/compiler/nir/nir_opt_if.c                 |  8 +---
 src/compiler/nir/nir_opt_intrinsics.c         |  9 ++---
 src/compiler/nir/nir_opt_large_constants.c    |  3 +-
 src/compiler/nir/nir_opt_licm.c               | 10 ++---
 .../nir/nir_opt_load_store_vectorize.c        |  5 +--
 src/compiler/nir/nir_opt_loop.c               |  4 +-
 src/compiler/nir/nir_opt_loop_unroll.c        |  4 +-
 src/compiler/nir/nir_opt_memcpy.c             |  8 +---
 src/compiler/nir/nir_opt_move.c               |  8 ++--
 .../nir/nir_opt_move_discards_to_top.c        |  3 +-
 src/compiler/nir/nir_opt_mqsad.c              |  5 +--
 src/compiler/nir/nir_opt_peephole_select.c    |  8 +---
 src/compiler/nir/nir_opt_preamble.c           |  3 +-
 src/compiler/nir/nir_opt_ray_queries.c        |  5 +--
 .../nir/nir_opt_rematerialize_compares.c      | 16 +-------
 src/compiler/nir/nir_opt_shrink_stores.c      |  7 +---
 src/compiler/nir/nir_opt_shrink_vectors.c     |  7 +---
 src/compiler/nir/nir_opt_sink.c               |  3 +-
 src/compiler/nir/nir_opt_uniform_atomics.c    |  9 ++---
 src/compiler/nir/nir_opt_varyings.c           | 12 ++----
 src/compiler/nir/nir_opt_vectorize.c          |  6 +--
 src/compiler/nir/nir_opt_vectorize_io.c       |  5 +--
 src/compiler/nir/nir_propagate_invariant.c    | 10 +----
 src/compiler/nir/nir_repair_ssa.c             |  2 +-
 src/compiler/nir/nir_search.c                 | 11 +-----
 src/compiler/nir/nir_split_vars.c             | 15 +++-----
 src/compiler/nir/nir_sweep.c                  |  2 +-
 src/compiler/nir/nir_to_lcssa.c               |  9 ++---
 src/compiler/nir/nir_trivialize_registers.c   |  2 +-
 src/compiler/nir/nir_use_dominance.c          |  2 +-
 .../ir3/ir3_nir_analyze_ubo_ranges.c          | 11 ++----
 src/freedreno/ir3/ir3_nir_lower_64b.c         |  4 +-
 src/freedreno/ir3/ir3_nir_lower_io_offsets.c  |  7 +---
 .../ir3_nir_lower_push_consts_to_preamble.c   |  2 +-
 src/freedreno/ir3/ir3_nir_lower_tess.c        | 23 +++--------
 .../ir3/ir3_nir_lower_tex_prefetch.c          |  7 +---
 .../ir3/ir3_nir_move_varying_inputs.c         |  5 +--
 src/freedreno/ir3/ir3_nir_opt_preamble.c      | 12 ++----
 .../vulkan/tu_nir_lower_multiview.cc          |  9 ++---
 .../vulkan/tu_nir_lower_ray_query.cc          |  2 +-
 src/gallium/auxiliary/nir/tgsi_to_nir.c       |  3 +-
 .../drivers/asahi/agx_nir_lower_point_size.c  |  4 +-
 src/gallium/drivers/crocus/crocus_program.c   |  5 +--
 .../drivers/d3d12/d3d12_lower_point_sprite.c  |  2 +-
 src/gallium/drivers/d3d12/d3d12_nir_passes.c  | 18 ++++-----
 src/gallium/drivers/etnaviv/etnaviv_nir.c     |  8 +---
 src/gallium/drivers/iris/iris_program.c       |  5 +--
 .../lima/ir/lima_nir_duplicate_consts.c       |  2 +-
 .../lima/ir/lima_nir_duplicate_intrinsic.c    |  2 +-
 .../lima/ir/lima_nir_duplicate_modifiers.c    |  2 +-
 .../sfn/sfn_nir_lower_fs_out_to_vector.cpp    |  7 +---
 .../r600/sfn/sfn_nir_vectorize_vs_inputs.c    |  6 +--
 .../drivers/radeonsi/si_nir_lower_abi.c       |  2 +-
 src/gallium/drivers/radeonsi/si_shader.c      | 14 ++-----
 src/gallium/drivers/radeonsi/si_shader_nir.c  |  8 +---
 src/gallium/drivers/vc4/vc4_nir_lower_blend.c |  3 +-
 src/gallium/drivers/vc4/vc4_nir_lower_io.c    |  4 +-
 src/gallium/drivers/zink/zink_compiler.c      |  5 +--
 .../lavapipe/lvp_ray_tracing_pipeline.c       |  7 +---
 .../lavapipe/nir/lvp_nir_lower_ray_queries.c  |  2 +-
 .../rogue/nir/rogue_nir_lower_io.c            |  7 +---
 src/intel/compiler/brw_compile_mesh.cpp       |  6 +--
 src/intel/compiler/brw_kernel.c               |  8 +---
 src/intel/compiler/brw_nir.c                  |  3 +-
 .../brw_nir_lower_alpha_to_coverage.c         |  6 +--
 .../compiler/brw_nir_lower_cs_intrinsics.c    |  3 +-
 .../brw_nir_lower_intersection_shader.c       |  2 +-
 .../compiler/brw_nir_lower_ray_queries.c      |  4 +-
 .../compiler/brw_nir_lower_rt_intrinsics.c    |  6 +--
 .../compiler/brw_nir_lower_shader_calls.c     |  2 +-
 src/intel/compiler/brw_nir_opt_fsat.c         |  8 +---
 src/intel/compiler/brw_nir_rt.c               | 16 +-------
 .../elk/elk_nir_lower_alpha_to_coverage.c     |  6 +--
 .../elk/elk_nir_lower_cs_intrinsics.c         |  3 +-
 .../compiler/intel_nir_tcs_workarounds.c      |  2 +-
 src/intel/vulkan/anv_nir_lower_multiview.c    |  4 +-
 .../vulkan_hasvk/anv_nir_lower_multiview.c    |  4 +-
 .../st_nir_lower_position_invariant.c         |  4 +-
 src/microsoft/clc/clc_nir.c                   |  8 +---
 src/microsoft/compiler/dxil_nir.c             |  8 +---
 src/microsoft/compiler/dxil_nir_tess.c        |  2 +-
 src/nouveau/codegen/nv50_ir_from_nir.cpp      |  3 +-
 src/nouveau/compiler/nak_nir_lower_cf.c       |  3 +-
 .../compiler/nak_nir_lower_gs_intrinsics.c    |  2 +-
 .../compiler/nak_nir_lower_non_uniform_ldcx.c |  9 +----
 .../compiler/nak_nir_mark_lcssa_invariants.c  | 10 ++---
 src/panfrost/midgard/nir_fuse_io_16.c         |  3 +-
 src/panfrost/util/pan_lower_writeout.c        |  4 +-
 192 files changed, 349 insertions(+), 909 deletions(-)

diff --git a/src/amd/common/nir/ac_nir_lower_legacy_gs.c b/src/amd/common/nir/ac_nir_lower_legacy_gs.c
index 261399dd0fd..066db3b7419 100644
--- a/src/amd/common/nir/ac_nir_lower_legacy_gs.c
+++ b/src/amd/common/nir/ac_nir_lower_legacy_gs.c
@@ -284,8 +284,7 @@ ac_nir_lower_legacy_gs(nir_shader *nir,
    nir_sendmsg_amd(b, nir_load_gs_wave_id_amd(b),
                    .base = AC_SENDMSG_GS_OP_NOP | AC_SENDMSG_GS_DONE);
 
-   if (progress)
-      nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(progress, impl, nir_metadata_none);
 
    return true;
 }
diff --git a/src/amd/common/nir/ac_nir_lower_legacy_vs.c b/src/amd/common/nir/ac_nir_lower_legacy_vs.c
index a1246baee11..3c160f009a9 100644
--- a/src/amd/common/nir/ac_nir_lower_legacy_vs.c
+++ b/src/amd/common/nir/ac_nir_lower_legacy_vs.c
@@ -89,7 +89,5 @@ ac_nir_lower_legacy_vs(nir_shader *nir,
                                &out);
    }
 
-   nir_metadata_preserve(impl, nir_metadata_none);
-
-   return true;
+   return nir_progress(true, impl, nir_metadata_none);
 }
diff --git a/src/amd/common/nir/ac_nir_lower_ngg.c b/src/amd/common/nir/ac_nir_lower_ngg.c
index c53a90984d7..b2005ac1a20 100644
--- a/src/amd/common/nir/ac_nir_lower_ngg.c
+++ b/src/amd/common/nir/ac_nir_lower_ngg.c
@@ -838,7 +838,7 @@ analyze_shader_before_culling(nir_shader *shader, lower_ngg_nogs_state *s)
          }
       }
 
-      nir_metadata_preserve(impl, nir_metadata_all);
+      nir_no_progress(impl);
    }
 }
 
@@ -1203,7 +1203,7 @@ add_deferred_attribute_culling(nir_builder *b, nir_cf_list *original_extracted_c
    nir_store_var(b, s->gs_accepted_var, gs_thread, 0x1u);
 
    /* Remove all non-position outputs, and put the position output into the variable. */
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
    remove_culling_shader_outputs(b->shader, s);
    b->cursor = nir_after_impl(impl);
 
@@ -1929,7 +1929,7 @@ ac_nir_lower_ngg_nogs(nir_shader *shader, const ac_nir_lower_ngg_options *option
       }
    }
 
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
    nir_validate_shader(shader, "after emitting NGG VS/TES");
 
    /* Cleanup */
diff --git a/src/amd/common/nir/ac_nir_lower_ngg_gs.c b/src/amd/common/nir/ac_nir_lower_ngg_gs.c
index 564348ea3bd..72946fd2b2a 100644
--- a/src/amd/common/nir/ac_nir_lower_ngg_gs.c
+++ b/src/amd/common/nir/ac_nir_lower_ngg_gs.c
@@ -957,13 +957,11 @@ ac_nir_lower_ngg_gs(nir_shader *shader, const ac_nir_lower_ngg_options *options)
    ngg_gs_finale(b, &state);
 
    /* Take care of metadata and validation before calling other passes */
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
    nir_validate_shader(shader, "after emitting NGG GS");
 
    /* Cleanup */
    nir_lower_vars_to_ssa(shader);
    nir_remove_dead_variables(shader, nir_var_function_temp, NULL);
-   nir_metadata_preserve(impl, nir_metadata_none);
-
-   return true;
+   return nir_progress(true, impl, nir_metadata_none);
 }
diff --git a/src/amd/common/nir/ac_nir_lower_ngg_mesh.c b/src/amd/common/nir/ac_nir_lower_ngg_mesh.c
index 846e2ee1afc..5492d9c7977 100644
--- a/src/amd/common/nir/ac_nir_lower_ngg_mesh.c
+++ b/src/amd/common/nir/ac_nir_lower_ngg_mesh.c
@@ -1429,7 +1429,7 @@ ac_nir_lower_ngg_mesh(nir_shader *shader,
    emit_ms_finale(b, &state);
 
    /* Take care of metadata and validation before calling other passes */
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
    nir_validate_shader(shader, "after emitting NGG MS");
 
    /* Cleanup */
diff --git a/src/amd/common/nir/ac_nir_lower_taskmesh_io_to_mem.c b/src/amd/common/nir/ac_nir_lower_taskmesh_io_to_mem.c
index 2d39039c870..015ee36a33d 100644
--- a/src/amd/common/nir/ac_nir_lower_taskmesh_io_to_mem.c
+++ b/src/amd/common/nir/ac_nir_lower_taskmesh_io_to_mem.c
@@ -306,7 +306,7 @@ ac_nir_lower_task_outputs_to_mem(nir_shader *shader,
        * that are made by lower_task_launch_mesh_workgroups.
        */
       nir_function_impl *impl = nir_shader_get_entrypoint(shader);
-      nir_metadata_preserve(impl, nir_metadata_none);
+      nir_progress(true, impl, nir_metadata_none);
    }
 
    return progress;
diff --git a/src/amd/common/nir/ac_nir_lower_tess_io_to_mem.c b/src/amd/common/nir/ac_nir_lower_tess_io_to_mem.c
index 9e2468db53b..10d752b0c45 100644
--- a/src/amd/common/nir/ac_nir_lower_tess_io_to_mem.c
+++ b/src/amd/common/nir/ac_nir_lower_tess_io_to_mem.c
@@ -1113,7 +1113,7 @@ hs_finale(nir_shader *shader, lower_tess_io_state *st)
    }
    nir_pop_if(b, if_invocation_id_zero);
 
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 }
 
 static nir_def *
diff --git a/src/amd/common/nir/ac_nir_lower_tex.c b/src/amd/common/nir/ac_nir_lower_tex.c
index bdd1fd3d849..935710086f0 100644
--- a/src/amd/common/nir/ac_nir_lower_tex.c
+++ b/src/amd/common/nir/ac_nir_lower_tex.c
@@ -495,10 +495,11 @@ ac_nir_lower_tex(nir_shader *nir, const ac_nir_lower_tex_options *options)
       state.num_wqm_vgprs = 0;
 
       bool divergent_discard = false;
-      if (move_coords_from_divergent_cf(&state, impl, &impl->body, &divergent_discard, false))
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-      else
-         nir_metadata_preserve(impl, nir_metadata_all);
+      bool impl_progress = move_coords_from_divergent_cf(&state, impl,
+                                                         &impl->body,
+                                                         &divergent_discard,
+                                                         false);
+      nir_progress(impl_progress, impl, nir_metadata_control_flow);
    }
 
    progress |= nir_shader_instructions_pass(
diff --git a/src/amd/common/nir/ac_nir_opt_outputs.c b/src/amd/common/nir/ac_nir_opt_outputs.c
index c04e146e146..3ae14222633 100644
--- a/src/amd/common/nir/ac_nir_opt_outputs.c
+++ b/src/amd/common/nir/ac_nir_opt_outputs.c
@@ -232,8 +232,7 @@ bool ac_nir_optimize_outputs(nir_shader *nir, bool sprite_tex_disallowed,
 
    if (nir->info.stage != MESA_SHADER_VERTEX &&
        nir->info.stage != MESA_SHADER_TESS_EVAL) {
-      nir_metadata_preserve(impl, nir_metadata_all);
-      return false;
+      return nir_no_progress(impl);
    }
 
    struct ac_out_info outputs[NUM_TOTAL_VARYING_SLOTS] = { 0 };
@@ -300,10 +299,5 @@ bool ac_nir_optimize_outputs(nir_shader *nir, bool sprite_tex_disallowed,
          ac_eliminate_duplicated_output(outputs, outputs_optimized, i, &b, slot_remap);
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
diff --git a/src/amd/compiler/aco_instruction_selection_setup.cpp b/src/amd/compiler/aco_instruction_selection_setup.cpp
index f89c12bbf58..72661e0c5a8 100644
--- a/src/amd/compiler/aco_instruction_selection_setup.cpp
+++ b/src/amd/compiler/aco_instruction_selection_setup.cpp
@@ -373,7 +373,7 @@ init_context(isel_context* ctx, nir_shader* shader)
 
    /* sanitize control flow */
    sanitize_cf_list(impl, &impl->body);
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 
    /* we'll need these for isel */
    nir_metadata_require(impl, nir_metadata_block_index);
diff --git a/src/amd/vulkan/nir/radv_nir_apply_pipeline_layout.c b/src/amd/vulkan/nir/radv_nir_apply_pipeline_layout.c
index 2b6744b4c05..aee15283b79 100644
--- a/src/amd/vulkan/nir/radv_nir_apply_pipeline_layout.c
+++ b/src/amd/vulkan/nir/radv_nir_apply_pipeline_layout.c
@@ -591,7 +591,7 @@ radv_nir_apply_pipeline_layout(nir_shader *shader, struct radv_device *device, c
 
    if (progress) {
       nir_foreach_function (function, shader) {
-         nir_metadata_preserve(function->impl, nir_metadata_control_flow);
+         nir_progress(true, function->impl, nir_metadata_control_flow);
       }
    }
 
diff --git a/src/amd/vulkan/nir/radv_nir_export_multiview.c b/src/amd/vulkan/nir/radv_nir_export_multiview.c
index 24630e7498e..bb67d0f0514 100644
--- a/src/amd/vulkan/nir/radv_nir_export_multiview.c
+++ b/src/amd/vulkan/nir/radv_nir_export_multiview.c
@@ -82,10 +82,5 @@ radv_nir_export_multiview(nir_shader *nir)
          break;
    }
 
-   if (progress)
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   else
-      nir_metadata_preserve(impl, nir_metadata_all);
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
diff --git a/src/amd/vulkan/nir/radv_nir_lower_abi.c b/src/amd/vulkan/nir/radv_nir_lower_abi.c
index 041515c259e..8eb24c75b62 100644
--- a/src/amd/vulkan/nir/radv_nir_lower_abi.c
+++ b/src/amd/vulkan/nir/radv_nir_lower_abi.c
@@ -516,7 +516,7 @@ radv_nir_lower_abi(nir_shader *shader, enum amd_gfx_level gfx_level, const struc
          state.gsvs_ring[i] = load_gsvs_ring(&b, &state, i);
 
       progress = true;
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 
    progress |= nir_shader_intrinsics_pass(shader, lower_abi_instr, nir_metadata_control_flow, &state);
diff --git a/src/amd/vulkan/nir/radv_nir_lower_cooperative_matrix.c b/src/amd/vulkan/nir/radv_nir_lower_cooperative_matrix.c
index b72d0697335..932dac57d37 100644
--- a/src/amd/vulkan/nir/radv_nir_lower_cooperative_matrix.c
+++ b/src/amd/vulkan/nir/radv_nir_lower_cooperative_matrix.c
@@ -521,11 +521,5 @@ radv_nir_lower_cooperative_matrix(nir_shader *shader, enum amd_gfx_level gfx_lev
 
    _mesa_hash_table_destroy(type_map, NULL);
 
-   if (progress) {
-      nir_metadata_preserve(func->impl, 0);
-   } else {
-      nir_metadata_preserve(func->impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, func->impl, 0);
 }
diff --git a/src/amd/vulkan/nir/radv_nir_lower_primitive_shading_rate.c b/src/amd/vulkan/nir/radv_nir_lower_primitive_shading_rate.c
index a98a8280346..ba387a64012 100644
--- a/src/amd/vulkan/nir/radv_nir_lower_primitive_shading_rate.c
+++ b/src/amd/vulkan/nir/radv_nir_lower_primitive_shading_rate.c
@@ -84,10 +84,5 @@ radv_nir_lower_primitive_shading_rate(nir_shader *nir, enum amd_gfx_level gfx_le
          break;
    }
 
-   if (progress)
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   else
-      nir_metadata_preserve(impl, nir_metadata_all);
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
diff --git a/src/amd/vulkan/nir/radv_nir_lower_ray_queries.c b/src/amd/vulkan/nir/radv_nir_lower_ray_queries.c
index 15a120d8090..217174c3cf4 100644
--- a/src/amd/vulkan/nir/radv_nir_lower_ray_queries.c
+++ b/src/amd/vulkan/nir/radv_nir_lower_ray_queries.c
@@ -719,7 +719,7 @@ radv_nir_lower_ray_queries(struct nir_shader *shader, struct radv_device *device
          }
       }
 
-      nir_metadata_preserve(function->impl, nir_metadata_none);
+      nir_progress(true, function->impl, nir_metadata_none);
    }
 
    ralloc_free(query_ht);
diff --git a/src/amd/vulkan/nir/radv_nir_rt_shader.c b/src/amd/vulkan/nir/radv_nir_rt_shader.c
index 63a561672f0..d1a3a656689 100644
--- a/src/amd/vulkan/nir/radv_nir_rt_shader.c
+++ b/src/amd/vulkan/nir/radv_nir_rt_shader.c
@@ -157,12 +157,7 @@ lower_rt_derefs(nir_shader *shader)
       }
    }
 
-   if (progress)
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   else
-      nir_metadata_preserve(impl, nir_metadata_all);
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 /*
@@ -789,10 +784,7 @@ lower_hit_attribs(nir_shader *shader, nir_variable **hit_attribs, uint32_t workg
    if (!hit_attribs)
       shader->info.shared_size = MAX2(shader->info.shared_size, workgroup_size * RADV_MAX_HIT_ATTRIB_SIZE);
 
-   if (progress)
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 static void
@@ -1210,7 +1202,7 @@ nir_lower_intersection_shader(nir_shader *intersection, nir_shader *any_hit)
          nir_def_rewrite_uses(&intrin->def, accepted);
       }
    }
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 
    /* We did some inlining; have to re-index SSA defs */
    nir_index_ssa_defs(impl);
@@ -1629,7 +1621,7 @@ radv_build_traversal(struct radv_device *device, struct radv_ray_tracing_pipelin
       radv_build_end_trace_token(b, vars, original_tmax, nir_load_var(b, trav_vars.hit),
                                  nir_load_var(b, iteration_instance_count));
 
-   nir_metadata_preserve(nir_shader_get_entrypoint(b->shader), nir_metadata_none);
+   nir_progress(true, nir_shader_get_entrypoint(b->shader), nir_metadata_none);
    radv_nir_lower_hit_attrib_derefs(b->shader);
 
    /* Register storage for hit attributes */
@@ -1748,7 +1740,7 @@ radv_build_traversal_shader(struct radv_device *device, struct radv_ray_tracing_
 
    /* Deal with all the inline functions. */
    nir_index_ssa_defs(nir_shader_get_entrypoint(b.shader));
-   nir_metadata_preserve(nir_shader_get_entrypoint(b.shader), nir_metadata_none);
+   nir_progress(true, nir_shader_get_entrypoint(b.shader), nir_metadata_none);
 
    /* Lower and cleanup variables */
    NIR_PASS(_, b.shader, nir_lower_global_vars_to_local);
@@ -2076,7 +2068,7 @@ radv_nir_lower_rt_abi(nir_shader *shader, const VkRayTracingPipelineCreateInfoKH
       radv_store_arg(&b, args, traversal_info, args->ac.rt.hit_kind, nir_load_var(&b, vars.hit_kind));
    }
 
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 
    /* cleanup passes */
    NIR_PASS(_, shader, nir_lower_global_vars_to_local);
diff --git a/src/amd/vulkan/radv_pipeline_rt.c b/src/amd/vulkan/radv_pipeline_rt.c
index fe9a320ec76..879320f4844 100644
--- a/src/amd/vulkan/radv_pipeline_rt.c
+++ b/src/amd/vulkan/radv_pipeline_rt.c
@@ -353,10 +353,8 @@ move_rt_instructions(nir_shader *shader)
       }
    }
 
-   if (progress)
-      nir_metadata_preserve(nir_shader_get_entrypoint(shader), nir_metadata_control_flow);
-
-   return progress;
+   return nir_progress(progress, nir_shader_get_entrypoint(shader),
+                       nir_metadata_control_flow);
 }
 
 static VkResult
diff --git a/src/asahi/compiler/agx_nir_lower_cull_distance.c b/src/asahi/compiler/agx_nir_lower_cull_distance.c
index 4120622ba67..9a9549b7a65 100644
--- a/src/asahi/compiler/agx_nir_lower_cull_distance.c
+++ b/src/asahi/compiler/agx_nir_lower_cull_distance.c
@@ -123,6 +123,5 @@ agx_nir_lower_cull_distance_fs(nir_shader *s, unsigned nr_distances)
                                            DIV_ROUND_UP(nr_distances, 4));
 
    s->info.fs.uses_discard = true;
-   nir_metadata_preserve(b->impl, nir_metadata_control_flow);
-   return true;
+   return nir_progress(true, b->impl, nir_metadata_control_flow);
 }
diff --git a/src/asahi/compiler/agx_nir_lower_discard_zs_emit.c b/src/asahi/compiler/agx_nir_lower_discard_zs_emit.c
index d4535d02817..7256e6d111e 100644
--- a/src/asahi/compiler/agx_nir_lower_discard_zs_emit.c
+++ b/src/asahi/compiler/agx_nir_lower_discard_zs_emit.c
@@ -129,13 +129,8 @@ agx_nir_lower_zs_emit(nir_shader *s)
          progress |= lower_zs_emit(block, s->info.fs.early_fragment_tests);
       }
 
-      if (progress) {
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
-
-      any_progress |= progress;
+      any_progress = any_progress | nir_progress(progress, impl,
+                                                 nir_metadata_control_flow);
    }
 
    return any_progress;
diff --git a/src/asahi/compiler/agx_nir_lower_sample_mask.c b/src/asahi/compiler/agx_nir_lower_sample_mask.c
index 747c115e299..37a40c8c848 100644
--- a/src/asahi/compiler/agx_nir_lower_sample_mask.c
+++ b/src/asahi/compiler/agx_nir_lower_sample_mask.c
@@ -213,11 +213,10 @@ agx_nir_lower_sample_mask(nir_shader *shader)
       }
    } else {
       /* regular shaders that don't use discard have nothing to lower */
-      nir_metadata_preserve(impl, nir_metadata_all);
-      return false;
+      return nir_no_progress(impl);
    }
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 
    nir_shader_intrinsics_pass(shader, lower_discard_to_sample_mask_0,
                               nir_metadata_control_flow, NULL);
diff --git a/src/asahi/lib/agx_nir_lower_alpha.c b/src/asahi/lib/agx_nir_lower_alpha.c
index 58eeebe3f4e..6b039c00552 100644
--- a/src/asahi/lib/agx_nir_lower_alpha.c
+++ b/src/asahi/lib/agx_nir_lower_alpha.c
@@ -47,8 +47,7 @@ agx_nir_lower_alpha_to_coverage(nir_shader *shader, uint8_t nr_samples)
     */
    nir_def *rgba = store ? store->src[0].ssa : NULL;
    if (!rgba || rgba->num_components < 4) {
-      nir_metadata_preserve(impl, nir_metadata_all);
-      return false;
+      return nir_no_progress(impl);
    }
 
    nir_builder _b = nir_builder_at(nir_before_instr(&store->instr));
@@ -68,8 +67,7 @@ agx_nir_lower_alpha_to_coverage(nir_shader *shader, uint8_t nr_samples)
    /* Discard samples that aren't covered */
    nir_discard_agx(b, nir_inot(b, mask));
    shader->info.fs.uses_discard = true;
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
-   return true;
+   return nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 /*
@@ -117,11 +115,5 @@ agx_nir_lower_alpha_to_one(nir_shader *shader)
       progress = true;
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
diff --git a/src/asahi/lib/agx_nir_lower_gs.c b/src/asahi/lib/agx_nir_lower_gs.c
index 864bab5fb58..79c967ce391 100644
--- a/src/asahi/lib/agx_nir_lower_gs.c
+++ b/src/asahi/lib/agx_nir_lower_gs.c
@@ -1190,7 +1190,7 @@ agx_nir_lower_gs_instancing(nir_shader *gs)
    nir_pop_loop(&b, loop);
 
    /* We've mucked about with control flow */
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 
    /* Use the loop counter as the invocation ID each iteration */
    nir_shader_intrinsics_pass(gs, rewrite_invocation_id,
diff --git a/src/asahi/lib/agx_nir_lower_msaa.c b/src/asahi/lib/agx_nir_lower_msaa.c
index c6eb6325cbb..06636141b37 100644
--- a/src/asahi/lib/agx_nir_lower_msaa.c
+++ b/src/asahi/lib/agx_nir_lower_msaa.c
@@ -106,7 +106,7 @@ agx_nir_wrap_per_sample_loop(nir_shader *shader, uint8_t nr_samples)
    nir_pop_loop(&b, loop);
 
    /* We've mucked about with control flow */
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 
    /* Use the loop variable for the active sampple mask each iteration */
    nir_shader_intrinsics_pass(shader, lower_active_samples,
diff --git a/src/asahi/lib/agx_nir_lower_tess.c b/src/asahi/lib/agx_nir_lower_tess.c
index eecf9b74f2e..8325c4e4182 100644
--- a/src/asahi/lib/agx_nir_lower_tess.c
+++ b/src/asahi/lib/agx_nir_lower_tess.c
@@ -289,6 +289,6 @@ agx_nir_lower_tes(nir_shader *tes, bool to_hw_vs)
    }
 
    nir_lower_idiv(tes, &(nir_lower_idiv_options){.allow_fp16 = true});
-   nir_metadata_preserve(nir_shader_get_entrypoint(tes), nir_metadata_none);
-   return true;
+   return nir_progress(true, nir_shader_get_entrypoint(tes),
+                       nir_metadata_none);
 }
diff --git a/src/asahi/lib/agx_nir_prolog_epilog.c b/src/asahi/lib/agx_nir_prolog_epilog.c
index 946d564400d..a3b70fc0e42 100644
--- a/src/asahi/lib/agx_nir_prolog_epilog.c
+++ b/src/asahi/lib/agx_nir_prolog_epilog.c
@@ -53,8 +53,7 @@ agx_nir_lower_poly_stipple(nir_shader *s)
    nir_demote_if(b, nir_ieq_imm(b, bit, 0));
    s->info.fs.uses_discard = true;
 
-   nir_metadata_preserve(b->impl, nir_metadata_control_flow);
-   return true;
+   return nir_progress(true, b->impl, nir_metadata_control_flow);
 }
 
 static bool
@@ -685,8 +684,7 @@ agx_nir_lower_stats_fs(nir_shader *s)
    nir_global_atomic(b, 32, addr, samples, .atomic_op = nir_atomic_op_iadd);
 
    nir_pop_if(b, NULL);
-   nir_metadata_preserve(b->impl, nir_metadata_control_flow);
-   return true;
+   return nir_progress(true, b->impl, nir_metadata_control_flow);
 }
 
 void
diff --git a/src/asahi/vulkan/hk_shader.c b/src/asahi/vulkan/hk_shader.c
index e5921660c47..33ee4be5d08 100644
--- a/src/asahi/vulkan/hk_shader.c
+++ b/src/asahi/vulkan/hk_shader.c
@@ -431,8 +431,7 @@ hk_nir_insert_psiz_write(nir_shader *nir)
    nir_function_impl *impl = nir_shader_get_entrypoint(nir);
 
    if (nir->info.outputs_written & VARYING_BIT_PSIZ) {
-      nir_metadata_preserve(impl, nir_metadata_all);
-      return false;
+      return nir_no_progress(impl);
    }
 
    nir_builder b = nir_builder_at(nir_after_impl(impl));
@@ -443,8 +442,7 @@ hk_nir_insert_psiz_write(nir_shader *nir)
                     .io_semantics.num_slots = 1, .src_type = nir_type_float32);
 
    nir->info.outputs_written |= VARYING_BIT_PSIZ;
-   nir_metadata_preserve(b.impl, nir_metadata_control_flow);
-   return true;
+   return nir_progress(true, b.impl, nir_metadata_control_flow);
 }
 
 static nir_def *
diff --git a/src/broadcom/compiler/v3d_nir_lower_io.c b/src/broadcom/compiler/v3d_nir_lower_io.c
index 95d4ce6f194..557db360a9e 100644
--- a/src/broadcom/compiler/v3d_nir_lower_io.c
+++ b/src/broadcom/compiler/v3d_nir_lower_io.c
@@ -673,8 +673,7 @@ v3d_nir_lower_io(nir_shader *s, struct v3d_compile *c)
                         emit_gs_vpm_output_header_prolog(c, &b, &state);
                 }
 
-                nir_metadata_preserve(impl,
-                                      nir_metadata_control_flow);
+                nir_progress(true, impl, nir_metadata_control_flow);
         }
 
         if (s->info.stage != MESA_SHADER_COMPUTE)
diff --git a/src/broadcom/compiler/v3d_nir_lower_line_smooth.c b/src/broadcom/compiler/v3d_nir_lower_line_smooth.c
index b4d512c6a19..0754fcd04e7 100644
--- a/src/broadcom/compiler/v3d_nir_lower_line_smooth.c
+++ b/src/broadcom/compiler/v3d_nir_lower_line_smooth.c
@@ -164,12 +164,7 @@ v3d_nir_lower_line_smooth(nir_shader *s)
 
                 progress |= lower_line_smooth_func(&state, impl);
 
-                if (progress) {
-                        nir_metadata_preserve(impl,
-                                              nir_metadata_control_flow);
-                } else {
-                        nir_metadata_preserve(impl, nir_metadata_all);
-                }
+                nir_progress(progress, impl, nir_metadata_control_flow);
         }
 
         return progress;
diff --git a/src/broadcom/compiler/v3d_nir_lower_logic_ops.c b/src/broadcom/compiler/v3d_nir_lower_logic_ops.c
index f15f7fe46e5..8decc59f786 100644
--- a/src/broadcom/compiler/v3d_nir_lower_logic_ops.c
+++ b/src/broadcom/compiler/v3d_nir_lower_logic_ops.c
@@ -408,13 +408,7 @@ v3d_nir_lower_logic_ops(nir_shader *s, struct v3d_compile *c)
                 nir_foreach_block(block, impl)
                         progress |= v3d_nir_lower_logic_ops_block(block, c);
 
-                if (progress) {
-                        nir_metadata_preserve(impl,
-                                              nir_metadata_control_flow);
-                } else {
-                        nir_metadata_preserve(impl,
-                                              nir_metadata_all);
-                }
+                nir_progress(progress, impl, nir_metadata_control_flow);
         }
 
         return progress;
diff --git a/src/broadcom/compiler/vir.c b/src/broadcom/compiler/vir.c
index fd0fae5a9c2..632719eec0d 100644
--- a/src/broadcom/compiler/vir.c
+++ b/src/broadcom/compiler/vir.c
@@ -1576,8 +1576,7 @@ v3d_nir_sort_constant_ubo_loads(nir_shader *s, struct v3d_compile *c)
                         c->sorted_any_ubo_loads |=
                                 v3d_nir_sort_constant_ubo_loads_block(c, block);
                 }
-                nir_metadata_preserve(impl,
-                                      nir_metadata_control_flow);
+                nir_progress(true, impl, nir_metadata_control_flow);
         }
         return c->sorted_any_ubo_loads;
 }
@@ -1672,8 +1671,7 @@ v3d_nir_lower_subgroup_intrinsics(nir_shader *s, struct v3d_compile *c)
                 nir_foreach_block(block, impl)
                         progress |= lower_subgroup_intrinsics(c, block, &b);
 
-                nir_metadata_preserve(impl,
-                                      nir_metadata_control_flow);
+                nir_progress(true, impl, nir_metadata_control_flow);
         }
         return progress;
 }
diff --git a/src/compiler/clc/nir_load_libclc.c b/src/compiler/clc/nir_load_libclc.c
index 10840f98641..28c9ca0783f 100644
--- a/src/compiler/clc/nir_load_libclc.c
+++ b/src/compiler/clc/nir_load_libclc.c
@@ -302,14 +302,14 @@ libclc_add_generic_variants(nir_shader *shader)
       }
 
       progress = true;
-      nir_metadata_preserve(func->impl, nir_metadata_none);
+      nir_progress(true, func->impl, nir_metadata_none);
    }
 
    if (progress) {
       nir_foreach_function_impl(impl, shader) {
          if (impl->valid_metadata & nir_metadata_not_properly_reset) {
             /* Preserve all metadata for functions that we didn't modify. */
-            nir_metadata_preserve(impl, nir_metadata_all);
+            nir_no_progress(impl);
          }
       }
    }
diff --git a/src/compiler/glsl/gl_nir_linker.c b/src/compiler/glsl/gl_nir_linker.c
index b5a3ff66144..95bb165ce82 100644
--- a/src/compiler/glsl/gl_nir_linker.c
+++ b/src/compiler/glsl/gl_nir_linker.c
@@ -1215,8 +1215,7 @@ gl_nir_add_point_size(nir_shader *nir)
    nir->info.outputs_written |= VARYING_BIT_PSIZ;
 
    /* We always modify the entrypoint */
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
-   return true;
+   return nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 static void
@@ -1251,8 +1250,7 @@ gl_nir_zero_initialize_clip_distance(nir_shader *nir)
    if (clip_dist1)
       zero_array_members(&b, clip_dist1);
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
-   return true;
+   return nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 static void
diff --git a/src/compiler/glsl/gl_nir_lower_blend_equation_advanced.c b/src/compiler/glsl/gl_nir_lower_blend_equation_advanced.c
index 404c64f4484..baf919e77f6 100644
--- a/src/compiler/glsl/gl_nir_lower_blend_equation_advanced.c
+++ b/src/compiler/glsl/gl_nir_lower_blend_equation_advanced.c
@@ -489,8 +489,7 @@ gl_nir_lower_blend_equation_advanced(nir_shader *sh, bool coherent)
    nir_function_impl *impl = nir_shader_get_entrypoint(sh);
 
    if (sh->info.fs.advanced_blend_modes == 0) {
-      nir_metadata_preserve(impl, nir_metadata_all);
-      return false;
+      return nir_no_progress(impl);
    }
 
    sh->info.fs.uses_sample_shading = true;
@@ -575,7 +574,7 @@ gl_nir_lower_blend_equation_advanced(nir_shader *sh, bool coherent)
       }
    }
 
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 
    /* Remove any dead writes before assigning location to __blend_fb_fetch
     * otherwise they will be unable to be removed.
diff --git a/src/compiler/glsl/gl_nir_lower_buffers.c b/src/compiler/glsl/gl_nir_lower_buffers.c
index 8e48e298141..5058f9634bb 100644
--- a/src/compiler/glsl/gl_nir_lower_buffers.c
+++ b/src/compiler/glsl/gl_nir_lower_buffers.c
@@ -311,13 +311,7 @@ lower_buffer_interface_derefs_impl(nir_function_impl *impl,
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c
index 4aef8264fae..307003874f5 100644
--- a/src/compiler/nir/nir.c
+++ b/src/compiler/nir/nir.c
@@ -2237,13 +2237,7 @@ nir_function_impl_lower_instructions(nir_function_impl *impl,
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, preserved);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, preserved);
 }
 
 bool
diff --git a/src/compiler/nir/nir_builder.c b/src/compiler/nir/nir_builder.c
index 66569b340d2..216c0a4f080 100644
--- a/src/compiler/nir/nir_builder.c
+++ b/src/compiler/nir/nir_builder.c
@@ -683,7 +683,7 @@ nir_call_serialized(nir_builder *b, const uint32_t *serialized,
 
    /* Indices & metadata are completely messed up now */
    nir_index_ssa_defs(b->impl);
-   nir_metadata_preserve(b->impl, nir_metadata_none);
+   nir_progress(true, b->impl, nir_metadata_none);
    ralloc_free(memctx);
    return ret;
 }
diff --git a/src/compiler/nir/nir_builder.h b/src/compiler/nir/nir_builder.h
index 949b371c61b..d3cd310f71a 100644
--- a/src/compiler/nir/nir_builder.h
+++ b/src/compiler/nir/nir_builder.h
@@ -109,13 +109,7 @@ nir_function_instructions_pass(nir_function_impl *impl,
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, preserved);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, preserved);
 }
 
 /**
@@ -172,13 +166,7 @@ nir_function_intrinsics_pass(nir_function_impl *impl,
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, preserved);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, preserved);
 }
 
 /**
@@ -228,12 +216,7 @@ nir_shader_alu_pass(nir_shader *shader,
          }
       }
 
-      if (func_progress) {
-         nir_metadata_preserve(impl, preserved);
-         progress = true;
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      progress = progress | nir_progress(func_progress, impl, preserved);
    }
 
    return progress;
@@ -259,12 +242,7 @@ nir_shader_tex_pass(nir_shader *shader, nir_tex_pass_cb pass,
          }
       }
 
-      if (func_progress) {
-         nir_metadata_preserve(impl, preserved);
-         progress = true;
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      progress = progress | nir_progress(func_progress, impl, preserved);
    }
 
    return progress;
@@ -289,12 +267,7 @@ nir_shader_phi_pass(nir_shader *shader,
          }
       }
 
-      if (func_progress) {
-         nir_metadata_preserve(impl, preserved);
-         progress = true;
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      progress = progress | nir_progress(func_progress, impl, preserved);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_control_flow.c b/src/compiler/nir/nir_control_flow.c
index a427ff9c56a..41c1224515b 100644
--- a/src/compiler/nir/nir_control_flow.c
+++ b/src/compiler/nir/nir_control_flow.c
@@ -495,7 +495,7 @@ nir_handle_add_jump(nir_block *block)
    unlink_block_successors(block);
 
    nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node);
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 
    switch (jump_instr->type) {
    case nir_jump_return:
@@ -554,7 +554,7 @@ nir_handle_remove_jump(nir_block *block, nir_jump_type type)
    unlink_jump(block, type, true);
 
    nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node);
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 }
 
 static void
@@ -751,7 +751,7 @@ nir_cf_extract(nir_cf_list *extracted, nir_cursor begin, nir_cursor end)
    exec_list_make_empty(&extracted->list);
 
    /* Dominance and other block-related information is toast. */
-   nir_metadata_preserve(extracted->impl, nir_metadata_none);
+   nir_progress(true, extracted->impl, nir_metadata_none);
 
    nir_cf_node *cf_node = &block_begin->cf_node;
    nir_cf_node *cf_node_end = &block_end->cf_node;
diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c
index 1adc2e99ff3..bc3c1b4cb82 100644
--- a/src/compiler/nir/nir_deref.c
+++ b/src/compiler/nir/nir_deref.c
@@ -393,13 +393,7 @@ nir_remove_dead_derefs_impl(nir_function_impl *impl)
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
@@ -1540,13 +1534,7 @@ nir_opt_deref_impl(nir_function_impl *impl)
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir_divergence_analysis.c b/src/compiler/nir/nir_divergence_analysis.c
index ed80bb7fab3..9564cc2e15e 100644
--- a/src/compiler/nir/nir_divergence_analysis.c
+++ b/src/compiler/nir/nir_divergence_analysis.c
@@ -1452,7 +1452,7 @@ nir_divergence_analysis_impl(nir_function_impl *impl, nir_divergence_options opt
    /* Unless this pass is called with shader->options->divergence_analysis_options,
     * it invalidates nir_metadata_divergence.
     */
-   nir_metadata_preserve(impl, ~nir_metadata_divergence);
+   nir_progress(true, impl, ~nir_metadata_divergence);
 }
 
 void
@@ -1484,7 +1484,7 @@ nir_vertex_divergence_analysis(nir_shader *shader)
       nir_metadata_require(impl, nir_metadata_block_index);
       state.impl = impl;
       visit_cf_list(&impl->body, &state);
-      nir_metadata_preserve(impl, nir_metadata_all & ~nir_metadata_divergence);
+      nir_progress(true, impl, nir_metadata_all & ~nir_metadata_divergence);
    }
 }
 
diff --git a/src/compiler/nir/nir_from_ssa.c b/src/compiler/nir/nir_from_ssa.c
index 1f3d47256f8..8acf8193082 100644
--- a/src/compiler/nir/nir_from_ssa.c
+++ b/src/compiler/nir/nir_from_ssa.c
@@ -1054,7 +1054,7 @@ nir_convert_from_ssa_impl(nir_function_impl *impl,
    }
 
    /* Mark metadata as dirty before we ask for liveness analysis */
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 
    nir_metadata_require(impl, nir_metadata_instr_index |
                                  nir_metadata_live_defs |
@@ -1074,7 +1074,7 @@ nir_convert_from_ssa_impl(nir_function_impl *impl,
       resolve_parallel_copies_block(block, &state);
    }
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 
    /* Clean up dead instructions and the hash tables */
    nir_instr_free_list(&state.dead_instrs);
diff --git a/src/compiler/nir/nir_group_loads.c b/src/compiler/nir/nir_group_loads.c
index bdc689136db..037f791faa6 100644
--- a/src/compiler/nir/nir_group_loads.c
+++ b/src/compiler/nir/nir_group_loads.c
@@ -476,7 +476,7 @@ nir_group_loads(nir_shader *shader, nir_load_grouping grouping,
          process_block(block, grouping, max_distance);
       }
 
-      nir_metadata_preserve(impl, nir_metadata_control_flow |
-                                     nir_metadata_loop_analysis);
+      nir_progress(true, impl,
+                   nir_metadata_control_flow | nir_metadata_loop_analysis);
    }
 }
diff --git a/src/compiler/nir/nir_inline_uniforms.c b/src/compiler/nir/nir_inline_uniforms.c
index b9add68fd39..6a53bd6cbae 100644
--- a/src/compiler/nir/nir_inline_uniforms.c
+++ b/src/compiler/nir/nir_inline_uniforms.c
@@ -462,7 +462,7 @@ nir_inline_uniforms(nir_shader *shader, unsigned num_uniforms,
             }
          }
 
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
+         nir_progress(true, impl, nir_metadata_control_flow);
       }
    }
 }
diff --git a/src/compiler/nir/nir_linking_helpers.c b/src/compiler/nir/nir_linking_helpers.c
index 9ed249e94d9..79ea89e877b 100644
--- a/src/compiler/nir/nir_linking_helpers.c
+++ b/src/compiler/nir/nir_linking_helpers.c
@@ -1074,10 +1074,7 @@ replace_varying_input_by_constant_load(nir_shader *shader,
       }
    }
 
-   if (progress)
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 static bool
@@ -1123,10 +1120,7 @@ replace_duplicate_input(nir_shader *shader, nir_variable *input_var,
       }
    }
 
-   if (progress)
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 static bool
@@ -1291,10 +1285,7 @@ replace_varying_input_by_uniform_load(nir_shader *shader,
       }
    }
 
-   if (progress)
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 /* The GLSL ES 3.20 spec says:
diff --git a/src/compiler/nir/nir_lower_amul.c b/src/compiler/nir/nir_lower_amul.c
index b47ed88e5aa..5ed2bf5675c 100644
--- a/src/compiler/nir/nir_lower_amul.c
+++ b/src/compiler/nir/nir_lower_amul.c
@@ -275,7 +275,7 @@ nir_lower_amul(nir_shader *shader,
          }
       }
 
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 
    return state.progress;
diff --git a/src/compiler/nir/nir_lower_array_deref_of_vec.c b/src/compiler/nir/nir_lower_array_deref_of_vec.c
index 1cd89f9ee96..40888c9c75b 100644
--- a/src/compiler/nir/nir_lower_array_deref_of_vec.c
+++ b/src/compiler/nir/nir_lower_array_deref_of_vec.c
@@ -131,14 +131,8 @@ nir_lower_array_deref_of_vec_impl(nir_function_impl *impl,
       }
    }
 
-   if (progress) {
-      /* indirect store lower will change control flow */
-      nir_metadata_preserve(impl, has_indirect_store ? nir_metadata_none : nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl,
+                       has_indirect_store ? nir_metadata_none : nir_metadata_control_flow);
 }
 
 /* Lowers away array dereferences on vectors
diff --git a/src/compiler/nir/nir_lower_atomics_to_ssbo.c b/src/compiler/nir/nir_lower_atomics_to_ssbo.c
index 440b122e86e..3d23250ff13 100644
--- a/src/compiler/nir/nir_lower_atomics_to_ssbo.c
+++ b/src/compiler/nir/nir_lower_atomics_to_ssbo.c
@@ -196,7 +196,7 @@ nir_lower_atomics_to_ssbo(nir_shader *shader, unsigned offset_align_state)
          }
       }
 
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 
    if (progress) {
diff --git a/src/compiler/nir/nir_lower_bit_size.c b/src/compiler/nir/nir_lower_bit_size.c
index 6a0e8a14ccf..25f11787888 100644
--- a/src/compiler/nir/nir_lower_bit_size.c
+++ b/src/compiler/nir/nir_lower_bit_size.c
@@ -284,13 +284,7 @@ lower_impl(nir_function_impl *impl,
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir_lower_bitmap.c b/src/compiler/nir/nir_lower_bitmap.c
index d56a324ec36..7337e16f950 100644
--- a/src/compiler/nir/nir_lower_bitmap.c
+++ b/src/compiler/nir/nir_lower_bitmap.c
@@ -106,7 +106,7 @@ lower_bitmap_impl(nir_function_impl *impl,
 
    lower_bitmap(impl->function->shader, &b, options);
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir_lower_clip.c b/src/compiler/nir/nir_lower_clip.c
index c64f0995454..865df247c67 100644
--- a/src/compiler/nir/nir_lower_clip.c
+++ b/src/compiler/nir/nir_lower_clip.c
@@ -416,9 +416,7 @@ nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables, bool use_vars,
       lower_clip_vertex_var(&b, &state);
    }
 
-   nir_metadata_preserve(impl, nir_metadata_dominance);
-
-   return true;
+   return nir_progress(true, impl, nir_metadata_dominance);
 }
 
 /*
@@ -568,7 +566,7 @@ lower_clip_fs(nir_function_impl *impl, unsigned ucp_enables,
       b.shader->info.fs.uses_discard = true;
    }
 
-   nir_metadata_preserve(impl, nir_metadata_dominance);
+   nir_progress(true, impl, nir_metadata_dominance);
 }
 
 static bool
diff --git a/src/compiler/nir/nir_lower_clip_cull_distance_arrays.c b/src/compiler/nir/nir_lower_clip_cull_distance_arrays.c
index 1a12c2903c0..9faa2703ef4 100644
--- a/src/compiler/nir/nir_lower_clip_cull_distance_arrays.c
+++ b/src/compiler/nir/nir_lower_clip_cull_distance_arrays.c
@@ -512,14 +512,8 @@ nir_lower_clip_cull_distance_arrays(nir_shader *nir)
    }
 
    nir_foreach_function_impl(impl, nir) {
-      if (progress) {
-         nir_metadata_preserve(impl,
-                               nir_metadata_control_flow |
-                               nir_metadata_live_defs |
-                               nir_metadata_loop_analysis);
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      nir_progress(progress, impl,
+                   nir_metadata_control_flow | nir_metadata_live_defs | nir_metadata_loop_analysis);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_lower_const_arrays_to_uniforms.c b/src/compiler/nir/nir_lower_const_arrays_to_uniforms.c
index 2b6f7ff3e7a..6d61868a5a3 100644
--- a/src/compiler/nir/nir_lower_const_arrays_to_uniforms.c
+++ b/src/compiler/nir/nir_lower_const_arrays_to_uniforms.c
@@ -406,7 +406,7 @@ nir_lower_const_arrays_to_uniforms(nir_shader *shader,
       }
    }
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 
    ralloc_free(var_infos);
    _mesa_hash_table_destroy(const_array_vars, NULL);
diff --git a/src/compiler/nir/nir_lower_continue_constructs.c b/src/compiler/nir/nir_lower_continue_constructs.c
index 6dd408b2258..5e9032107fc 100644
--- a/src/compiler/nir/nir_lower_continue_constructs.c
+++ b/src/compiler/nir/nir_lower_continue_constructs.c
@@ -139,7 +139,7 @@ lower_continue_constructs_impl(nir_function_impl *impl)
    bool progress = visit_cf_list(&b, &impl->body, &repair_ssa);
 
    if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_none);
+      nir_progress(true, impl, nir_metadata_none);
 
       /* Merge the Phis from Header and Continue Target */
       nir_lower_reg_intrinsics_to_ssa_impl(impl);
@@ -151,7 +151,7 @@ lower_continue_constructs_impl(nir_function_impl *impl)
       if (repair_ssa)
          nir_repair_ssa_impl(impl);
    } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
+      nir_no_progress(impl);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_lower_double_ops.c b/src/compiler/nir/nir_lower_double_ops.c
index 62e4a6fba23..16899101f22 100644
--- a/src/compiler/nir/nir_lower_double_ops.c
+++ b/src/compiler/nir/nir_lower_double_ops.c
@@ -881,17 +881,13 @@ nir_lower_doubles_impl(nir_function_impl *impl,
       /* Indices are completely messed up now */
       nir_index_ssa_defs(impl);
 
-      nir_metadata_preserve(impl, nir_metadata_none);
+      nir_progress(true, impl, nir_metadata_none);
 
       /* And we have deref casts we need to clean up thanks to function
        * inlining.
        */
       nir_opt_deref_impl(impl);
-   } else if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
+   } else nir_progress(progress, impl, nir_metadata_control_flow);
 
    return progress;
 }
diff --git a/src/compiler/nir/nir_lower_flrp.c b/src/compiler/nir/nir_lower_flrp.c
index 7f17ea071ce..f40d9045ad2 100644
--- a/src/compiler/nir/nir_lower_flrp.c
+++ b/src/compiler/nir/nir_lower_flrp.c
@@ -634,7 +634,7 @@ lower_flrp_impl(nir_function_impl *impl,
       }
    }
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 /**
diff --git a/src/compiler/nir/nir_lower_global_vars_to_local.c b/src/compiler/nir/nir_lower_global_vars_to_local.c
index fb185191208..00a15941c53 100644
--- a/src/compiler/nir/nir_lower_global_vars_to_local.c
+++ b/src/compiler/nir/nir_lower_global_vars_to_local.c
@@ -88,9 +88,8 @@ nir_lower_global_vars_to_local(nir_shader *shader)
          exec_node_remove(&var->node);
          var->data.mode = nir_var_function_temp;
          exec_list_push_tail(&impl->locals, &var->node);
-         nir_metadata_preserve(impl, nir_metadata_control_flow |
-                                        nir_metadata_live_defs);
-         progress = true;
+         progress = nir_progress(true, impl,
+                                 nir_metadata_control_flow | nir_metadata_live_defs);
       }
    }
 
@@ -100,7 +99,7 @@ nir_lower_global_vars_to_local(nir_shader *shader)
       nir_fixup_deref_modes(shader);
 
    nir_foreach_function_impl(impl, shader) {
-      nir_metadata_preserve(impl, nir_metadata_all);
+      nir_no_progress(impl);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_lower_goto_ifs.c b/src/compiler/nir/nir_lower_goto_ifs.c
index cb32d34405f..3d53ecdcdd4 100644
--- a/src/compiler/nir/nir_lower_goto_ifs.c
+++ b/src/compiler/nir/nir_lower_goto_ifs.c
@@ -914,8 +914,7 @@ static bool
 nir_lower_goto_ifs_impl(nir_function_impl *impl)
 {
    if (impl->structured) {
-      nir_metadata_preserve(impl, nir_metadata_all);
-      return false;
+      return nir_no_progress(impl);
    }
 
    nir_metadata_require(impl, nir_metadata_dominance);
@@ -961,7 +960,7 @@ nir_lower_goto_ifs_impl(nir_function_impl *impl)
    ralloc_free(mem_ctx);
    nir_cf_delete(&cf_list);
 
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 
    nir_repair_ssa_impl(impl);
    nir_lower_reg_intrinsics_to_ssa_impl(impl);
diff --git a/src/compiler/nir/nir_lower_gs_intrinsics.c b/src/compiler/nir/nir_lower_gs_intrinsics.c
index 9d956f841af..93a831badfe 100644
--- a/src/compiler/nir/nir_lower_gs_intrinsics.c
+++ b/src/compiler/nir/nir_lower_gs_intrinsics.c
@@ -537,7 +537,7 @@ nir_lower_gs_intrinsics(nir_shader *shader, nir_lower_gs_intrinsics_flags option
    /* This only works because we have a single main() function. */
    append_set_vertex_and_primitive_count(impl->end_block, &state);
 
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 
    return state.progress;
 }
diff --git a/src/compiler/nir/nir_lower_indirect_derefs.c b/src/compiler/nir/nir_lower_indirect_derefs.c
index 5b5506edddf..1b729668187 100644
--- a/src/compiler/nir/nir_lower_indirect_derefs.c
+++ b/src/compiler/nir/nir_lower_indirect_derefs.c
@@ -201,12 +201,7 @@ lower_indirects_impl(nir_function_impl *impl, nir_variable_mode modes,
                                               max_lower_array_len);
    }
 
-   if (progress)
-      nir_metadata_preserve(impl, nir_metadata_none);
-   else
-      nir_metadata_preserve(impl, nir_metadata_all);
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_none);
 }
 
 /** Lowers indirect variable loads/stores to direct loads/stores.
diff --git a/src/compiler/nir/nir_lower_int_to_float.c b/src/compiler/nir/nir_lower_int_to_float.c
index e7c935f64ff..dc107de07e5 100644
--- a/src/compiler/nir/nir_lower_int_to_float.c
+++ b/src/compiler/nir/nir_lower_int_to_float.c
@@ -297,11 +297,7 @@ nir_lower_int_to_float_impl(nir_function_impl *impl)
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
+   nir_progress(progress, impl, nir_metadata_control_flow);
 
    free(float_types);
    free(int_types);
diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c
index 09c87d8ee84..71c4fb5fe4b 100644
--- a/src/compiler/nir/nir_lower_io.c
+++ b/src/compiler/nir/nir_lower_io.c
@@ -876,7 +876,7 @@ nir_lower_io_impl(nir_function_impl *impl,
 
    ralloc_free(state.dead_ctx);
 
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 
    return progress;
 }
@@ -2473,13 +2473,7 @@ nir_lower_explicit_io_impl(nir_function_impl *impl, nir_variable_mode modes,
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_none);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_none);
 }
 
 /** Lower explicitly laid out I/O access to byte offset/address intrinsics
@@ -2564,15 +2558,8 @@ nir_lower_vars_to_explicit_types_impl(nir_function_impl *impl,
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow |
-                                     nir_metadata_live_defs |
-                                     nir_metadata_loop_analysis);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl,
+                       nir_metadata_control_flow | nir_metadata_live_defs | nir_metadata_loop_analysis);
 }
 
 static bool
@@ -3131,10 +3118,7 @@ nir_io_add_const_offset_to_base(nir_shader *nir, nir_variable_mode modes)
          impl_progress |= add_const_offset_to_base_block(block, &b, modes);
       }
       progress |= impl_progress;
-      if (impl_progress)
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-      else
-         nir_metadata_preserve(impl, nir_metadata_all);
+      nir_progress(impl_progress, impl, nir_metadata_control_flow);
    }
 
    return progress;
@@ -3211,12 +3195,7 @@ nir_lower_color_inputs(nir_shader *nir)
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
@@ -3290,7 +3269,7 @@ nir_io_add_intrinsic_xfb_info(nir_shader *nir)
       }
    }
 
-   nir_metadata_preserve(impl, nir_metadata_all);
+   nir_no_progress(impl);
    return progress;
 }
 
diff --git a/src/compiler/nir/nir_lower_io_arrays_to_elements.c b/src/compiler/nir/nir_lower_io_arrays_to_elements.c
index 673e11cd5b3..14c5c4be841 100644
--- a/src/compiler/nir/nir_lower_io_arrays_to_elements.c
+++ b/src/compiler/nir/nir_lower_io_arrays_to_elements.c
@@ -351,11 +351,7 @@ lower_io_arrays_to_elements(nir_shader *shader, nir_variable_mode mask,
          }
       }
 
-      if (progress) {
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      nir_progress(progress, impl, nir_metadata_control_flow);
    }
 }
 
diff --git a/src/compiler/nir/nir_lower_io_to_temporaries.c b/src/compiler/nir/nir_lower_io_to_temporaries.c
index 8c7b0809bdd..f4cb0ff5891 100644
--- a/src/compiler/nir/nir_lower_io_to_temporaries.c
+++ b/src/compiler/nir/nir_lower_io_to_temporaries.c
@@ -340,8 +340,7 @@ nir_lower_io_to_temporaries(nir_shader *shader, nir_function_impl *entrypoint,
        shader->info.stage != MESA_SHADER_TESS_EVAL &&
        shader->info.stage != MESA_SHADER_GEOMETRY &&
        shader->info.stage != MESA_SHADER_FRAGMENT) {
-      nir_metadata_preserve(entrypoint, nir_metadata_all);
-      return false;
+      return nir_no_progress(entrypoint);
    }
 
    state.shader = shader;
@@ -381,7 +380,7 @@ nir_lower_io_to_temporaries(nir_shader *shader, nir_function_impl *entrypoint,
       if (outputs)
          emit_output_copies_impl(&state, impl);
 
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 
    exec_list_append(&shader->variables, &state.old_inputs);
diff --git a/src/compiler/nir/nir_lower_io_to_vector.c b/src/compiler/nir/nir_lower_io_to_vector.c
index ef54b3c5268..d96ff048094 100644
--- a/src/compiler/nir/nir_lower_io_to_vector.c
+++ b/src/compiler/nir/nir_lower_io_to_vector.c
@@ -596,11 +596,7 @@ nir_lower_io_to_vector_impl(nir_function_impl *impl, nir_variable_mode modes)
    nir_fixup_deref_modes(b.shader);
    util_dynarray_fini(&demote_vars);
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir_lower_load_const_to_scalar.c b/src/compiler/nir/nir_lower_load_const_to_scalar.c
index 79e2e1f5421..a8351dde71b 100644
--- a/src/compiler/nir/nir_lower_load_const_to_scalar.c
+++ b/src/compiler/nir/nir_lower_load_const_to_scalar.c
@@ -74,13 +74,7 @@ nir_lower_load_const_to_scalar_impl(nir_function_impl *impl)
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir_lower_locals_to_regs.c b/src/compiler/nir/nir_lower_locals_to_regs.c
index d69e65773f5..cb3b0e39c36 100644
--- a/src/compiler/nir/nir_lower_locals_to_regs.c
+++ b/src/compiler/nir/nir_lower_locals_to_regs.c
@@ -301,7 +301,7 @@ impl(nir_function_impl *impl, uint8_t bool_bitsize)
       lower_locals_to_regs_block(block, &state);
    }
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 
    _mesa_hash_table_destroy(state.regs_table, NULL);
 
diff --git a/src/compiler/nir/nir_lower_mediump.c b/src/compiler/nir/nir_lower_mediump.c
index 2114007e719..ffbcec341a9 100644
--- a/src/compiler/nir/nir_lower_mediump.c
+++ b/src/compiler/nir/nir_lower_mediump.c
@@ -147,11 +147,7 @@ nir_recompute_io_bases(nir_shader *nir, nir_variable_mode modes)
       }
    }
 
-   if (changed) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
+   nir_progress(changed, impl, nir_metadata_control_flow);
 
    if (modes & nir_var_shader_in)
       nir->num_inputs = BITSET_COUNT(inputs);
@@ -285,13 +281,7 @@ nir_lower_mediump_io(nir_shader *nir, nir_variable_mode modes,
    if (changed && use_16bit_slots)
       nir_recompute_io_bases(nir, modes);
 
-   if (changed) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return changed;
+   return nir_progress(changed, impl, nir_metadata_control_flow);
 }
 
 /**
@@ -346,13 +336,7 @@ nir_force_mediump_io(nir_shader *nir, nir_variable_mode modes,
       }
    }
 
-   if (changed) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return changed;
+   return nir_progress(changed, impl, nir_metadata_control_flow);
 }
 
 /**
@@ -391,13 +375,7 @@ nir_unpack_16bit_varying_slots(nir_shader *nir, nir_variable_mode modes)
    if (changed)
       nir_recompute_io_bases(nir, modes);
 
-   if (changed) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return changed;
+   return nir_progress(changed, impl, nir_metadata_control_flow);
 }
 
 static bool
@@ -557,13 +535,7 @@ nir_lower_mediump_vars_impl(nir_function_impl *impl, nir_variable_mode modes,
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir_lower_memcpy.c b/src/compiler/nir/nir_lower_memcpy.c
index 9c4557faaea..59545467b2d 100644
--- a/src/compiler/nir/nir_lower_memcpy.c
+++ b/src/compiler/nir/nir_lower_memcpy.c
@@ -176,12 +176,8 @@ lower_memcpy_impl(nir_function_impl *impl)
    }
 
    if (found_non_const_memcpy) {
-      nir_metadata_preserve(impl, nir_metadata_none);
-   } else if (found_const_memcpy) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
+      nir_progress(true, impl, nir_metadata_none);
+   } else nir_progress(found_const_memcpy, impl, nir_metadata_control_flow);
 
    return found_const_memcpy || found_non_const_memcpy;
 }
diff --git a/src/compiler/nir/nir_lower_memory_model.c b/src/compiler/nir/nir_lower_memory_model.c
index c797eae8a4e..c0b38ab9140 100644
--- a/src/compiler/nir/nir_lower_memory_model.c
+++ b/src/compiler/nir/nir_lower_memory_model.c
@@ -240,12 +240,8 @@ nir_lower_memory_model(nir_shader *shader)
       modes = 0;
       foreach_list_typed_reverse(nir_cf_node, cf_node, node, cf_list)
          impl_progress |= lower_make_available(cf_node, &modes);
-
-      if (impl_progress)
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-      else
-         nir_metadata_preserve(impl, nir_metadata_all);
-      progress |= impl_progress;
+      progress = progress | nir_progress(impl_progress, impl,
+                                         nir_metadata_control_flow);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_lower_multiview.c b/src/compiler/nir/nir_lower_multiview.c
index 07c90f2fc23..7b5fcd478f4 100644
--- a/src/compiler/nir/nir_lower_multiview.c
+++ b/src/compiler/nir/nir_lower_multiview.c
@@ -326,6 +326,5 @@ nir_lower_multiview(nir_shader *shader, nir_lower_multiview_options options)
 
    _mesa_hash_table_destroy(out_derefs, NULL);
 
-   nir_metadata_preserve(entrypoint, nir_metadata_none);
-   return true;
+   return nir_progress(true, entrypoint, nir_metadata_none);
 }
diff --git a/src/compiler/nir/nir_lower_non_uniform_access.c b/src/compiler/nir/nir_lower_non_uniform_access.c
index 76180ed99df..7483eb6d12b 100644
--- a/src/compiler/nir/nir_lower_non_uniform_access.c
+++ b/src/compiler/nir/nir_lower_non_uniform_access.c
@@ -451,10 +451,7 @@ nir_lower_non_uniform_access_impl(nir_function_impl *impl,
 
    _mesa_hash_table_destroy(state.accesses, NULL);
 
-   if (progress)
-      nir_metadata_preserve(impl, nir_metadata_none);
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_none);
 }
 
 /**
diff --git a/src/compiler/nir/nir_lower_passthrough_edgeflags.c b/src/compiler/nir/nir_lower_passthrough_edgeflags.c
index 09347a10fe6..6909542a191 100644
--- a/src/compiler/nir/nir_lower_passthrough_edgeflags.c
+++ b/src/compiler/nir/nir_lower_passthrough_edgeflags.c
@@ -49,7 +49,7 @@ lower_impl(nir_function_impl *impl)
                     .base = shader->num_outputs++,
                     .io_semantics.location = VARYING_SLOT_EDGE);
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir_lower_patch_vertices.c b/src/compiler/nir/nir_lower_patch_vertices.c
index a9ee46ebfa4..72b83befd20 100644
--- a/src/compiler/nir/nir_lower_patch_vertices.c
+++ b/src/compiler/nir/nir_lower_patch_vertices.c
@@ -89,9 +89,7 @@ nir_lower_patch_vertices(nir_shader *nir,
          }
       }
 
-      if (progress) {
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-      }
+      nir_progress(progress, impl, nir_metadata_control_flow);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_lower_phis_to_scalar.c b/src/compiler/nir/nir_lower_phis_to_scalar.c
index e4245ea251b..47fadea5dfc 100644
--- a/src/compiler/nir/nir_lower_phis_to_scalar.c
+++ b/src/compiler/nir/nir_lower_phis_to_scalar.c
@@ -269,7 +269,7 @@ lower_phis_to_scalar_impl(nir_function_impl *impl, bool lower_all)
       progress = lower_phis_to_scalar_block(block, &state) || progress;
    }
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 
    nir_instr_free_list(&state.dead_instrs);
 
diff --git a/src/compiler/nir/nir_lower_pntc_ytransform.c b/src/compiler/nir/nir_lower_pntc_ytransform.c
index 7b641531b08..caf819e1787 100644
--- a/src/compiler/nir/nir_lower_pntc_ytransform.c
+++ b/src/compiler/nir/nir_lower_pntc_ytransform.c
@@ -132,7 +132,7 @@ nir_lower_pntc_ytransform(nir_shader *shader,
       nir_foreach_block(block, impl) {
          lower_pntc_ytransform_block(&state, block);
       }
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 
    return state.pntc_transform != NULL;
diff --git a/src/compiler/nir/nir_lower_point_size_mov.c b/src/compiler/nir/nir_lower_point_size_mov.c
index 952e17a7caa..e7139330345 100644
--- a/src/compiler/nir/nir_lower_point_size_mov.c
+++ b/src/compiler/nir/nir_lower_point_size_mov.c
@@ -86,7 +86,7 @@ nir_lower_point_size_mov(nir_shader *shader,
       lower_point_size_mov_after(&b, in);
       shader->info.outputs_written |= VARYING_BIT_PSIZ;
       progress = true;
-      nir_metadata_preserve(impl, preserved);
+      nir_progress(true, impl, preserved);
    }
    return progress;
 }
diff --git a/src/compiler/nir/nir_lower_reg_intrinsics_to_ssa.c b/src/compiler/nir/nir_lower_reg_intrinsics_to_ssa.c
index 36897f20c56..9ab9b96c74a 100644
--- a/src/compiler/nir/nir_lower_reg_intrinsics_to_ssa.c
+++ b/src/compiler/nir/nir_lower_reg_intrinsics_to_ssa.c
@@ -128,8 +128,7 @@ nir_lower_reg_intrinsics_to_ssa_impl(nir_function_impl *impl)
       }
    }
    if (!need_lower_reg) {
-      nir_metadata_preserve(impl, nir_metadata_all);
-      return false;
+      return nir_no_progress(impl);
    }
 
    nir_metadata_require(impl, nir_metadata_control_flow);
@@ -170,8 +169,7 @@ nir_lower_reg_intrinsics_to_ssa_impl(nir_function_impl *impl)
 
    ralloc_free(dead_ctx);
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
-   return true;
+   return nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir_lower_returns.c b/src/compiler/nir/nir_lower_returns.c
index d363d9a1774..7f511f7bba9 100644
--- a/src/compiler/nir/nir_lower_returns.c
+++ b/src/compiler/nir/nir_lower_returns.c
@@ -286,11 +286,11 @@ nir_lower_returns_impl(nir_function_impl *impl)
    progress = progress || state.removed_unreachable_code;
 
    if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_none);
+      nir_progress(true, impl, nir_metadata_none);
       nir_rematerialize_derefs_in_use_blocks_impl(impl);
       nir_repair_ssa_impl(impl);
    } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
+      nir_no_progress(impl);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_lower_scratch.c b/src/compiler/nir/nir_lower_scratch.c
index 3536e05d9c4..23583377f5b 100644
--- a/src/compiler/nir/nir_lower_scratch.c
+++ b/src/compiler/nir/nir_lower_scratch.c
@@ -219,12 +219,8 @@ nir_lower_vars_to_scratch(nir_shader *shader,
          }
       }
 
-      if (impl_progress) {
-         progress = true;
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      progress = progress | nir_progress(impl_progress, impl,
+                                         nir_metadata_control_flow);
    }
 
    _mesa_set_destroy(set, NULL);
diff --git a/src/compiler/nir/nir_lower_shader_calls.c b/src/compiler/nir/nir_lower_shader_calls.c
index 46d473cb2d0..c1caec4601a 100644
--- a/src/compiler/nir/nir_lower_shader_calls.c
+++ b/src/compiler/nir/nir_lower_shader_calls.c
@@ -57,13 +57,7 @@ move_system_values_to_top(nir_shader *shader)
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 static bool
@@ -894,7 +888,7 @@ duplicate_loop_bodies(nir_function_impl *impl, nir_instr *resume_instr)
    }
 
    if (resume_reg != NULL)
-      nir_metadata_preserve(impl, nir_metadata_none);
+      nir_progress(true, impl, nir_metadata_none);
 
    return resume_reg != NULL;
 }
@@ -1289,7 +1283,7 @@ lower_resume(nir_shader *shader, int call_idx)
 
    ralloc_free(mem_ctx);
 
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 
    nir_validate_shader(shader, "after flatten_resume_if_ladder in "
                                "nir_lower_shader_calls");
@@ -1589,10 +1583,8 @@ nir_opt_trim_stack_values(nir_shader *shader)
       }
    }
 
-   nir_metadata_preserve(impl,
-                         progress ? (nir_metadata_control_flow |
-                                     nir_metadata_loop_analysis)
-                                  : nir_metadata_all);
+   nir_progress(progress, impl,
+                nir_metadata_control_flow | nir_metadata_loop_analysis);
 
    _mesa_hash_table_u64_destroy(value_id_to_mask);
 
@@ -1834,10 +1826,8 @@ nir_opt_stack_loads(nir_shader *shader)
          }
       }
 
-      nir_metadata_preserve(impl,
-                            func_progress ? (nir_metadata_control_flow |
-                                             nir_metadata_loop_analysis)
-                                          : nir_metadata_all);
+      nir_progress(func_progress, impl,
+                   nir_metadata_control_flow | nir_metadata_loop_analysis);
 
       progress |= func_progress;
    }
diff --git a/src/compiler/nir/nir_lower_task_shader.c b/src/compiler/nir/nir_lower_task_shader.c
index 8765f25c4df..3854cf42598 100644
--- a/src/compiler/nir/nir_lower_task_shader.c
+++ b/src/compiler/nir/nir_lower_task_shader.c
@@ -143,9 +143,7 @@ nir_lower_nv_task_count(nir_shader *shader)
    nir_builder builder = nir_builder_create(impl);
 
    append_launch_mesh_workgroups_to_nv_task(&builder, &state);
-   nir_metadata_preserve(impl, nir_metadata_none);
-
-   return true;
+   return nir_progress(true, impl, nir_metadata_none);
 }
 
 static nir_intrinsic_op
@@ -446,7 +444,7 @@ nir_lower_task_shader(nir_shader *shader,
       nir_block *last_block = nir_impl_last_block(impl);
       builder.cursor = nir_after_block_before_jump(last_block);
       nir_launch_mesh_workgroups(&builder, nir_imm_zero(&builder, 3, 32));
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 
    bool atomics = options.payload_to_shared_for_atomics;
diff --git a/src/compiler/nir/nir_lower_terminate_to_demote.c b/src/compiler/nir/nir_lower_terminate_to_demote.c
index 03976bd3bd5..f7927eda78a 100644
--- a/src/compiler/nir/nir_lower_terminate_to_demote.c
+++ b/src/compiler/nir/nir_lower_terminate_to_demote.c
@@ -85,13 +85,7 @@ nir_lower_terminate_impl(nir_function_impl *impl)
    nir_builder b = nir_builder_create(impl);
    bool progress = nir_lower_terminate_cf_list(&b, &impl->body);
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_none);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_none);
 }
 
 /** Lowers nir_intrinsic_terminate to demote + halt
diff --git a/src/compiler/nir/nir_lower_tex.c b/src/compiler/nir/nir_lower_tex.c
index d8d67833565..fcc06f6f18f 100644
--- a/src/compiler/nir/nir_lower_tex.c
+++ b/src/compiler/nir/nir_lower_tex.c
@@ -1791,7 +1791,7 @@ nir_lower_tex_impl(nir_function_impl *impl,
       progress |= nir_lower_tex_block(block, &builder, options, compiler_options);
    }
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
    return progress;
 }
 
diff --git a/src/compiler/nir/nir_lower_texcoord_replace.c b/src/compiler/nir/nir_lower_texcoord_replace.c
index 5e98f6435e8..850138db575 100644
--- a/src/compiler/nir/nir_lower_texcoord_replace.c
+++ b/src/compiler/nir/nir_lower_texcoord_replace.c
@@ -124,7 +124,7 @@ nir_lower_texcoord_replace_impl(nir_function_impl *impl,
       }
    }
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir_lower_variable_initializers.c b/src/compiler/nir/nir_lower_variable_initializers.c
index 9ab4f53cdf1..ec3f3d1beef 100644
--- a/src/compiler/nir/nir_lower_variable_initializers.c
+++ b/src/compiler/nir/nir_lower_variable_initializers.c
@@ -120,13 +120,8 @@ nir_lower_variable_initializers(nir_shader *shader, nir_variable_mode modes)
                                                   nir_var_function_temp);
       }
 
-      if (impl_progress) {
-         progress = true;
-         nir_metadata_preserve(impl, nir_metadata_control_flow |
-                                        nir_metadata_live_defs);
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      progress = progress | nir_progress(impl_progress, impl,
+                                         nir_metadata_control_flow | nir_metadata_live_defs);
    }
 
    return progress;
@@ -201,9 +196,8 @@ nir_zero_initialize_shared_memory(nir_shader *shader,
    nir_barrier(&b, SCOPE_WORKGROUP, SCOPE_WORKGROUP, NIR_MEMORY_ACQ_REL,
                nir_var_mem_shared);
 
-   nir_metadata_preserve(nir_shader_get_entrypoint(shader), nir_metadata_none);
-
-   return true;
+   return nir_progress(true, nir_shader_get_entrypoint(shader),
+                       nir_metadata_none);
 }
 
 
@@ -297,7 +291,6 @@ nir_clear_shared_memory(nir_shader *shader,
       nir_builder_instr_insert(&b, &offset_phi->instr);
    }
 
-   nir_metadata_preserve(nir_shader_get_entrypoint(shader), nir_metadata_none);
-
-   return true;
+   return nir_progress(true, nir_shader_get_entrypoint(shader),
+                       nir_metadata_none);
 }
diff --git a/src/compiler/nir/nir_lower_vars_to_ssa.c b/src/compiler/nir/nir_lower_vars_to_ssa.c
index 2ff2a29ab0c..a6dbd3b51ce 100644
--- a/src/compiler/nir/nir_lower_vars_to_ssa.c
+++ b/src/compiler/nir/nir_lower_vars_to_ssa.c
@@ -833,8 +833,7 @@ nir_lower_vars_to_ssa_impl(nir_function_impl *impl)
    }
 
    if (!progress) {
-      nir_metadata_preserve(impl, nir_metadata_all);
-      return false;
+      return nir_no_progress(impl);
    }
 
    nir_metadata_require(impl, nir_metadata_dominance);
@@ -882,7 +881,7 @@ nir_lower_vars_to_ssa_impl(nir_function_impl *impl)
 
    nir_phi_builder_finish(state.phi_builder);
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 
    ralloc_free(state.dead_ctx);
 
diff --git a/src/compiler/nir/nir_metadata.c b/src/compiler/nir/nir_metadata.c
index 2ab2b00659f..fea93a377d0 100644
--- a/src/compiler/nir/nir_metadata.c
+++ b/src/compiler/nir/nir_metadata.c
@@ -89,7 +89,7 @@ void
 nir_shader_preserve_all_metadata(nir_shader *shader)
 {
    nir_foreach_function_impl(impl, shader) {
-      nir_metadata_preserve(impl, nir_metadata_all);
+      nir_no_progress(impl);
    }
 }
 
diff --git a/src/compiler/nir/nir_move_output_stores_to_end.c b/src/compiler/nir/nir_move_output_stores_to_end.c
index 29b34bfbcde..cd3943cb16d 100644
--- a/src/compiler/nir/nir_move_output_stores_to_end.c
+++ b/src/compiler/nir/nir_move_output_stores_to_end.c
@@ -92,7 +92,5 @@ nir_move_output_stores_to_end(nir_shader *nir)
       progress = true;
    }
 
-   nir_metadata_preserve(impl, progress ? nir_metadata_control_flow :
-                                          nir_metadata_all);
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
diff --git a/src/compiler/nir/nir_move_vec_src_uses_to_dest.c b/src/compiler/nir/nir_move_vec_src_uses_to_dest.c
index c85aa19fc2a..d10e6e28ba1 100644
--- a/src/compiler/nir/nir_move_vec_src_uses_to_dest.c
+++ b/src/compiler/nir/nir_move_vec_src_uses_to_dest.c
@@ -187,7 +187,7 @@ nir_move_vec_src_uses_to_dest_impl(nir_shader *shader, nir_function_impl *impl,
       progress |= move_vec_src_uses_to_dest_block(block, skip_const_srcs);
    }
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 
    return progress;
 }
diff --git a/src/compiler/nir/nir_opt_access.c b/src/compiler/nir/nir_opt_access.c
index 01aacec14be..a33816472c9 100644
--- a/src/compiler/nir/nir_opt_access.c
+++ b/src/compiler/nir/nir_opt_access.c
@@ -277,14 +277,8 @@ opt_access_impl(struct access_state *state,
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl,
-                            nir_metadata_control_flow |
-                            nir_metadata_live_defs |
-                            nir_metadata_loop_analysis);
-   }
-
-   return progress;
+   return nir_progress(progress, impl,
+                       nir_metadata_control_flow | nir_metadata_live_defs | nir_metadata_loop_analysis);
 }
 
 bool
@@ -323,12 +317,8 @@ nir_opt_access(nir_shader *shader, const nir_opt_access_options *options)
       progress |= opt_access_impl(&state, impl);
 
       /* If we make a change to the uniforms, update all the impls. */
-      if (var_progress) {
-         nir_metadata_preserve(impl,
-                               nir_metadata_control_flow |
-                               nir_metadata_live_defs |
-                               nir_metadata_loop_analysis);
-      }
+      nir_progress(var_progress, impl,
+                   nir_metadata_control_flow | nir_metadata_live_defs | nir_metadata_loop_analysis);
    }
 
    progress |= var_progress;
diff --git a/src/compiler/nir/nir_opt_barriers.c b/src/compiler/nir/nir_opt_barriers.c
index 25f228e11ea..353c33e8afc 100644
--- a/src/compiler/nir/nir_opt_barriers.c
+++ b/src/compiler/nir/nir_opt_barriers.c
@@ -70,14 +70,8 @@ nir_opt_combine_barriers_impl(nir_function_impl *impl,
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow |
-                                     nir_metadata_live_defs);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl,
+                       nir_metadata_control_flow | nir_metadata_live_defs);
 }
 
 /* Combine adjacent scoped barriers. */
@@ -234,13 +228,9 @@ nir_opt_barrier_modes(nir_shader *shader)
       nir_metadata_require(impl, nir_metadata_dominance |
                                  nir_metadata_instr_index);
 
-      if (nir_opt_barrier_modes_impl(impl)) {
-         nir_metadata_preserve(impl, nir_metadata_control_flow |
-                                     nir_metadata_live_defs);
-         progress = true;
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      bool impl_progress = nir_opt_barrier_modes_impl(impl);
+      progress = progress | nir_progress(impl_progress, impl,
+                                         nir_metadata_control_flow | nir_metadata_live_defs);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_opt_call.c b/src/compiler/nir/nir_opt_call.c
index d1f7822fefd..4a8a4f389e7 100644
--- a/src/compiler/nir/nir_opt_call.c
+++ b/src/compiler/nir/nir_opt_call.c
@@ -245,8 +245,7 @@ nir_minimize_call_live_states_impl(nir_function_impl *impl)
 
    ralloc_free(mem_ctx);
 
-   nir_metadata_preserve(impl, nir_metadata_block_index |
-                                  nir_metadata_dominance);
+   nir_progress(true, impl, nir_metadata_block_index | nir_metadata_dominance);
    return progress;
 }
 
diff --git a/src/compiler/nir/nir_opt_combine_stores.c b/src/compiler/nir/nir_opt_combine_stores.c
index a5acaae5c31..dcb88156a5a 100644
--- a/src/compiler/nir/nir_opt_combine_stores.c
+++ b/src/compiler/nir/nir_opt_combine_stores.c
@@ -401,11 +401,8 @@ combine_stores_impl(struct combine_stores_state *state, nir_function_impl *impl)
    nir_foreach_block(block, impl)
       combine_stores_block(state, block);
 
-   if (state->progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
+   bool impl_progress = state->progress;
+   nir_progress(impl_progress, impl, nir_metadata_control_flow);
 
    return state->progress;
 }
diff --git a/src/compiler/nir/nir_opt_comparison_pre.c b/src/compiler/nir/nir_opt_comparison_pre.c
index e8b5b0c7914..dbaeac8a1a1 100644
--- a/src/compiler/nir/nir_opt_comparison_pre.c
+++ b/src/compiler/nir/nir_opt_comparison_pre.c
@@ -384,13 +384,7 @@ nir_opt_comparison_pre_impl(nir_function_impl *impl)
 
    block_queue_finish(&bq);
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir_opt_copy_prop_vars.c b/src/compiler/nir/nir_opt_copy_prop_vars.c
index 6d86f8598d1..f5117328ea0 100644
--- a/src/compiler/nir/nir_opt_copy_prop_vars.c
+++ b/src/compiler/nir/nir_opt_copy_prop_vars.c
@@ -1510,11 +1510,8 @@ nir_copy_prop_vars_impl(nir_function_impl *impl)
 
    copy_prop_vars_cf_node(&state, NULL, &impl->cf_node);
 
-   if (state.progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
+   bool impl_progress = state.progress;
+   nir_progress(impl_progress, impl, nir_metadata_control_flow);
 
    ralloc_free(mem_ctx);
    return state.progress;
diff --git a/src/compiler/nir/nir_opt_copy_propagate.c b/src/compiler/nir/nir_opt_copy_propagate.c
index c1725d2287d..be76b3287ae 100644
--- a/src/compiler/nir/nir_opt_copy_propagate.c
+++ b/src/compiler/nir/nir_opt_copy_propagate.c
@@ -157,13 +157,7 @@ nir_copy_prop_impl(nir_function_impl *impl)
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir_opt_cse.c b/src/compiler/nir/nir_opt_cse.c
index e7271eb6b12..01c02640f8e 100644
--- a/src/compiler/nir/nir_opt_cse.c
+++ b/src/compiler/nir/nir_opt_cse.c
@@ -53,11 +53,7 @@ nir_opt_cse_impl(nir_function_impl *impl)
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
+   nir_progress(progress, impl, nir_metadata_control_flow);
 
    nir_instr_set_destroy(instr_set);
    return progress;
diff --git a/src/compiler/nir/nir_opt_dce.c b/src/compiler/nir/nir_opt_dce.c
index ab2642b29fd..ec47a01658c 100644
--- a/src/compiler/nir/nir_opt_dce.c
+++ b/src/compiler/nir/nir_opt_dce.c
@@ -237,13 +237,7 @@ nir_opt_dce_impl(nir_function_impl *impl)
 
    nir_instr_free_list(&dead_instrs);
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir_opt_dead_cf.c b/src/compiler/nir/nir_opt_dead_cf.c
index 592491fec05..b5cf43b7c08 100644
--- a/src/compiler/nir/nir_opt_dead_cf.c
+++ b/src/compiler/nir/nir_opt_dead_cf.c
@@ -388,7 +388,7 @@ opt_dead_cf_impl(nir_function_impl *impl)
    bool progress = dead_cf_list(&impl->body, &dummy);
 
    if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_none);
+      nir_progress(true, impl, nir_metadata_none);
       nir_rematerialize_derefs_in_use_blocks_impl(impl);
 
       /* The CF manipulation code called by this pass is smart enough to keep
@@ -402,7 +402,7 @@ opt_dead_cf_impl(nir_function_impl *impl)
        */
       nir_repair_ssa_impl(impl);
    } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
+      nir_no_progress(impl);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_opt_dead_write_vars.c b/src/compiler/nir/nir_opt_dead_write_vars.c
index d86485c6eb5..0eac227850f 100644
--- a/src/compiler/nir/nir_opt_dead_write_vars.c
+++ b/src/compiler/nir/nir_opt_dead_write_vars.c
@@ -267,13 +267,7 @@ remove_dead_write_vars_impl(void *mem_ctx, nir_shader *shader, nir_function_impl
    nir_foreach_block(block, impl)
       progress |= remove_dead_write_vars_local(mem_ctx, shader, block);
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir_opt_find_array_copies.c b/src/compiler/nir/nir_opt_find_array_copies.c
index 42e87c9a557..ec541e2ec39 100644
--- a/src/compiler/nir/nir_opt_find_array_copies.c
+++ b/src/compiler/nir/nir_opt_find_array_copies.c
@@ -651,9 +651,9 @@ opt_find_array_copies_impl(nir_function_impl *impl)
    ralloc_free(s.dead_ctx);
 
    if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    } else {
-      nir_metadata_preserve(impl, nir_metadata_all & ~nir_metadata_instr_index);
+      nir_progress(true, impl, nir_metadata_all & ~nir_metadata_instr_index);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_opt_fragdepth.c b/src/compiler/nir/nir_opt_fragdepth.c
index 4c8e3ff8cce..2c29501d614 100644
--- a/src/compiler/nir/nir_opt_fragdepth.c
+++ b/src/compiler/nir/nir_opt_fragdepth.c
@@ -111,10 +111,8 @@ nir_opt_fragdepth(nir_shader *shader)
        */
       nir_instr_remove(&store_intrin->instr);
 
-      nir_metadata_preserve(impl, nir_metadata_control_flow |
-                                     nir_metadata_loop_analysis |
-                                     nir_metadata_instr_index);
-      progress = true;
+      progress = nir_progress(true, impl,
+                              nir_metadata_control_flow | nir_metadata_loop_analysis | nir_metadata_instr_index);
    }
 
 end:
diff --git a/src/compiler/nir/nir_opt_gcm.c b/src/compiler/nir/nir_opt_gcm.c
index 9d424b2faa2..cb1de480b56 100644
--- a/src/compiler/nir/nir_opt_gcm.c
+++ b/src/compiler/nir/nir_opt_gcm.c
@@ -858,10 +858,10 @@ opt_gcm_impl(nir_shader *shader, nir_function_impl *impl, bool value_number)
    ralloc_free(state.instr_infos);
 
    if (state.progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    } else {
-      nir_metadata_preserve(impl, nir_metadata_control_flow |
-                                     nir_metadata_loop_analysis);
+      nir_progress(true, impl,
+                   nir_metadata_control_flow | nir_metadata_loop_analysis);
    }
 
    return state.progress;
diff --git a/src/compiler/nir/nir_opt_if.c b/src/compiler/nir/nir_opt_if.c
index 0cfb4911341..aeed27bc999 100644
--- a/src/compiler/nir/nir_opt_if.c
+++ b/src/compiler/nir/nir_opt_if.c
@@ -1444,7 +1444,7 @@ nir_opt_if(nir_shader *shader, nir_opt_if_options options)
 
       nir_metadata_require(impl, nir_metadata_control_flow);
       progress = opt_if_safe_cf_list(&b, &impl->body, options);
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
 
       bool preserve = true;
 
@@ -1464,11 +1464,7 @@ nir_opt_if(nir_shader *shader, nir_opt_if_options options)
          nir_lower_reg_intrinsics_to_ssa_impl(impl);
       }
 
-      if (preserve) {
-         nir_metadata_preserve(impl, nir_metadata_none);
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      nir_progress(preserve, impl, nir_metadata_none);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_opt_intrinsics.c b/src/compiler/nir/nir_opt_intrinsics.c
index 441e498d287..4e4820fada5 100644
--- a/src/compiler/nir/nir_opt_intrinsics.c
+++ b/src/compiler/nir/nir_opt_intrinsics.c
@@ -428,12 +428,9 @@ nir_opt_intrinsics(nir_shader *shader)
    bool progress = false;
 
    nir_foreach_function_impl(impl, shader) {
-      if (opt_intrinsics_impl(impl, shader->options)) {
-         progress = true;
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      bool impl_progress = opt_intrinsics_impl(impl, shader->options);
+      progress = progress | nir_progress(impl_progress, impl,
+                                         nir_metadata_control_flow);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_opt_large_constants.c b/src/compiler/nir/nir_opt_large_constants.c
index 9ec18888017..fb4346ce506 100644
--- a/src/compiler/nir/nir_opt_large_constants.c
+++ b/src/compiler/nir/nir_opt_large_constants.c
@@ -591,6 +591,5 @@ nir_opt_large_constants(nir_shader *shader,
 
    ralloc_free(var_infos);
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
-   return true;
+   return nir_progress(true, impl, nir_metadata_control_flow);
 }
diff --git a/src/compiler/nir/nir_opt_licm.c b/src/compiler/nir/nir_opt_licm.c
index cf4c729dcdb..41f3e743d80 100644
--- a/src/compiler/nir/nir_opt_licm.c
+++ b/src/compiler/nir/nir_opt_licm.c
@@ -131,13 +131,9 @@ nir_opt_licm(nir_shader *shader)
       nir_metadata_require(impl, nir_metadata_block_index |
                                     nir_metadata_dominance);
 
-      if (visit_cf_list(&impl->body, NULL, NULL)) {
-         progress = true;
-         nir_metadata_preserve(impl, nir_metadata_block_index |
-                                        nir_metadata_dominance);
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      bool impl_progress = visit_cf_list(&impl->body, NULL, NULL);
+      progress = progress | nir_progress(impl_progress, impl,
+                                         nir_metadata_block_index | nir_metadata_dominance);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_opt_load_store_vectorize.c b/src/compiler/nir/nir_opt_load_store_vectorize.c
index 3b8d09cb544..b11931a3983 100644
--- a/src/compiler/nir/nir_opt_load_store_vectorize.c
+++ b/src/compiler/nir/nir_opt_load_store_vectorize.c
@@ -1625,9 +1625,8 @@ nir_opt_load_store_vectorize(nir_shader *shader, const nir_load_store_vectorize_
       nir_foreach_block(block, impl)
          progress |= process_block(impl, ctx, block);
 
-      nir_metadata_preserve(impl,
-                            nir_metadata_control_flow |
-                            nir_metadata_live_defs);
+      nir_progress(true, impl,
+                   nir_metadata_control_flow | nir_metadata_live_defs);
    }
 
    ralloc_free(ctx);
diff --git a/src/compiler/nir/nir_opt_loop.c b/src/compiler/nir/nir_opt_loop.c
index 9f8c1a11941..e39457043ca 100644
--- a/src/compiler/nir/nir_opt_loop.c
+++ b/src/compiler/nir/nir_opt_loop.c
@@ -720,13 +720,13 @@ nir_opt_loop(nir_shader *shader)
 
       /* First we run the simple pass to get rid of pesky continues */
       if (opt_loop_cf_list(&b, &impl->body, NULL)) {
-         nir_metadata_preserve(impl, nir_metadata_none);
+         nir_progress(true, impl, nir_metadata_none);
 
          /* If that made progress, we're no longer really in SSA form. */
          nir_lower_reg_intrinsics_to_ssa_impl(impl);
          progress = true;
       } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
+         nir_no_progress(impl);
       }
    }
 
diff --git a/src/compiler/nir/nir_opt_loop_unroll.c b/src/compiler/nir/nir_opt_loop_unroll.c
index 7d56be193d9..e93bce54b45 100644
--- a/src/compiler/nir/nir_opt_loop_unroll.c
+++ b/src/compiler/nir/nir_opt_loop_unroll.c
@@ -1170,10 +1170,10 @@ nir_opt_loop_unroll_impl(nir_function_impl *impl,
                                       &has_nested_loop);
 
    if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_none);
+      nir_progress(true, impl, nir_metadata_none);
       nir_lower_reg_intrinsics_to_ssa_impl(impl);
    } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
+      nir_no_progress(impl);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_opt_memcpy.c b/src/compiler/nir/nir_opt_memcpy.c
index 3234fc794b2..ba388f655c3 100644
--- a/src/compiler/nir/nir_opt_memcpy.c
+++ b/src/compiler/nir/nir_opt_memcpy.c
@@ -274,13 +274,7 @@ opt_memcpy_impl(nir_function_impl *impl)
 
    _mesa_set_destroy(complex_vars, NULL);
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir_opt_move.c b/src/compiler/nir/nir_opt_move.c
index 4201edbf6d1..db984518668 100644
--- a/src/compiler/nir/nir_opt_move.c
+++ b/src/compiler/nir/nir_opt_move.c
@@ -145,11 +145,11 @@ nir_opt_move(nir_shader *shader, nir_move_options options)
       }
 
       if (impl_progress) {
-         nir_metadata_preserve(impl, nir_metadata_control_flow |
-                                        nir_metadata_live_defs);
-         progress = true;
+         progress = nir_progress(true, impl,
+                                 nir_metadata_control_flow | nir_metadata_live_defs);
       } else {
-         nir_metadata_preserve(impl, nir_metadata_all & ~nir_metadata_instr_index);
+         nir_progress(true, impl,
+                      nir_metadata_all & ~nir_metadata_instr_index);
       }
    }
 
diff --git a/src/compiler/nir/nir_opt_move_discards_to_top.c b/src/compiler/nir/nir_opt_move_discards_to_top.c
index 5f9f8e7ea5a..a93a40c3c1e 100644
--- a/src/compiler/nir/nir_opt_move_discards_to_top.c
+++ b/src/compiler/nir/nir_opt_move_discards_to_top.c
@@ -360,8 +360,7 @@ nir_opt_move_discards_to_top(nir_shader *shader)
 
    nir_foreach_function_impl(impl, shader) {
       if (opt_move_discards_to_top_impl(impl)) {
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-         progress = true;
+         progress = nir_progress(true, impl, nir_metadata_control_flow);
       }
    }
 
diff --git a/src/compiler/nir/nir_opt_mqsad.c b/src/compiler/nir/nir_opt_mqsad.c
index e38d3c55311..76ef5325ee6 100644
--- a/src/compiler/nir/nir_opt_mqsad.c
+++ b/src/compiler/nir/nir_opt_mqsad.c
@@ -135,10 +135,9 @@ nir_opt_mqsad(nir_shader *shader)
       }
 
       if (progress_impl) {
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-         progress = true;
+         progress = nir_progress(true, impl, nir_metadata_control_flow);
       } else {
-         nir_metadata_preserve(impl, nir_metadata_block_index);
+         nir_progress(true, impl, nir_metadata_block_index);
       }
    }
 
diff --git a/src/compiler/nir/nir_opt_peephole_select.c b/src/compiler/nir/nir_opt_peephole_select.c
index 3735cd29caa..0f2727faa11 100644
--- a/src/compiler/nir/nir_opt_peephole_select.c
+++ b/src/compiler/nir/nir_opt_peephole_select.c
@@ -566,13 +566,7 @@ nir_opt_peephole_select_impl(nir_function_impl *impl,
       progress |= nir_opt_peephole_select_block(block, shader, options);
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_none);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_none);
 }
 
 bool
diff --git a/src/compiler/nir/nir_opt_preamble.c b/src/compiler/nir/nir_opt_preamble.c
index a8134f92b92..a6a3e3c9bd1 100644
--- a/src/compiler/nir/nir_opt_preamble.c
+++ b/src/compiler/nir/nir_opt_preamble.c
@@ -962,8 +962,7 @@ nir_opt_preamble(nir_shader *shader, const nir_opt_preamble_options *options,
       }
    }
 
-   nir_metadata_preserve(impl,
-                         nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 
    ralloc_free(remap_table);
    free(ctx.states);
diff --git a/src/compiler/nir/nir_opt_ray_queries.c b/src/compiler/nir/nir_opt_ray_queries.c
index 8e77a4d2b24..aab10b2acd3 100644
--- a/src/compiler/nir/nir_opt_ray_queries.c
+++ b/src/compiler/nir/nir_opt_ray_queries.c
@@ -233,8 +233,7 @@ nir_opt_ray_query_ranges(nir_shader *shader)
    }
 
    if (ray_query_count <= 1) {
-      nir_metadata_preserve(func->impl, nir_metadata_all);
-      return false;
+      return nir_no_progress(func->impl);
    }
 
    void *mem_ctx = ralloc_context(NULL);
@@ -406,7 +405,7 @@ nir_opt_ray_query_ranges(nir_shader *shader)
       }
    }
 
-   nir_metadata_preserve(func->impl, nir_metadata_all);
+   nir_no_progress(func->impl);
 
    /* Remove dead ray queries. */
    if (progress) {
diff --git a/src/compiler/nir/nir_opt_rematerialize_compares.c b/src/compiler/nir/nir_opt_rematerialize_compares.c
index baf4423dc0f..346795fdc78 100644
--- a/src/compiler/nir/nir_opt_rematerialize_compares.c
+++ b/src/compiler/nir/nir_opt_rematerialize_compares.c
@@ -202,13 +202,7 @@ nir_opt_rematerialize_compares_impl(nir_shader *shader, nir_function_impl *impl)
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 static bool
@@ -301,13 +295,7 @@ nir_opt_rematerialize_alu_impl(nir_shader *shader, nir_function_impl *impl)
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/compiler/nir/nir_opt_shrink_stores.c b/src/compiler/nir/nir_opt_shrink_stores.c
index 027834e1f92..7fbea167b60 100644
--- a/src/compiler/nir/nir_opt_shrink_stores.c
+++ b/src/compiler/nir/nir_opt_shrink_stores.c
@@ -111,12 +111,7 @@ nir_opt_shrink_stores(nir_shader *shader, bool shrink_image_store)
          }
       }
 
-      if (progress) {
-         nir_metadata_preserve(impl,
-                               nir_metadata_control_flow);
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      nir_progress(progress, impl, nir_metadata_control_flow);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_opt_shrink_vectors.c b/src/compiler/nir/nir_opt_shrink_vectors.c
index 5311e29f8af..651fe0b81ab 100644
--- a/src/compiler/nir/nir_opt_shrink_vectors.c
+++ b/src/compiler/nir/nir_opt_shrink_vectors.c
@@ -578,12 +578,7 @@ nir_opt_shrink_vectors(nir_shader *shader, bool shrink_start)
          }
       }
 
-      if (progress) {
-         nir_metadata_preserve(impl,
-                               nir_metadata_control_flow);
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      nir_progress(progress, impl, nir_metadata_control_flow);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_opt_sink.c b/src/compiler/nir/nir_opt_sink.c
index 046cb9f0cc5..8d5d6d61c78 100644
--- a/src/compiler/nir/nir_opt_sink.c
+++ b/src/compiler/nir/nir_opt_sink.c
@@ -261,8 +261,7 @@ nir_opt_sink(nir_shader *shader, nir_move_options options)
          }
       }
 
-      nir_metadata_preserve(impl,
-                            nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_opt_uniform_atomics.c b/src/compiler/nir/nir_opt_uniform_atomics.c
index e06f5e7d553..eb3425a3a15 100644
--- a/src/compiler/nir/nir_opt_uniform_atomics.c
+++ b/src/compiler/nir/nir_opt_uniform_atomics.c
@@ -333,12 +333,9 @@ nir_opt_uniform_atomics(nir_shader *shader, bool fs_atomics_predicated)
    nir_foreach_function_impl(impl, shader) {
       nir_metadata_require(impl, nir_metadata_block_index | nir_metadata_divergence);
 
-      if (opt_uniform_atomics(impl, fs_atomics_predicated)) {
-         progress = true;
-         nir_metadata_preserve(impl, nir_metadata_none);
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      bool impl_progress = opt_uniform_atomics(impl, fs_atomics_predicated);
+      progress = progress | nir_progress(impl_progress, impl,
+                                         nir_metadata_none);
    }
 
    return progress;
diff --git a/src/compiler/nir/nir_opt_varyings.c b/src/compiler/nir/nir_opt_varyings.c
index c6ba2d95184..095b9f92541 100644
--- a/src/compiler/nir/nir_opt_varyings.c
+++ b/src/compiler/nir/nir_opt_varyings.c
@@ -5297,14 +5297,10 @@ nir_opt_varyings(nir_shader *producer, nir_shader *consumer, bool spirv,
    /* Part 4: Do compaction. */
    compact_varyings(linkage, &progress);
 
-   nir_metadata_preserve(linkage->producer_builder.impl,
-                         progress & nir_progress_producer ?
-                            (nir_metadata_control_flow) :
-                            nir_metadata_all);
-   nir_metadata_preserve(linkage->consumer_builder.impl,
-                         progress & nir_progress_consumer ?
-                            (nir_metadata_control_flow) :
-                            nir_metadata_all);
+   nir_progress(true, linkage->producer_builder.impl,
+                progress & nir_progress_producer ? (nir_metadata_control_flow) : nir_metadata_all);
+   nir_progress(true, linkage->consumer_builder.impl,
+                progress & nir_progress_consumer ? (nir_metadata_control_flow) : nir_metadata_all);
    free_linkage(linkage);
    FREE(linkage);
 
diff --git a/src/compiler/nir/nir_opt_vectorize.c b/src/compiler/nir/nir_opt_vectorize.c
index e40858b8f07..39789a7c0f2 100644
--- a/src/compiler/nir/nir_opt_vectorize.c
+++ b/src/compiler/nir/nir_opt_vectorize.c
@@ -596,11 +596,7 @@ nir_opt_vectorize_impl(nir_function_impl *impl,
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
+   nir_progress(progress, impl, nir_metadata_control_flow);
 
    vec_instr_set_destroy(instr_set);
    return progress;
diff --git a/src/compiler/nir/nir_opt_vectorize_io.c b/src/compiler/nir/nir_opt_vectorize_io.c
index 04cd236f840..22352199912 100644
--- a/src/compiler/nir/nir_opt_vectorize_io.c
+++ b/src/compiler/nir/nir_opt_vectorize_io.c
@@ -575,9 +575,8 @@ nir_opt_vectorize_io(nir_shader *shader, nir_variable_mode modes)
          progress |= vectorize_batch(&io_instructions);
       }
 
-      nir_metadata_preserve(impl, progress ? (nir_metadata_block_index |
-                                              nir_metadata_dominance) :
-                                             nir_metadata_all);
+      nir_progress(progress, impl,
+                   nir_metadata_block_index | nir_metadata_dominance);
       global_progress |= progress;
    }
    util_dynarray_fini(&io_instructions);
diff --git a/src/compiler/nir/nir_propagate_invariant.c b/src/compiler/nir/nir_propagate_invariant.c
index abf9e5fb664..8bc479424b8 100644
--- a/src/compiler/nir/nir_propagate_invariant.c
+++ b/src/compiler/nir/nir_propagate_invariant.c
@@ -171,14 +171,8 @@ propagate_invariant_impl(nir_function_impl *impl, struct set *invariants)
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow |
-                                     nir_metadata_live_defs);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl,
+                       nir_metadata_control_flow | nir_metadata_live_defs);
 }
 
 /* If invariant_prim=true, this pass considers all geometry-affecting
diff --git a/src/compiler/nir/nir_repair_ssa.c b/src/compiler/nir/nir_repair_ssa.c
index 2cb68f8a9b1..811fb69b61b 100644
--- a/src/compiler/nir/nir_repair_ssa.c
+++ b/src/compiler/nir/nir_repair_ssa.c
@@ -160,7 +160,7 @@ nir_repair_ssa_impl(nir_function_impl *impl)
    }
 
    if (state.progress)
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
 
    if (state.phi_builder) {
       nir_phi_builder_finish(state.phi_builder);
diff --git a/src/compiler/nir/nir_search.c b/src/compiler/nir/nir_search.c
index 619d75b7376..e0157923092 100644
--- a/src/compiler/nir/nir_search.c
+++ b/src/compiler/nir/nir_search.c
@@ -899,8 +899,7 @@ nir_algebraic_impl(nir_function_impl *impl,
     */
    struct util_dynarray states = { 0 };
    if (!util_dynarray_resize(&states, uint16_t, impl->ssa_alloc)) {
-      nir_metadata_preserve(impl, nir_metadata_all);
-      return false;
+      return nir_no_progress(impl);
    }
    memset(states.data, 0, states.size);
 
@@ -950,11 +949,5 @@ nir_algebraic_impl(nir_function_impl *impl,
    ralloc_free(range_ht);
    util_dynarray_fini(&states);
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
diff --git a/src/compiler/nir/nir_split_vars.c b/src/compiler/nir/nir_split_vars.c
index b84656db914..276441c857b 100644
--- a/src/compiler/nir/nir_split_vars.c
+++ b/src/compiler/nir/nir_split_vars.c
@@ -380,10 +380,9 @@ nir_split_struct_vars(nir_shader *shader, nir_variable_mode modes)
          split_struct_derefs_impl(impl, var_field_map,
                                   modes, mem_ctx);
 
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-         progress = true;
+         progress = nir_progress(true, impl, nir_metadata_control_flow);
       } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
+         nir_no_progress(impl);
       }
    }
 
@@ -971,10 +970,9 @@ nir_split_array_vars(nir_shader *shader, nir_variable_mode modes)
          split_array_copies_impl(impl, var_info_map, modes, mem_ctx);
          split_array_access_impl(impl, var_info_map, modes, mem_ctx);
 
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-         progress = true;
+         progress = nir_progress(true, impl, nir_metadata_control_flow);
       } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
+         nir_no_progress(impl);
       }
    }
 
@@ -1730,10 +1728,9 @@ nir_shrink_vec_array_vars(nir_shader *shader, nir_variable_mode modes)
       if (globals_shrunk || locals_shrunk) {
          shrink_vec_var_access_impl(impl, var_usage_map, modes);
 
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-         progress = true;
+         progress = nir_progress(true, impl, nir_metadata_control_flow);
       } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
+         nir_no_progress(impl);
       }
    }
 
diff --git a/src/compiler/nir/nir_sweep.c b/src/compiler/nir/nir_sweep.c
index 6b5da2d1c65..55995f10ad0 100644
--- a/src/compiler/nir/nir_sweep.c
+++ b/src/compiler/nir/nir_sweep.c
@@ -125,7 +125,7 @@ sweep_impl(nir_shader *nir, nir_function_impl *impl)
    sweep_block(nir, impl->end_block);
 
    /* Wipe out all the metadata, if any. */
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 }
 
 static void
diff --git a/src/compiler/nir/nir_to_lcssa.c b/src/compiler/nir/nir_to_lcssa.c
index 6b303c9c485..919febcce86 100644
--- a/src/compiler/nir/nir_to_lcssa.c
+++ b/src/compiler/nir/nir_to_lcssa.c
@@ -406,12 +406,9 @@ nir_convert_to_lcssa(nir_shader *shader, bool skip_invariants, bool skip_bool_in
       foreach_list_typed(nir_cf_node, node, node, &impl->body)
          convert_to_lcssa(node, state);
 
-      if (state->progress) {
-         progress = true;
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      bool impl_progress = state->progress;
+      progress = progress | nir_progress(impl_progress, impl,
+                                         nir_metadata_control_flow);
    }
 
    ralloc_free(state);
diff --git a/src/compiler/nir/nir_trivialize_registers.c b/src/compiler/nir/nir_trivialize_registers.c
index dd0e59a42a8..27c93da1f75 100644
--- a/src/compiler/nir/nir_trivialize_registers.c
+++ b/src/compiler/nir/nir_trivialize_registers.c
@@ -507,7 +507,7 @@ nir_trivialize_registers(nir_shader *s)
          trivialize_stores(impl, block);
       }
 
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 
    return true;
diff --git a/src/compiler/nir/nir_use_dominance.c b/src/compiler/nir/nir_use_dominance.c
index d0645772c46..540846f903e 100644
--- a/src/compiler/nir/nir_use_dominance.c
+++ b/src/compiler/nir/nir_use_dominance.c
@@ -288,7 +288,7 @@ nir_calc_use_dominance_impl(nir_function_impl *impl, bool post_dominance)
       }
    }
 
-   nir_metadata_preserve(impl, nir_metadata_all & ~nir_metadata_instr_index);
+   nir_progress(true, impl, nir_metadata_all & ~nir_metadata_instr_index);
 
    return state;
 }
diff --git a/src/freedreno/ir3/ir3_nir_analyze_ubo_ranges.c b/src/freedreno/ir3/ir3_nir_analyze_ubo_ranges.c
index aa9812606b1..bc03e976c3f 100644
--- a/src/freedreno/ir3/ir3_nir_analyze_ubo_ranges.c
+++ b/src/freedreno/ir3/ir3_nir_analyze_ubo_ranges.c
@@ -591,8 +591,7 @@ ir3_nir_lower_const_global_loads(nir_shader *nir, struct ir3_shader_variant *v)
       nir_foreach_function (function, nir) {
          if (function->impl) {
             if (function->is_preamble) {
-               nir_metadata_preserve(
-                  function->impl, nir_metadata_all);
+               nir_no_progress(function->impl);
                continue;
             }
 
@@ -607,8 +606,7 @@ ir3_nir_lower_const_global_loads(nir_shader *nir, struct ir3_shader_variant *v)
                }
             }
 
-            nir_metadata_preserve(
-               function->impl, nir_metadata_control_flow);
+            nir_progress(true, function->impl, nir_metadata_control_flow);
          }
       }
    }
@@ -697,7 +695,7 @@ ir3_nir_lower_ubo_loads(nir_shader *nir, struct ir3_shader_variant *v)
       if (function->impl) {
          if (function->is_preamble && push_ubos) {
             has_preamble = true;
-            nir_metadata_preserve(function->impl, nir_metadata_all);
+            nir_no_progress(function->impl);
             continue;
          }
          nir_builder builder = nir_builder_create(function->impl);
@@ -711,8 +709,7 @@ ir3_nir_lower_ubo_loads(nir_shader *nir, struct ir3_shader_variant *v)
             }
          }
 
-         nir_metadata_preserve(
-            function->impl, nir_metadata_control_flow);
+         nir_progress(true, function->impl, nir_metadata_control_flow);
       }
    }
    /* Update the num_ubos field for GL (first_ubo_is_default_ubo).  With
diff --git a/src/freedreno/ir3/ir3_nir_lower_64b.c b/src/freedreno/ir3/ir3_nir_lower_64b.c
index a9171c1d4e0..04dcd58cc80 100644
--- a/src/freedreno/ir3/ir3_nir_lower_64b.c
+++ b/src/freedreno/ir3/ir3_nir_lower_64b.c
@@ -383,9 +383,7 @@ ir3_nir_lower_64b_regs(nir_shader *shader)
       }
 
       if (impl_progress) {
-         nir_metadata_preserve(
-            impl, nir_metadata_control_flow);
-         progress = true;
+         progress = nir_progress(true, impl, nir_metadata_control_flow);
       }
    }
 
diff --git a/src/freedreno/ir3/ir3_nir_lower_io_offsets.c b/src/freedreno/ir3/ir3_nir_lower_io_offsets.c
index 72a9337f059..a93e8ec678c 100644
--- a/src/freedreno/ir3/ir3_nir_lower_io_offsets.c
+++ b/src/freedreno/ir3/ir3_nir_lower_io_offsets.c
@@ -326,12 +326,7 @@ lower_io_offsets_func(nir_function_impl *impl)
       progress |= lower_io_offsets_block(block, &b, mem_ctx);
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl,
-                            nir_metadata_control_flow);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/freedreno/ir3/ir3_nir_lower_push_consts_to_preamble.c b/src/freedreno/ir3/ir3_nir_lower_push_consts_to_preamble.c
index e1fdc7dae86..008949ac166 100644
--- a/src/freedreno/ir3/ir3_nir_lower_push_consts_to_preamble.c
+++ b/src/freedreno/ir3/ir3_nir_lower_push_consts_to_preamble.c
@@ -26,7 +26,7 @@ ir3_nir_lower_push_consts_to_preamble(nir_shader *nir,
       .range = v->shader_options.push_consts_dwords);
 
    nir_foreach_function_impl(impl, nir) {
-      nir_metadata_preserve(impl, nir_metadata_none);
+      nir_progress(true, impl, nir_metadata_none);
    }
    return true;
 }
diff --git a/src/freedreno/ir3/ir3_nir_lower_tess.c b/src/freedreno/ir3/ir3_nir_lower_tess.c
index 54ee6d18046..9b6615e1f25 100644
--- a/src/freedreno/ir3/ir3_nir_lower_tess.c
+++ b/src/freedreno/ir3/ir3_nir_lower_tess.c
@@ -301,11 +301,7 @@ ir3_nir_lower_to_explicit_output(nir_shader *shader,
    nir_foreach_block_safe (block, impl)
       progress |= lower_block_to_explicit_output(block, &b, &state);
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
+   nir_progress(progress, impl, nir_metadata_control_flow);
 
    v->output_size = state.map.stride;
    return progress;
@@ -386,11 +382,7 @@ ir3_nir_lower_to_explicit_input(nir_shader *shader,
    nir_foreach_block_safe (block, impl)
       progress |= lower_block_to_explicit_input(block, &b, &state);
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
+   nir_progress(progress, impl, nir_metadata_control_flow);
 
    v->input_size = calc_primitive_map_size(shader);
    return progress;
@@ -723,8 +715,7 @@ ir3_nir_lower_tess_ctrl(nir_shader *shader, struct ir3_shader_variant *v,
 
    nir_pop_if(&b, nif);
 
-   nir_metadata_preserve(impl, nir_metadata_none);
-   return true;
+   return nir_progress(true, impl, nir_metadata_none);
 }
 
 static void
@@ -813,8 +804,7 @@ ir3_nir_lower_tess_eval(nir_shader *shader, struct ir3_shader_variant *v,
 
    v->input_size = calc_primitive_map_size(shader);
 
-   nir_metadata_preserve(impl, nir_metadata_none);
-   return true;
+   return nir_progress(true, impl, nir_metadata_none);
 }
 
 /* The hardware does not support incomplete primitives in multiple streams at
@@ -1096,7 +1086,7 @@ ir3_nir_lower_gs(nir_shader *shader)
    exec_list_append(&shader->variables, &state.emit_outputs);
    exec_list_append(&shader->variables, &state.new_outputs);
 
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 
    nir_lower_global_vars_to_local(shader);
    nir_split_var_copies(shader);
@@ -1109,6 +1099,5 @@ ir3_nir_lower_gs(nir_shader *shader)
       nir_log_shaderi(shader);
    }
 
-   nir_metadata_preserve(impl, nir_metadata_none);
-   return true;
+   return nir_progress(true, impl, nir_metadata_none);
 }
diff --git a/src/freedreno/ir3/ir3_nir_lower_tex_prefetch.c b/src/freedreno/ir3/ir3_nir_lower_tex_prefetch.c
index 9e62683b05e..af9830788e2 100644
--- a/src/freedreno/ir3/ir3_nir_lower_tex_prefetch.c
+++ b/src/freedreno/ir3/ir3_nir_lower_tex_prefetch.c
@@ -203,12 +203,7 @@ lower_tex_prefetch_func(nir_function_impl *impl)
 
    bool progress = lower_tex_prefetch_block(block);
 
-   if (progress) {
-      nir_metadata_preserve(impl,
-                            nir_metadata_control_flow);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/freedreno/ir3/ir3_nir_move_varying_inputs.c b/src/freedreno/ir3/ir3_nir_move_varying_inputs.c
index dec2ae7631f..3d2cde591a6 100644
--- a/src/freedreno/ir3/ir3_nir_move_varying_inputs.c
+++ b/src/freedreno/ir3/ir3_nir_move_varying_inputs.c
@@ -201,10 +201,7 @@ ir3_nir_move_varying_inputs(nir_shader *shader)
          progress |= move_varying_inputs_block(&state, block);
       }
 
-      if (progress) {
-         nir_metadata_preserve(
-            function->impl, nir_metadata_control_flow);
-      }
+      nir_progress(progress, function->impl, nir_metadata_control_flow);
    }
 
    return progress;
diff --git a/src/freedreno/ir3/ir3_nir_opt_preamble.c b/src/freedreno/ir3/ir3_nir_opt_preamble.c
index ba458b1138f..c2381e0eb8b 100644
--- a/src/freedreno/ir3/ir3_nir_opt_preamble.c
+++ b/src/freedreno/ir3/ir3_nir_opt_preamble.c
@@ -763,12 +763,9 @@ ir3_nir_opt_prefetch_descriptors(nir_shader *nir, struct ir3_shader_variant *v)
    }
 
 finished:
-   nir_metadata_preserve(main, nir_metadata_all);
-   if (preamble) {
-      nir_metadata_preserve(preamble,
-                            nir_metadata_block_index |
-                            nir_metadata_dominance);
-   }
+   nir_no_progress(main);
+   nir_progress(preamble, preamble,
+                nir_metadata_block_index | nir_metadata_dominance);
    nir_instr_set_destroy(instr_set);
    free(preamble_defs);
    return progress;
@@ -897,6 +894,5 @@ ir3_nir_lower_preamble(nir_shader *nir, struct ir3_shader_variant *v)
    exec_node_remove(&main->preamble->node);
    main->preamble = NULL;
 
-   nir_metadata_preserve(main, nir_metadata_none);
-   return true;
+   return nir_progress(true, main, nir_metadata_none);
 }
diff --git a/src/freedreno/vulkan/tu_nir_lower_multiview.cc b/src/freedreno/vulkan/tu_nir_lower_multiview.cc
index c48f2929f41..2aa34cdde98 100644
--- a/src/freedreno/vulkan/tu_nir_lower_multiview.cc
+++ b/src/freedreno/vulkan/tu_nir_lower_multiview.cc
@@ -23,8 +23,7 @@ lower_multiview_mask(nir_shader *nir, uint32_t *mask)
    nir_function_impl *impl = nir_shader_get_entrypoint(nir);
 
    if (util_is_power_of_two_or_zero(*mask + 1)) {
-      nir_metadata_preserve(impl, nir_metadata_all);
-      return false;
+      return nir_no_progress(impl);
    }
 
    nir_builder b = nir_builder_create(impl);
@@ -61,13 +60,11 @@ lower_multiview_mask(nir_shader *nir, uint32_t *mask)
          nir_def *src = nir_bcsel(&b, cmp, orig_src, nir_imm_float(&b, 0.));
          nir_src_rewrite(&intrin->src[1], src);
 
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-         return true;
+         return nir_progress(true, impl, nir_metadata_control_flow);
       }
    }
 
-   nir_metadata_preserve(impl, nir_metadata_all);
-   return false;
+   return nir_no_progress(impl);
 }
 
 bool
diff --git a/src/freedreno/vulkan/tu_nir_lower_ray_query.cc b/src/freedreno/vulkan/tu_nir_lower_ray_query.cc
index 18902aee8e7..0499ee52bfa 100644
--- a/src/freedreno/vulkan/tu_nir_lower_ray_query.cc
+++ b/src/freedreno/vulkan/tu_nir_lower_ray_query.cc
@@ -1031,7 +1031,7 @@ tu_nir_lower_ray_queries(nir_shader *shader)
          }
       }
 
-      nir_metadata_preserve(function->impl, nir_metadata_none);
+      nir_progress(true, function->impl, nir_metadata_none);
    }
 
    ralloc_free(query_ht);
diff --git a/src/gallium/auxiliary/nir/tgsi_to_nir.c b/src/gallium/auxiliary/nir/tgsi_to_nir.c
index c59d99ff7f2..c17b88496ab 100644
--- a/src/gallium/auxiliary/nir/tgsi_to_nir.c
+++ b/src/gallium/auxiliary/nir/tgsi_to_nir.c
@@ -2511,8 +2511,7 @@ lower_clipdistance_to_array(nir_shader *nir)
             _mesa_set_add(deletes, deref);
          }
       }
-      if (func_progress)
-         nir_metadata_preserve(impl, nir_metadata_none);
+      nir_progress(func_progress, impl, nir_metadata_none);
       /* derefs must be queued for deletion to avoid deleting the same deref repeatedly */
       set_foreach_remove(deletes, he)
          nir_instr_remove((void*)he->key);
diff --git a/src/gallium/drivers/asahi/agx_nir_lower_point_size.c b/src/gallium/drivers/asahi/agx_nir_lower_point_size.c
index b918d2c3483..19c0c5a6c77 100644
--- a/src/gallium/drivers/asahi/agx_nir_lower_point_size.c
+++ b/src/gallium/drivers/asahi/agx_nir_lower_point_size.c
@@ -58,7 +58,5 @@ agx_nir_lower_point_size(nir_shader *nir, bool insert_write)
       .write_mask = nir_component_mask(1), .src_type = nir_type_float32);
 
    nir->info.outputs_written |= VARYING_BIT_PSIZ;
-   nir_metadata_preserve(b.impl, nir_metadata_control_flow);
-
-   return true;
+   return nir_progress(true, b.impl, nir_metadata_control_flow);
 }
diff --git a/src/gallium/drivers/crocus/crocus_program.c b/src/gallium/drivers/crocus/crocus_program.c
index a107f8f9623..9400380bdd2 100644
--- a/src/gallium/drivers/crocus/crocus_program.c
+++ b/src/gallium/drivers/crocus/crocus_program.c
@@ -341,9 +341,8 @@ crocus_fix_edge_flags(nir_shader *nir)
    nir_fixup_deref_modes(nir);
 
    nir_foreach_function_impl(impl, nir) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow |
-                            nir_metadata_live_defs |
-                            nir_metadata_loop_analysis);
+      nir_progress(true, impl,
+                   nir_metadata_control_flow | nir_metadata_live_defs | nir_metadata_loop_analysis);
    }
 
    return true;
diff --git a/src/gallium/drivers/d3d12/d3d12_lower_point_sprite.c b/src/gallium/drivers/d3d12/d3d12_lower_point_sprite.c
index fe9adac5c64..9607e166982 100644
--- a/src/gallium/drivers/d3d12/d3d12_lower_point_sprite.c
+++ b/src/gallium/drivers/d3d12/d3d12_lower_point_sprite.c
@@ -297,7 +297,7 @@ d3d12_lower_point_sprite(nir_shader *shader,
          }
       }
 
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 
    util_dynarray_fini(&state.output_writes);
diff --git a/src/gallium/drivers/d3d12/d3d12_nir_passes.c b/src/gallium/drivers/d3d12/d3d12_nir_passes.c
index 6fc1158dcad..bfe2bfad78e 100644
--- a/src/gallium/drivers/d3d12/d3d12_nir_passes.c
+++ b/src/gallium/drivers/d3d12/d3d12_nir_passes.c
@@ -101,7 +101,7 @@ d3d12_lower_yflip(nir_shader *nir)
          }
       }
 
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 }
 
@@ -154,7 +154,7 @@ d3d12_lower_depth_range(nir_shader *nir)
          }
       }
 
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 }
 
@@ -247,7 +247,7 @@ d3d12_lower_uint_cast(nir_shader *nir, bool is_signed)
          }
       }
 
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 }
 
@@ -412,7 +412,7 @@ d3d12_nir_invert_depth(nir_shader *shader, unsigned viewport_mask, bool clip_hal
          invert_depth_impl(&b, &state);
       }
 
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 }
 
@@ -524,7 +524,7 @@ d3d12_lower_state_vars(nir_shader *nir, struct d3d12_shader *shader)
          }
       }
 
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 
    if (progress) {
@@ -592,7 +592,7 @@ d3d12_add_missing_dual_src_target(struct nir_shader *s,
 
       nir_store_var(&b, out, zero, 0xf);
    }
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 void
@@ -622,7 +622,7 @@ d3d12_lower_primitive_id(nir_shader *shader)
       }
    }
 
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 }
 
 static void
@@ -755,7 +755,7 @@ d3d12_lower_triangle_strip(nir_shader *shader)
    }
 
    _mesa_hash_table_destroy(tmp_vars, NULL);
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
    NIR_PASS_V(shader, nir_lower_var_copies);
 }
 
@@ -1030,6 +1030,6 @@ d3d12_write_0_to_new_varying(nir_shader *s, nir_variable *var)
          }
       }
 
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 }
diff --git a/src/gallium/drivers/etnaviv/etnaviv_nir.c b/src/gallium/drivers/etnaviv/etnaviv_nir.c
index e108af4c144..a1d06816275 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_nir.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_nir.c
@@ -166,8 +166,7 @@ etna_lower_io(nir_shader *shader, struct etna_shader_variant *v)
          }
       }
 
-      if (func_progress)
-         nir_metadata_preserve(impl, nir_metadata_none);
+      nir_progress(func_progress, impl, nir_metadata_none);
 
       progress |= func_progress;
    }
@@ -235,10 +234,7 @@ etna_lower_alu_impl(nir_function_impl *impl, bool has_new_transcendentals)
       }
    }
 
-   if (progress)
-      nir_metadata_preserve(impl, nir_metadata_none);
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_none);
 }
 
 bool
diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c
index 078514075fb..2962488cbbf 100644
--- a/src/gallium/drivers/iris/iris_program.c
+++ b/src/gallium/drivers/iris/iris_program.c
@@ -859,9 +859,8 @@ iris_fix_edge_flags(nir_shader *nir)
    nir_fixup_deref_modes(nir);
 
    nir_foreach_function_impl(impl, nir) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow |
-                                  nir_metadata_live_defs |
-                                  nir_metadata_loop_analysis);
+      nir_progress(true, impl,
+                   nir_metadata_control_flow | nir_metadata_live_defs | nir_metadata_loop_analysis);
    }
 
    return true;
diff --git a/src/gallium/drivers/lima/ir/lima_nir_duplicate_consts.c b/src/gallium/drivers/lima/ir/lima_nir_duplicate_consts.c
index a8af9bc5709..ff311d0448d 100644
--- a/src/gallium/drivers/lima/ir/lima_nir_duplicate_consts.c
+++ b/src/gallium/drivers/lima/ir/lima_nir_duplicate_consts.c
@@ -117,7 +117,7 @@ lima_nir_duplicate_load_consts_impl(nir_shader *shader, nir_function_impl *impl)
       }
    }
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 /* Duplicate load consts for every user.
diff --git a/src/gallium/drivers/lima/ir/lima_nir_duplicate_intrinsic.c b/src/gallium/drivers/lima/ir/lima_nir_duplicate_intrinsic.c
index 56f2a435154..2598aa6e367 100644
--- a/src/gallium/drivers/lima/ir/lima_nir_duplicate_intrinsic.c
+++ b/src/gallium/drivers/lima/ir/lima_nir_duplicate_intrinsic.c
@@ -119,7 +119,7 @@ lima_nir_duplicate_intrinsic_impl(nir_shader *shader, nir_function_impl *impl,
       }
    }
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 /* Duplicate load uniforms for every user.
diff --git a/src/gallium/drivers/lima/ir/lima_nir_duplicate_modifiers.c b/src/gallium/drivers/lima/ir/lima_nir_duplicate_modifiers.c
index 8b2c4d70eb7..6c427007b39 100644
--- a/src/gallium/drivers/lima/ir/lima_nir_duplicate_modifiers.c
+++ b/src/gallium/drivers/lima/ir/lima_nir_duplicate_modifiers.c
@@ -113,7 +113,7 @@ lima_nir_duplicate_modifier_impl(nir_shader *shader, nir_function_impl *impl,
       }
    }
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 /* Duplicate load inputs for every user.
diff --git a/src/gallium/drivers/r600/sfn/sfn_nir_lower_fs_out_to_vector.cpp b/src/gallium/drivers/r600/sfn/sfn_nir_lower_fs_out_to_vector.cpp
index 279ab19c890..80c1c661e01 100644
--- a/src/gallium/drivers/r600/sfn/sfn_nir_lower_fs_out_to_vector.cpp
+++ b/src/gallium/drivers/r600/sfn/sfn_nir_lower_fs_out_to_vector.cpp
@@ -132,12 +132,7 @@ NirLowerIOToVector::run(nir_function_impl *impl)
    create_new_io_vars(impl->function->shader);
 
    bool progress = vectorize_block(&b, nir_start_block(impl));
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 void
diff --git a/src/gallium/drivers/r600/sfn/sfn_nir_vectorize_vs_inputs.c b/src/gallium/drivers/r600/sfn/sfn_nir_vectorize_vs_inputs.c
index d5d3e05a759..158ebd3a3d4 100644
--- a/src/gallium/drivers/r600/sfn/sfn_nir_vectorize_vs_inputs.c
+++ b/src/gallium/drivers/r600/sfn/sfn_nir_vectorize_vs_inputs.c
@@ -418,11 +418,7 @@ r600_vectorize_io_impl(nir_function_impl *impl)
    bool progress =
       r600_vectorize_block(&b, nir_start_block(impl), instr_set, updated_vars);
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
+   nir_progress(progress, impl, nir_metadata_control_flow);
 
    r600_vec_instr_set_destroy(instr_set);
    return false;
diff --git a/src/gallium/drivers/radeonsi/si_nir_lower_abi.c b/src/gallium/drivers/radeonsi/si_nir_lower_abi.c
index a1484598fd6..8af33eba7e2 100644
--- a/src/gallium/drivers/radeonsi/si_nir_lower_abi.c
+++ b/src/gallium/drivers/radeonsi/si_nir_lower_abi.c
@@ -652,7 +652,7 @@ bool si_nir_lower_abi(nir_shader *nir, struct si_shader *shader, struct si_shade
    nir_metadata preserved = progress ?
       nir_metadata_control_flow :
       nir_metadata_all;
-   nir_metadata_preserve(impl, preserved);
+   nir_progress(true, impl, preserved);
 
    return progress;
 }
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index dcd978fdac9..ecfdbdaad99 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -1654,8 +1654,7 @@ static bool si_nir_kill_outputs(nir_shader *nir, const union si_shader_key *key)
        !key->ge.opt.kill_layer &&
        !key->ge.opt.kill_clip_distances &&
        !(nir->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_LAYER))) {
-      nir_metadata_preserve(impl, nir_metadata_all);
-      return false;
+      return nir_no_progress(impl);
    }
 
    bool progress = false;
@@ -1719,13 +1718,7 @@ static bool si_nir_kill_outputs(nir_shader *nir, const union si_shader_key *key)
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 static unsigned si_map_io_driver_location(unsigned semantic)
@@ -2122,8 +2115,7 @@ static bool si_nir_emit_polygon_stipple(nir_shader *nir)
    nir_def *pass = nir_i2b(b, bit);
    nir_discard_if(b, nir_inot(b, pass));
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
-   return true;
+   return nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 bool si_should_clear_lds(struct si_screen *sscreen, const struct nir_shader *shader)
diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c
index 524bc8db8c9..d20c57e8120 100644
--- a/src/gallium/drivers/radeonsi/si_shader_nir.c
+++ b/src/gallium/drivers/radeonsi/si_shader_nir.c
@@ -411,12 +411,8 @@ static bool si_mark_divergent_texture_non_uniform(struct nir_shader *nir)
             (tex->texture_non_uniform || tex->sampler_non_uniform);
       }
    }
-
-   if (divergence_changed)
-      nir_metadata_preserve(impl, nir_metadata_all & ~nir_metadata_divergence);
-   else
-      nir_metadata_preserve(impl, nir_metadata_all);
-   return divergence_changed;
+   return nir_progress(divergence_changed, impl,
+                       nir_metadata_all & ~nir_metadata_divergence);
 }
 
 char *si_finalize_nir(struct pipe_screen *screen, struct nir_shader *nir)
diff --git a/src/gallium/drivers/vc4/vc4_nir_lower_blend.c b/src/gallium/drivers/vc4/vc4_nir_lower_blend.c
index 7df2247d531..35992840ed4 100644
--- a/src/gallium/drivers/vc4/vc4_nir_lower_blend.c
+++ b/src/gallium/drivers/vc4/vc4_nir_lower_blend.c
@@ -595,8 +595,7 @@ vc4_nir_lower_blend(nir_shader *s, struct vc4_compile *c)
                         vc4_nir_lower_blend_block(block, c);
                 }
 
-                nir_metadata_preserve(impl,
-                                      nir_metadata_control_flow);
+                nir_progress(true, impl, nir_metadata_control_flow);
         }
 
         /* If we didn't do alpha-to-coverage on the output color, we still
diff --git a/src/gallium/drivers/vc4/vc4_nir_lower_io.c b/src/gallium/drivers/vc4/vc4_nir_lower_io.c
index 15e1ca3e35d..32c34fbeb99 100644
--- a/src/gallium/drivers/vc4/vc4_nir_lower_io.c
+++ b/src/gallium/drivers/vc4/vc4_nir_lower_io.c
@@ -349,9 +349,7 @@ vc4_nir_lower_io_impl(struct vc4_compile *c, nir_function_impl *impl)
                         vc4_nir_lower_io_instr(c, &b, instr);
         }
 
-        nir_metadata_preserve(impl, nir_metadata_control_flow);
-
-        return true;
+        return nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 void
diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c
index deb20db5df5..eadabbe1a3a 100644
--- a/src/gallium/drivers/zink/zink_compiler.c
+++ b/src/gallium/drivers/zink/zink_compiler.c
@@ -2571,7 +2571,7 @@ clamp_layer_output(nir_shader *vs, nir_shader *fs, unsigned *next_location)
       b = nir_builder_at(nir_after_impl(impl));
       assert(impl->end_block->predecessors->entries == 1);
       clamp_layer_output_emit(&b, &state);
-      nir_metadata_preserve(impl, nir_metadata_dominance);
+      nir_progress(true, impl, nir_metadata_dominance);
    }
    optimize_nir(vs, NULL, true);
    NIR_PASS_V(vs, nir_remove_dead_variables, nir_var_shader_temp, NULL);
@@ -3251,8 +3251,7 @@ lower_64bit_vars_function(nir_shader *shader, nir_function_impl *impl, nir_varia
          }
       }
    }
-   if (func_progress)
-      nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(func_progress, impl, nir_metadata_none);
    /* derefs must be queued for deletion to avoid deleting the same deref repeatedly */
    set_foreach_remove(deletes, he)
       nir_instr_remove((void*)he->key);
diff --git a/src/gallium/frontends/lavapipe/lvp_ray_tracing_pipeline.c b/src/gallium/frontends/lavapipe/lvp_ray_tracing_pipeline.c
index f99f63ec6c6..56d1485582b 100644
--- a/src/gallium/frontends/lavapipe/lvp_ray_tracing_pipeline.c
+++ b/src/gallium/frontends/lavapipe/lvp_ray_tracing_pipeline.c
@@ -130,12 +130,7 @@ lvp_lower_ray_tracing_derefs(nir_shader *shader)
       }
    }
 
-   if (progress)
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   else
-      nir_metadata_preserve(impl, nir_metadata_all);
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 static bool
diff --git a/src/gallium/frontends/lavapipe/nir/lvp_nir_lower_ray_queries.c b/src/gallium/frontends/lavapipe/nir/lvp_nir_lower_ray_queries.c
index 2389c96ccec..bb89e0dd06b 100644
--- a/src/gallium/frontends/lavapipe/nir/lvp_nir_lower_ray_queries.c
+++ b/src/gallium/frontends/lavapipe/nir/lvp_nir_lower_ray_queries.c
@@ -644,7 +644,7 @@ lvp_nir_lower_ray_queries(struct nir_shader *shader)
          }
       }
 
-      nir_metadata_preserve(function->impl, nir_metadata_none);
+      nir_progress(true, function->impl, nir_metadata_none);
    }
 
    ralloc_free(query_ht);
diff --git a/src/imagination/rogue/nir/rogue_nir_lower_io.c b/src/imagination/rogue/nir/rogue_nir_lower_io.c
index e5aad31e1cb..88508a548e3 100644
--- a/src/imagination/rogue/nir/rogue_nir_lower_io.c
+++ b/src/imagination/rogue/nir/rogue_nir_lower_io.c
@@ -123,12 +123,7 @@ static bool lower_impl(nir_function_impl *impl)
       }
    }
 
-   if (progress)
-      nir_metadata_preserve(impl, nir_metadata_none);
-   else
-      nir_metadata_preserve(impl, nir_metadata_all);
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_none);
 }
 
 PUBLIC
diff --git a/src/intel/compiler/brw_compile_mesh.cpp b/src/intel/compiler/brw_compile_mesh.cpp
index bd46269950e..79794a80a5d 100644
--- a/src/intel/compiler/brw_compile_mesh.cpp
+++ b/src/intel/compiler/brw_compile_mesh.cpp
@@ -279,7 +279,7 @@ brw_nir_lower_mesh_primitive_count(nir_shader *nir)
    }
    nir_pop_if(b, NULL);
 
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 
    nir->info.outputs_written |= VARYING_BIT_PRIMITIVE_COUNT;
 
@@ -1338,9 +1338,9 @@ brw_nir_initialize_mue(nir_shader *nir,
    }
 
    if (remaining) {
-      nir_metadata_preserve(entrypoint, nir_metadata_none);
+      nir_progress(true, entrypoint, nir_metadata_none);
    } else {
-      nir_metadata_preserve(entrypoint, nir_metadata_control_flow);
+      nir_progress(true, entrypoint, nir_metadata_control_flow);
    }
 }
 
diff --git a/src/intel/compiler/brw_kernel.c b/src/intel/compiler/brw_kernel.c
index 204d1a9d999..b32387530c3 100644
--- a/src/intel/compiler/brw_kernel.c
+++ b/src/intel/compiler/brw_kernel.c
@@ -231,13 +231,7 @@ lower_kernel_intrinsics(nir_shader *nir)
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 static const struct spirv_capabilities spirv_caps = {
diff --git a/src/intel/compiler/brw_nir.c b/src/intel/compiler/brw_nir.c
index 95a1daeddb0..f6a140719e5 100644
--- a/src/intel/compiler/brw_nir.c
+++ b/src/intel/compiler/brw_nir.c
@@ -2448,8 +2448,7 @@ brw_nir_move_interpolation_to_top(nir_shader *nir)
 
       progress = progress || impl_progress;
 
-      nir_metadata_preserve(impl, impl_progress ? nir_metadata_control_flow
-                                                : nir_metadata_all);
+      nir_progress(impl_progress, impl, nir_metadata_control_flow);
    }
 
    return progress;
diff --git a/src/intel/compiler/brw_nir_lower_alpha_to_coverage.c b/src/intel/compiler/brw_nir_lower_alpha_to_coverage.c
index f383d932878..f2b7b3fb698 100644
--- a/src/intel/compiler/brw_nir_lower_alpha_to_coverage.c
+++ b/src/intel/compiler/brw_nir_lower_alpha_to_coverage.c
@@ -183,10 +183,8 @@ brw_nir_lower_alpha_to_coverage(nir_shader *shader,
 
    nir_src_rewrite(&sample_mask_write->src[0], dither_mask);
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
-   return true;
+   return nir_progress(true, impl, nir_metadata_control_flow);
 
 skip:
-   nir_metadata_preserve(impl, nir_metadata_all);
-   return false;
+   return nir_no_progress(impl);
 }
diff --git a/src/intel/compiler/brw_nir_lower_cs_intrinsics.c b/src/intel/compiler/brw_nir_lower_cs_intrinsics.c
index c507b0f8d10..2c889318a6c 100644
--- a/src/intel/compiler/brw_nir_lower_cs_intrinsics.c
+++ b/src/intel/compiler/brw_nir_lower_cs_intrinsics.c
@@ -318,8 +318,7 @@ lower_cs_intrinsics_convert_impl(struct lower_intrinsics_state *state)
       lower_cs_intrinsics_convert_block(state, block);
    }
 
-   nir_metadata_preserve(state->impl,
-                         nir_metadata_control_flow);
+   nir_progress(true, state->impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/intel/compiler/brw_nir_lower_intersection_shader.c b/src/intel/compiler/brw_nir_lower_intersection_shader.c
index dc6c859bf58..c3e035140bf 100644
--- a/src/intel/compiler/brw_nir_lower_intersection_shader.c
+++ b/src/intel/compiler/brw_nir_lower_intersection_shader.c
@@ -279,7 +279,7 @@ brw_nir_lower_intersection_shader(nir_shader *intersection,
          }
       }
    }
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 
    /* We did some inlining; have to re-index SSA defs */
    nir_index_ssa_defs(impl);
diff --git a/src/intel/compiler/brw_nir_lower_ray_queries.c b/src/intel/compiler/brw_nir_lower_ray_queries.c
index bc951104378..5ca3aec2588 100644
--- a/src/intel/compiler/brw_nir_lower_ray_queries.c
+++ b/src/intel/compiler/brw_nir_lower_ray_queries.c
@@ -528,7 +528,7 @@ lower_ray_query_impl(nir_function_impl *impl, struct lowering_state *state)
       }
    }
 
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 }
 
 bool
@@ -562,7 +562,7 @@ brw_nir_lower_ray_queries(nir_shader *shader,
                                 nir_var_shader_temp | nir_var_function_temp,
                                 NULL);
 
-      nir_metadata_preserve(state.impl, nir_metadata_none);
+      nir_progress(true, state.impl, nir_metadata_none);
    }
 
    ralloc_free(state.queries);
diff --git a/src/intel/compiler/brw_nir_lower_rt_intrinsics.c b/src/intel/compiler/brw_nir_lower_rt_intrinsics.c
index cca55ffe340..5194862ef71 100644
--- a/src/intel/compiler/brw_nir_lower_rt_intrinsics.c
+++ b/src/intel/compiler/brw_nir_lower_rt_intrinsics.c
@@ -386,10 +386,8 @@ lower_rt_intrinsics_impl(nir_function_impl *impl,
       }
    }
 
-   nir_metadata_preserve(impl,
-                         progress ?
-                         nir_metadata_none :
-                         (nir_metadata_control_flow));
+   nir_progress(true, impl,
+                progress ? nir_metadata_none : (nir_metadata_control_flow));
 }
 
 /** Lower ray-tracing system values and intrinsics
diff --git a/src/intel/compiler/brw_nir_lower_shader_calls.c b/src/intel/compiler/brw_nir_lower_shader_calls.c
index b6d739c032a..3a3f6402082 100644
--- a/src/intel/compiler/brw_nir_lower_shader_calls.c
+++ b/src/intel/compiler/brw_nir_lower_shader_calls.c
@@ -117,7 +117,7 @@ brw_nir_lower_shader_returns(nir_shader *shader)
       }
    }
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 static void
diff --git a/src/intel/compiler/brw_nir_opt_fsat.c b/src/intel/compiler/brw_nir_opt_fsat.c
index fa1f376acff..54d7cb58554 100644
--- a/src/intel/compiler/brw_nir_opt_fsat.c
+++ b/src/intel/compiler/brw_nir_opt_fsat.c
@@ -242,12 +242,8 @@ brw_nir_opt_fsat(nir_shader *shader)
          }
       }
 
-      if (progress_impl) {
-         nir_metadata_preserve(impl, nir_metadata_control_flow);
-         progress = true;
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      progress = progress | nir_progress(progress_impl, impl,
+                                         nir_metadata_control_flow);
    }
 
    if (sources != NULL)
diff --git a/src/intel/compiler/brw_nir_rt.c b/src/intel/compiler/brw_nir_rt.c
index f586dab7f4f..853a6ece8fc 100644
--- a/src/intel/compiler/brw_nir_rt.c
+++ b/src/intel/compiler/brw_nir_rt.c
@@ -144,13 +144,7 @@ lower_rt_io_derefs(nir_shader *shader)
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 /** Lowers ray-tracing shader I/O and scratch access
@@ -331,13 +325,7 @@ lower_ray_walk_intrinsics(nir_shader *shader,
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_none);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_none);
 }
 
 void
diff --git a/src/intel/compiler/elk/elk_nir_lower_alpha_to_coverage.c b/src/intel/compiler/elk/elk_nir_lower_alpha_to_coverage.c
index 59edd9f7481..5240a88fdcf 100644
--- a/src/intel/compiler/elk/elk_nir_lower_alpha_to_coverage.c
+++ b/src/intel/compiler/elk/elk_nir_lower_alpha_to_coverage.c
@@ -183,10 +183,8 @@ elk_nir_lower_alpha_to_coverage(nir_shader *shader,
 
    nir_src_rewrite(&sample_mask_write->src[0], dither_mask);
 
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
-   return true;
+   return nir_progress(true, impl, nir_metadata_control_flow);
 
 skip:
-   nir_metadata_preserve(impl, nir_metadata_all);
-   return false;
+   return nir_no_progress(impl);
 }
diff --git a/src/intel/compiler/elk/elk_nir_lower_cs_intrinsics.c b/src/intel/compiler/elk/elk_nir_lower_cs_intrinsics.c
index 3d9cd99cd24..d60fc507acc 100644
--- a/src/intel/compiler/elk/elk_nir_lower_cs_intrinsics.c
+++ b/src/intel/compiler/elk/elk_nir_lower_cs_intrinsics.c
@@ -289,8 +289,7 @@ lower_cs_intrinsics_convert_impl(struct lower_intrinsics_state *state)
       lower_cs_intrinsics_convert_block(state, block);
    }
 
-   nir_metadata_preserve(state->impl,
-                         nir_metadata_control_flow);
+   nir_progress(true, state->impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/intel/compiler/intel_nir_tcs_workarounds.c b/src/intel/compiler/intel_nir_tcs_workarounds.c
index e2b6f358c88..e06ec236abe 100644
--- a/src/intel/compiler/intel_nir_tcs_workarounds.c
+++ b/src/intel/compiler/intel_nir_tcs_workarounds.c
@@ -131,5 +131,5 @@ intel_nir_apply_tcs_quads_workaround(nir_shader *nir)
       emit_quads_workaround(&b, end_preds[i]);
    }
 
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 }
diff --git a/src/intel/vulkan/anv_nir_lower_multiview.c b/src/intel/vulkan/anv_nir_lower_multiview.c
index 18c6fe69d33..096cdf505e2 100644
--- a/src/intel/vulkan/anv_nir_lower_multiview.c
+++ b/src/intel/vulkan/anv_nir_lower_multiview.c
@@ -301,9 +301,7 @@ anv_nir_lower_multiview(nir_shader *shader, uint32_t view_mask,
       }
    }
 
-   nir_metadata_preserve(entrypoint, nir_metadata_control_flow);
-
-   return true;
+   return nir_progress(true, entrypoint, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/intel/vulkan_hasvk/anv_nir_lower_multiview.c b/src/intel/vulkan_hasvk/anv_nir_lower_multiview.c
index 00d69818b40..20a1551a644 100644
--- a/src/intel/vulkan_hasvk/anv_nir_lower_multiview.c
+++ b/src/intel/vulkan_hasvk/anv_nir_lower_multiview.c
@@ -272,7 +272,5 @@ anv_nir_lower_multiview(nir_shader *shader, uint32_t view_mask)
       }
    }
 
-   nir_metadata_preserve(entrypoint, nir_metadata_control_flow);
-
-   return true;
+   return nir_progress(true, entrypoint, nir_metadata_control_flow);
 }
diff --git a/src/mesa/state_tracker/st_nir_lower_position_invariant.c b/src/mesa/state_tracker/st_nir_lower_position_invariant.c
index 5976dd54326..dcf9b9af330 100644
--- a/src/mesa/state_tracker/st_nir_lower_position_invariant.c
+++ b/src/mesa/state_tracker/st_nir_lower_position_invariant.c
@@ -50,7 +50,5 @@ st_nir_lower_position_invariant(struct nir_shader *s, bool aos,
 
    nir_store_output(&b, result, nir_imm_int(&b, 0),
                     .io_semantics.location = VARYING_SLOT_POS);
-   nir_metadata_preserve(b.impl, nir_metadata_control_flow);
-
-   return true;
+   return nir_progress(true, b.impl, nir_metadata_control_flow);
 }
diff --git a/src/microsoft/clc/clc_nir.c b/src/microsoft/clc/clc_nir.c
index 46b9df7129a..6d4161384ac 100644
--- a/src/microsoft/clc/clc_nir.c
+++ b/src/microsoft/clc/clc_nir.c
@@ -247,12 +247,8 @@ clc_lower_printf_base(nir_shader *nir, unsigned uav_id)
          }
       }
 
-      if (progress)
-         nir_metadata_preserve(impl, nir_metadata_loop_analysis |
-                                     nir_metadata_block_index |
-                                     nir_metadata_dominance);
-      else
-         nir_metadata_preserve(impl, nir_metadata_all);
+      nir_progress(progress, impl,
+                   nir_metadata_loop_analysis | nir_metadata_block_index | nir_metadata_dominance);
    }
 
    return printf_var != NULL;
diff --git a/src/microsoft/compiler/dxil_nir.c b/src/microsoft/compiler/dxil_nir.c
index 9cdf8381289..69fa0945f2e 100644
--- a/src/microsoft/compiler/dxil_nir.c
+++ b/src/microsoft/compiler/dxil_nir.c
@@ -900,13 +900,7 @@ upcast_phi_impl(nir_function_impl *impl, unsigned min_bit_size)
       }
    }
 
-   if (progress) {
-      nir_metadata_preserve(impl, nir_metadata_control_flow);
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-   }
-
-   return progress;
+   return nir_progress(progress, impl, nir_metadata_control_flow);
 }
 
 bool
diff --git a/src/microsoft/compiler/dxil_nir_tess.c b/src/microsoft/compiler/dxil_nir_tess.c
index dc489e8b89c..6c2adec4297 100644
--- a/src/microsoft/compiler/dxil_nir_tess.c
+++ b/src/microsoft/compiler/dxil_nir_tess.c
@@ -54,7 +54,7 @@ remove_hs_intrinsics(nir_function_impl *impl)
          nir_instr_remove(instr);
       }
    }
-   nir_metadata_preserve(impl, nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 static void
diff --git a/src/nouveau/codegen/nv50_ir_from_nir.cpp b/src/nouveau/codegen/nv50_ir_from_nir.cpp
index a00a4679fdc..eb4af297f24 100644
--- a/src/nouveau/codegen/nv50_ir_from_nir.cpp
+++ b/src/nouveau/codegen/nv50_ir_from_nir.cpp
@@ -3296,8 +3296,7 @@ nv_nir_move_stores_to_end(nir_shader *s)
             first_store = instr;
       }
    }
-   nir_metadata_preserve(impl,
-                         nir_metadata_control_flow);
+   nir_progress(true, impl, nir_metadata_control_flow);
 }
 
 unsigned
diff --git a/src/nouveau/compiler/nak_nir_lower_cf.c b/src/nouveau/compiler/nak_nir_lower_cf.c
index f8aece84bfe..0c17c31d3a3 100644
--- a/src/nouveau/compiler/nak_nir_lower_cf.c
+++ b/src/nouveau/compiler/nak_nir_lower_cf.c
@@ -436,8 +436,7 @@ lower_cf_func(nir_function *func)
       return false;
 
    if (exec_list_is_singular(&func->impl->body)) {
-      nir_metadata_preserve(func->impl, nir_metadata_all);
-      return false;
+      return nir_no_progress(func->impl);
    }
 
    nir_function_impl *old_impl = func->impl;
diff --git a/src/nouveau/compiler/nak_nir_lower_gs_intrinsics.c b/src/nouveau/compiler/nak_nir_lower_gs_intrinsics.c
index 0640abd62e5..f5518fe64a2 100644
--- a/src/nouveau/compiler/nak_nir_lower_gs_intrinsics.c
+++ b/src/nouveau/compiler/nak_nir_lower_gs_intrinsics.c
@@ -119,7 +119,7 @@ nak_nir_lower_gs_intrinsics(nir_shader *nir)
 
    append_final_primitive_nv(impl->end_block, &state);
 
-   nir_metadata_preserve(impl, nir_metadata_none);
+   nir_progress(true, impl, nir_metadata_none);
 
    return state.progress;
 }
\ No newline at end of file
diff --git a/src/nouveau/compiler/nak_nir_lower_non_uniform_ldcx.c b/src/nouveau/compiler/nak_nir_lower_non_uniform_ldcx.c
index ecd8696e5d6..c19b068f187 100644
--- a/src/nouveau/compiler/nak_nir_lower_non_uniform_ldcx.c
+++ b/src/nouveau/compiler/nak_nir_lower_non_uniform_ldcx.c
@@ -479,11 +479,6 @@ nak_nir_lower_non_uniform_ldcx(nir_shader *nir)
    /* We use block indices to determine when something is a predecessor */
    nir_metadata_require(impl, nir_metadata_block_index | nir_metadata_divergence);
 
-   if (lower_cf_list(&b, &impl->body)) {
-      nir_metadata_preserve(impl, nir_metadata_none);
-      return true;
-   } else {
-      nir_metadata_preserve(impl, nir_metadata_all);
-      return false;
-   }
+   bool progress = lower_cf_list(&b, &impl->body);
+   return nir_progress(progress, impl, nir_metadata_none);
 }
diff --git a/src/nouveau/compiler/nak_nir_mark_lcssa_invariants.c b/src/nouveau/compiler/nak_nir_mark_lcssa_invariants.c
index bd343bc543f..f0016c50b03 100644
--- a/src/nouveau/compiler/nak_nir_mark_lcssa_invariants.c
+++ b/src/nouveau/compiler/nak_nir_mark_lcssa_invariants.c
@@ -107,13 +107,9 @@ nak_nir_mark_lcssa_invariants(nir_shader *shader)
       nir_builder b = nir_builder_create(impl);
       nir_metadata_require(impl, nir_metadata_divergence);
 
-      if (lower_cf_list(&b, &impl->body)) {
-         progress = true;
-         nir_metadata_preserve(impl, nir_metadata_control_flow |
-                                     nir_metadata_divergence);
-      } else {
-         nir_metadata_preserve(impl, nir_metadata_all);
-      }
+      bool impl_progress = lower_cf_list(&b, &impl->body);
+      progress = progress | nir_progress(impl_progress, impl,
+                                         nir_metadata_control_flow | nir_metadata_divergence);
    }
 
    return progress;
diff --git a/src/panfrost/midgard/nir_fuse_io_16.c b/src/panfrost/midgard/nir_fuse_io_16.c
index 18fd962e195..d19b3740b82 100644
--- a/src/panfrost/midgard/nir_fuse_io_16.c
+++ b/src/panfrost/midgard/nir_fuse_io_16.c
@@ -88,8 +88,7 @@ nir_fuse_io_16(nir_shader *shader)
          }
       }
 
-      nir_metadata_preserve(impl,
-                            nir_metadata_control_flow);
+      nir_progress(true, impl, nir_metadata_control_flow);
    }
 
    return progress;
diff --git a/src/panfrost/util/pan_lower_writeout.c b/src/panfrost/util/pan_lower_writeout.c
index 532c11f4e6c..1c0d623d988 100644
--- a/src/panfrost/util/pan_lower_writeout.c
+++ b/src/panfrost/util/pan_lower_writeout.c
@@ -229,9 +229,7 @@ pan_nir_lower_zs_store(nir_shader *nir)
             nir_instr_remove(&stores[i]->instr);
       }
 
-      nir_metadata_preserve(impl,
-                            nir_metadata_control_flow);
-      progress = true;
+      progress = nir_progress(true, impl, nir_metadata_control_flow);
    }
 
    return progress;
-- 
2.48.1

