mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 11:18:08 +02:00
nak: add nak_nir_phi_is_divergent helper
This commit is contained in:
parent
0fc02a8b69
commit
584ba918a1
2 changed files with 35 additions and 27 deletions
|
|
@ -376,6 +376,39 @@ lower_cf_list(nir_builder *b, nir_def *esc_reg, struct scope *parent_scope,
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nak_nir_phi_is_divergent(nir_phi_instr *phi)
|
||||
{
|
||||
bool divergent = false;
|
||||
nir_foreach_phi_src(phi_src, phi) {
|
||||
/* There is a tricky case we need to care about here where a
|
||||
* convergent block has a divergent dominator. This can happen
|
||||
* if, for instance, you have the following loop:
|
||||
*
|
||||
* loop {
|
||||
* if (div) {
|
||||
* %20 = load_ubo(0, 0);
|
||||
* } else {
|
||||
* terminate;
|
||||
* }
|
||||
* }
|
||||
* use(%20);
|
||||
*
|
||||
* In this case, the load_ubo() dominates the use() even though
|
||||
* the load_ubo() exists in divergent control-flow. In this
|
||||
* case, we simply flag the whole phi divergent because we
|
||||
* don't want to deal with inserting a r2ur somewhere.
|
||||
*/
|
||||
if (phi_src->pred->divergent || phi_src->src.ssa->divergent ||
|
||||
nir_def_block(phi_src->src.ssa)->divergent) {
|
||||
divergent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return divergent;
|
||||
}
|
||||
|
||||
static void
|
||||
recompute_phi_divergence_impl(nir_function_impl *impl)
|
||||
{
|
||||
|
|
@ -388,33 +421,7 @@ recompute_phi_divergence_impl(nir_function_impl *impl)
|
|||
break;
|
||||
|
||||
nir_phi_instr *phi = nir_instr_as_phi(instr);
|
||||
|
||||
bool divergent = false;
|
||||
nir_foreach_phi_src(phi_src, phi) {
|
||||
/* There is a tricky case we need to care about here where a
|
||||
* convergent block has a divergent dominator. This can happen
|
||||
* if, for instance, you have the following loop:
|
||||
*
|
||||
* loop {
|
||||
* if (div) {
|
||||
* %20 = load_ubo(0, 0);
|
||||
* } else {
|
||||
* terminate;
|
||||
* }
|
||||
* }
|
||||
* use(%20);
|
||||
*
|
||||
* In this case, the load_ubo() dominates the use() even though
|
||||
* the load_ubo() exists in divergent control-flow. In this
|
||||
* case, we simply flag the whole phi divergent because we
|
||||
* don't want to deal with inserting a r2ur somewhere.
|
||||
*/
|
||||
if (phi_src->pred->divergent || phi_src->src.ssa->divergent ||
|
||||
nir_def_block(phi_src->src.ssa)->divergent) {
|
||||
divergent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool divergent = nak_nir_phi_is_divergent(phi);
|
||||
|
||||
if (divergent != phi->def.divergent) {
|
||||
phi->def.divergent = divergent;
|
||||
|
|
|
|||
|
|
@ -370,6 +370,7 @@ bool nak_nir_lower_cmat(nir_shader *shader, const struct nak_compiler *nak);
|
|||
* writing uregs from these blocks.
|
||||
*/
|
||||
bool nak_block_is_divergent(const nir_block *block);
|
||||
bool nak_nir_phi_is_divergent(nir_phi_instr *phi);
|
||||
|
||||
void nak_optimize_nir(nir_shader *nir, const struct nak_compiler *nak);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue