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: 8fb8ebfbb0
("intel/compiler: More peephole select")
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
This commit is contained in:
parent
4d65d2b12e
commit
8d8f80af3a
|
@ -48,6 +48,37 @@ find_continue_block(nir_loop *loop)
|
|||
unreachable("Continue block not found!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue