mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 02:10:11 +01:00
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 <pendingchaos02@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24197>
This commit is contained in:
parent
faed5d647f
commit
debddca134
1 changed files with 45 additions and 0 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue