From: Eric Anholt Date: Thu, 20 Aug 2020 18:43:29 +0000 (-0700) Subject: nir: Add a helper for general instruction-modifying passes. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a62098fff202f5e6c689aa6e78ace67c50f17c8e;p=mesa.git nir: Add a helper for general instruction-modifying passes. The nir_shader_lower_instructions() is really nice, but it's only for SSA operations, and sometimes you want something more general. I've put it in nir_builder.h so it can be inlined and retain the same performance characteristics we're used to in our lowering passes even in the absence of LTO. Reviewed-By: Mike Blumenkrantz Part-of: --- diff --git a/src/compiler/nir/nir_builder.h b/src/compiler/nir/nir_builder.h index 6da2e3c4cc1..af638275eec 100644 --- a/src/compiler/nir/nir_builder.h +++ b/src/compiler/nir/nir_builder.h @@ -62,6 +62,49 @@ nir_builder_init_simple_shader(nir_builder *build, void *mem_ctx, build->cursor = nir_after_cf_list(&build->impl->body); } +typedef bool (*nir_instr_pass_cb)(struct nir_builder *, nir_instr *, void *); + +/** + * Iterates over all the instructions in a NIR shader and calls the given pass + * on them. + * + * The pass should return true if it modified the shader. In that case, only + * the preserved metadata flags will be preserved in the function impl. + * + * The builder will be initialized to point at the function impl, but its + * cursor is unset. + */ +static inline bool +nir_shader_instructions_pass(nir_shader *shader, + nir_instr_pass_cb pass, + nir_metadata preserved, + void *cb_data) +{ + bool progress = false; + + nir_foreach_function(function, shader) { + if (!function->impl) + continue; + + nir_builder b; + nir_builder_init(&b, function->impl); + + nir_foreach_block_safe(block, function->impl) { + nir_foreach_instr_safe(instr, block) { + progress |= pass(&b, instr, cb_data); + } + } + + if (progress) { + nir_metadata_preserve(function->impl, preserved); + } else { + nir_metadata_preserve(function->impl, nir_metadata_all); + } + } + + return progress; +} + static inline void nir_builder_instr_insert(nir_builder *build, nir_instr *instr) {