From ad8b5325d43125247f39cf4ccfae2ea561f5e2fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sat, 18 Jan 2025 22:22:26 -0500 Subject: [PATCH] nir/group_loads: group any reorderable intrinsics regardless of barriers Acked-by: Alyssa Rosenzweig Part-of: --- src/compiler/nir/nir_group_loads.c | 47 +++++++++--------------------- 1 file changed, 13 insertions(+), 34 deletions(-) diff --git a/src/compiler/nir/nir_group_loads.c b/src/compiler/nir/nir_group_loads.c index 9879e1be269..dd54a588bd4 100644 --- a/src/compiler/nir/nir_group_loads.c +++ b/src/compiler/nir/nir_group_loads.c @@ -119,8 +119,10 @@ is_grouped_load(nir_instr *instr) if (instr->type == nir_instr_type_tex) return true; - if (instr->type == nir_instr_type_intrinsic) - return get_intrinsic_resource(nir_instr_as_intrinsic(instr)) != NULL; + if (instr->type == nir_instr_type_intrinsic) { + return get_intrinsic_resource(nir_instr_as_intrinsic(instr)) != NULL && + nir_intrinsic_can_reorder(nir_instr_as_intrinsic(instr)); + } return false; } @@ -130,22 +132,14 @@ can_move(nir_instr *instr, uint8_t current_indirection_level) { /* Grouping is done by moving everything else out of the first/last * instruction range of the indirection level. + * + * We can move anything that's not a grouped load because we are not really + * moving it. What we are doing is that we are moving grouped loads to + * the same place by moving everything else between the first and last load + * out of the way. This doesn't change the order of non-reorderable + * instructions. */ - if (is_grouped_load(instr) && instr->pass_flags == current_indirection_level) - return false; - - if (instr->type == nir_instr_type_alu || - instr->type == nir_instr_type_deref || - instr->type == nir_instr_type_tex || - instr->type == nir_instr_type_load_const || - instr->type == nir_instr_type_undef) - return true; - - if (instr->type == nir_instr_type_intrinsic && - nir_intrinsic_can_reorder(nir_instr_as_intrinsic(instr))) - return true; - - return false; + return !is_grouped_load(instr) || instr->pass_flags != current_indirection_level; } static nir_instr * @@ -329,21 +323,6 @@ is_demote(nir_instr *instr) return false; } -static bool -is_barrier(nir_instr *instr) -{ - if (instr->type == nir_instr_type_intrinsic) { - nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); - const char *name = nir_intrinsic_infos[intr->intrinsic].name; - - /* TODO: nir_intrinsics.py could do this */ - if (strstr(name, "barrier")) - return true; - } - - return false; -} - struct indirection_state { nir_block *block; unsigned indirections; @@ -447,8 +426,8 @@ process_block(nir_block *block, nir_load_grouping grouping, * between them out. */ nir_foreach_instr(current, block) { - /* Don't group across terminate and barriers. */ - if (is_demote(current) || is_barrier(current)) { + /* Don't group across terminate. */ + if (is_demote(current)) { /* Group unconditionally. */ handle_load_range(&first_load, &last_load, NULL, 0); first_load = NULL;