From e3ad271273cb11343907ad079833a1f9c98933de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tapani=20P=C3=A4lli?= Date: Fri, 3 May 2019 09:54:32 +0300 Subject: [PATCH] nir: HACK - refuse loop unrolling with hacky restrictions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes a lot of Android CTS tests that currently timeout because compilation of shaders can take up to many minutes in: dEQP-VK.spirv_assembly.instruction.graphics.8bit_storage.* Signed-off-by: Tapani Pälli --- src/compiler/nir/nir.h | 3 ++ src/compiler/nir/nir_loop_analyze.c | 49 ++++++++++++++++++++++++++ src/compiler/nir/nir_opt_loop_unroll.c | 4 +++ 3 files changed, 56 insertions(+) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 3083adbfcd9..c2f49e3d03e 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -1966,6 +1966,9 @@ typedef struct { /* Unroll the loop regardless of its size */ bool force_unroll; + /* Do not unroll the loop, no matter what. */ + bool force_no_unroll; + /* Does the loop contain complex loop terminators, continues or other * complex behaviours? If this is true we can't rely on * loop_terminator_list to be complete or accurate. diff --git a/src/compiler/nir/nir_loop_analyze.c b/src/compiler/nir/nir_loop_analyze.c index 0ae9533e007..67b0396cb4c 100644 --- a/src/compiler/nir/nir_loop_analyze.c +++ b/src/compiler/nir/nir_loop_analyze.c @@ -1016,6 +1016,46 @@ force_unroll_array_access(loop_info_state *state, nir_deref_instr *deref) return false; } +static bool +force_no_unroll_heuristics(loop_info_state *state, nir_block *block) +{ + nir_foreach_instr(instr, block) { + if (instr->type != nir_instr_type_alu) + continue; + + nir_alu_instr *alu = nir_instr_as_alu(instr); + switch (alu->op) { + case nir_op_u2u8: + case nir_op_i2i8: + case nir_op_i2i32: + case nir_op_u2u32: + /* Check if the parent is ubo/ssbo load. */ + if (alu->src[0].src.is_ssa) { + nir_instr *parent = alu->src[0].src.ssa->parent_instr; + if (parent->type == nir_instr_type_intrinsic) { + nir_intrinsic_instr *ii = nir_instr_as_intrinsic(parent); + if (ii->intrinsic == nir_intrinsic_load_ubo || + ii->intrinsic == nir_intrinsic_load_ssbo) + return true; + + /* Check if deref points to variable in ssbo, ubo. */ + if (ii->intrinsic == nir_intrinsic_load_deref) { + nir_deref_instr *deref = + nir_instr_as_deref(ii->src->ssa->parent_instr); + if (deref->mode == nir_var_mem_ssbo || + deref->mode == nir_var_mem_ubo) + return true; + } + } + } + break; + default: + break; + } + } + return false; +} + static bool force_unroll_heuristics(loop_info_state *state, nir_block *block) { @@ -1115,6 +1155,15 @@ get_loop_info(loop_info_state *state, nir_function_impl *impl) break; } } + + nir_foreach_block_in_cf_node(block, &state->loop->cf_node) { + if (force_no_unroll_heuristics(state, block)) { + state->loop->info->force_unroll = false; + state->loop->info->force_no_unroll = true; + break; + } + } + } static loop_info_state * diff --git a/src/compiler/nir/nir_opt_loop_unroll.c b/src/compiler/nir/nir_opt_loop_unroll.c index c0198390749..bdb4a7c64d4 100644 --- a/src/compiler/nir/nir_opt_loop_unroll.c +++ b/src/compiler/nir/nir_opt_loop_unroll.c @@ -783,6 +783,10 @@ check_unrolling_restrictions(nir_shader *shader, nir_loop *loop) return false; nir_loop_info *li = loop->info; + + if (li->force_no_unroll) + return false; + unsigned max_iter = shader->options->max_unroll_iterations; unsigned trip_count = li->max_trip_count ? li->max_trip_count : li->guessed_trip_count; -- 2.20.1