Module: Mesa Branch: main Commit: debddca1344435d3b30cb86e5a9d4f3b79a378f8 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=debddca1344435d3b30cb86e5a9d4f3b79a378f8
Author: Rhys Perry <pendingchao...@gmail.com> Date: Mon Jul 17 17:49:04 2023 +0100 nir: add helpers to skip idempotent passes For example, in the loop: while (more_late_algebraic) { more_late_algebraic = false; NIR_PASS(more_late_algebraic, nir, nir_opt_algebraic_late); NIR_PASS(_, nir, nir_opt_constant_folding); NIR_PASS(_, nir, nir_copy_prop); NIR_PASS(_, nir, nir_opt_dce); NIR_PASS(_, nir, nir_opt_cse); } if nir_opt_algebraic_late makes no progress, later passes might be skippable depending on which ones made progress in the previous iteration. Signed-off-by: Rhys Perry <pendingchao...@gmail.com> Reviewed-by: Bas Nieuwenhuizen <b...@basnieuwenhuizen.nl> Reviewed-by: Daniel Schürmann <dan...@schuermann.dev> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24197> --- src/compiler/nir/nir.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 365c47893fa..9df515f1342 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -4883,6 +4883,51 @@ should_print_nir(UNUSED nir_shader *shader) nir_print_shader(nir, stdout); \ }) +#define _NIR_LOOP_PASS(progress, idempotent, skip, nir, pass, ...) \ +do { \ + bool nir_loop_pass_progress = false; \ + if (!_mesa_set_search(skip, (void (*)())&pass)) \ + NIR_PASS(nir_loop_pass_progress, nir, pass, ##__VA_ARGS__); \ + if (nir_loop_pass_progress) \ + _mesa_set_clear(skip, NULL); \ + if (idempotent || !nir_loop_pass_progress) \ + _mesa_set_add(skip, (void (*)())&pass); \ + UNUSED bool _ = false; \ + progress |= nir_loop_pass_progress; \ +} while (0) + +/* Helper to skip a pass if no different passes have made progress since it was + * previously run. Note that two passes are considered the same if they have + * the same function pointer, even if they used different options. + * + * The usage of this is mostly identical to NIR_PASS. "skip" is a "struct set *" + * (created by _mesa_pointer_set_create) which the macro uses to keep track of + * already run passes. + * + * Example: + * bool progress = true; + * struct set *skip = _mesa_pointer_set_create(NULL); + * while (progress) { + * progress = false; + * NIR_LOOP_PASS(progress, skip, nir, pass1); + * NIR_LOOP_PASS_NOT_IDEMPOTENT(progress, skip, nir, nir_opt_algebraic); + * NIR_LOOP_PASS(progress, skip, nir, pass2); + * ... + * } + * _mesa_set_destroy(skip, NULL); + * + * You shouldn't mix usage of this with the NIR_PASS set of helpers, without + * using a new "skip" in-between. + */ +#define NIR_LOOP_PASS(progress, skip, nir, pass, ...) \ + _NIR_LOOP_PASS(progress, true, skip, nir, pass, ##__VA_ARGS__) + +/* Like NIR_LOOP_PASS, but use this for passes which may make further progress + * when repeated. + */ +#define NIR_LOOP_PASS_NOT_IDEMPOTENT(progress, skip, nir, pass, ...) \ + _NIR_LOOP_PASS(progress, false, skip, nir, pass, ##__VA_ARGS__) + #define NIR_SKIP(name) should_skip_nir(#name) /** An instruction filtering callback with writemask