diff options
author | Ian Romanick <[email protected]> | 2019-01-14 11:36:23 -0800 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2019-02-08 10:37:06 -0800 |
commit | 8d8f80af3a17354508f2ec9d6559c915d5be351d (patch) | |
tree | 7c5a452bbf7e76e75c7a4ba2df4c900a08d5d0a3 /src | |
parent | 4d65d2b12ee261a3e37f197bcf5c4ac1807fc9d1 (diff) |
nir: Refactor code that checks phi nodes in opt_peel_loop_initial_if
This will be used in a couple more places soon.
The function name is... horribly long. Neither Matt nor I could think
of any thing that was shorter and still more descriptive than
"is_phi_foo". I'm willing to entertain suggestions.
Fixes: 8fb8ebfbb05 ("intel/compiler: More peephole select")
Reviewed-by: Timothy Arceri <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/nir/nir_opt_if.c | 52 |
1 files changed, 36 insertions, 16 deletions
diff --git a/src/compiler/nir/nir_opt_if.c b/src/compiler/nir/nir_opt_if.c index c2f945d4d59..c54d4a20f4c 100644 --- a/src/compiler/nir/nir_opt_if.c +++ b/src/compiler/nir/nir_opt_if.c @@ -49,6 +49,37 @@ find_continue_block(nir_loop *loop) } /** + * Does a phi have one constant value from outside a loop and one from inside? + */ +static bool +phi_has_constant_from_outside_and_one_from_inside_loop(nir_phi_instr *phi, + const nir_block *continue_block, + uint32_t *entry_val, + uint32_t *continue_val) +{ + /* We already know we have exactly one continue */ + assert(exec_list_length(&phi->srcs) == 2); + + *entry_val = 0; + *continue_val = 0; + + nir_foreach_phi_src(src, phi) { + assert(src->src.is_ssa); + nir_const_value *const_src = nir_src_as_const_value(src->src); + if (!const_src) + return false; + + if (src->pred == continue_block) { + *continue_val = const_src->u32[0]; + } else { + *entry_val = const_src->u32[0]; + } + } + + return true; +} + +/** * This optimization detects if statements at the tops of loops where the * condition is a phi node of two constants and moves half of the if to above * the loop and the other half of the if to the end of the loop. A simple for @@ -136,23 +167,12 @@ opt_peel_loop_initial_if(nir_loop *loop) if (cond->parent_instr->block != header_block) return false; - /* We already know we have exactly one continue */ - assert(exec_list_length(&cond_phi->srcs) == 2); - uint32_t entry_val = 0, continue_val = 0; - nir_foreach_phi_src(src, cond_phi) { - assert(src->src.is_ssa); - nir_const_value *const_src = nir_src_as_const_value(src->src); - if (!const_src) - return false; - - if (src->pred == continue_block) { - continue_val = const_src->u32[0]; - } else { - assert(src->pred == prev_block); - entry_val = const_src->u32[0]; - } - } + if (!phi_has_constant_from_outside_and_one_from_inside_loop(cond_phi, + continue_block, + &entry_val, + &continue_val)) + return false; /* If they both execute or both don't execute, this is a job for * nir_dead_cf, not this pass. |