mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 17:30:12 +01:00
nir: consider loop invariance in nir_src_is_divergent()
By doing so, this function does not require LCSSA form anymore in order to provide correct results. Reviewed-by: Rhys Perry <pendingchaos02@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30787>
This commit is contained in:
parent
1a55d6c23b
commit
d34d2f8fa8
1 changed files with 34 additions and 1 deletions
|
|
@ -73,7 +73,40 @@ visit_cf_list(struct exec_list *list, struct divergence_state *state);
|
|||
bool
|
||||
nir_src_is_divergent(nir_src *src)
|
||||
{
|
||||
return src->ssa->divergent;
|
||||
if (src->ssa->divergent)
|
||||
return true;
|
||||
|
||||
nir_cf_node *use_node = nir_src_get_block(src)->cf_node.parent;
|
||||
nir_cf_node *def_node = src->ssa->parent_instr->block->cf_node.parent;
|
||||
|
||||
/* Short-cut the common case. */
|
||||
if (def_node == use_node)
|
||||
return false;
|
||||
|
||||
/* If the source was computed in a divergent loop, and is not
|
||||
* loop-invariant, then it must also be considered divergent.
|
||||
*/
|
||||
bool loop_invariant = src->ssa->loop_invariant;
|
||||
while (def_node) {
|
||||
if (def_node->type == nir_cf_node_loop) {
|
||||
/* Check whether the use is inside this loop. */
|
||||
for (nir_cf_node *node = use_node; node != NULL; node = node->parent) {
|
||||
if (def_node == node)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Because the use is outside of this loop, it is divergent. */
|
||||
if (nir_cf_node_as_loop(def_node)->divergent_break && !loop_invariant)
|
||||
return true;
|
||||
|
||||
/* For outer loops, consider this variable not loop invariant. */
|
||||
loop_invariant = false;
|
||||
}
|
||||
|
||||
def_node = def_node->parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue