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

Reply via email to