nir: Avoid coalescing vars created by lower_io_to_temporaries
Right now nir_copy_prop_vars is effectively undoing nir_lower_io_to_temporaries for inputs by propagating the original variable through the copy created in lower_io_to_temporaries. A theoretical variable coalescing pass would have the same issue with output variables, although that doesn't exist yet. To fix this, add a new bit to nir_variable, and disable copy propagation when it's set. This doesn't seem to affect any drivers now, probably since since no one uses lower_io_to_temporaries for inputs as well as copy_prop_vars, but it will fix radv once we flip on lower_io_to_temporaries for fs inputs. Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
This commit is contained in:
@@ -227,6 +227,17 @@ typedef struct nir_variable {
|
|||||||
unsigned patch:1;
|
unsigned patch:1;
|
||||||
unsigned invariant:1;
|
unsigned invariant:1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can this variable be coalesced with another?
|
||||||
|
*
|
||||||
|
* This is set by nir_lower_io_to_temporaries to say that any
|
||||||
|
* copies involving this variable should stay put. Propagating it can
|
||||||
|
* duplicate the resulting load/store, which is not wanted, and may
|
||||||
|
* result in a load/store of the variable with an indirect offset which
|
||||||
|
* the backend may not be able to handle.
|
||||||
|
*/
|
||||||
|
unsigned cannot_coalesce:1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When separate shader programs are enabled, only input/outputs between
|
* When separate shader programs are enabled, only input/outputs between
|
||||||
* the stages of a multi-stage separate program can be safely removed
|
* the stages of a multi-stage separate program can be safely removed
|
||||||
|
@@ -123,6 +123,7 @@ create_shadow_temp(struct lower_io_state *state, nir_variable *var)
|
|||||||
{
|
{
|
||||||
nir_variable *nvar = ralloc(state->shader, nir_variable);
|
nir_variable *nvar = ralloc(state->shader, nir_variable);
|
||||||
memcpy(nvar, var, sizeof *nvar);
|
memcpy(nvar, var, sizeof *nvar);
|
||||||
|
nvar->data.cannot_coalesce = true;
|
||||||
|
|
||||||
/* The original is now the temporary */
|
/* The original is now the temporary */
|
||||||
nir_variable *temp = var;
|
nir_variable *temp = var;
|
||||||
|
@@ -997,6 +997,14 @@ copy_prop_vars_block(struct copy_prop_var_state *state,
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nir_variable *src_var = nir_deref_instr_get_variable(src);
|
||||||
|
if (src_var && src_var->data.cannot_coalesce) {
|
||||||
|
/* The source cannot be coaleseced, which means we can't propagate
|
||||||
|
* this copy.
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
struct copy_entry *dst_entry =
|
struct copy_entry *dst_entry =
|
||||||
get_entry_and_kill_aliases(copies, dst, full_mask);
|
get_entry_and_kill_aliases(copies, dst, full_mask);
|
||||||
value_set_from_value(&dst_entry->src, &value, 0, full_mask);
|
value_set_from_value(&dst_entry->src, &value, 0, full_mask);
|
||||||
|
Reference in New Issue
Block a user