From 48f093a45b823caa60cad27bf91c0e642857c5ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tapani=20P=C3=A4lli?= Date: Thu, 2 May 2019 13:49:41 +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 Signed-off-by: Tapani Pälli --- src/compiler/nir/nir.h | 3 ++ src/compiler/nir/nir_loop_analyze.c | 38 ++++++++++++++++++++++++++ src/compiler/nir/nir_opt_loop_unroll.c | 4 +++ 3 files changed, 45 insertions(+) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 3fc01b798e4..313a10205b8 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -1963,6 +1963,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..45c66fb237b 100644 --- a/src/compiler/nir/nir_loop_analyze.c +++ b/src/compiler/nir/nir_loop_analyze.c @@ -1016,6 +1016,35 @@ 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) +{ + uint32_t unwanted_ops = 0; + nir_foreach_instr(instr, block) { + switch (instr->type) { + case nir_instr_type_alu: { + nir_alu_instr *alu = nir_instr_as_alu(instr); + switch (alu->op) { + case nir_op_u2u8: + case nir_op_i2i8: + unwanted_ops++; + break; + default: + break; + } + break; + } + default: + break; + } + } + + if (unwanted_ops > 10) + return true; + + return false; +} + static bool force_unroll_heuristics(loop_info_state *state, nir_block *block) { @@ -1115,6 +1144,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