nir: Add a helper for chasing movs with nir_ssa_scalar().

Sometimes you might want to find a constant source without going through
all the copy prop and constant folding to make your source be a
load_const.

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11613>
This commit is contained in:
Emma Anholt 2021-06-25 13:58:04 -07:00 committed by Marge Bot
parent 9133999430
commit 0afab39af9
3 changed files with 54 additions and 22 deletions

View file

@ -2502,3 +2502,44 @@ nir_variable *nir_get_binding_variable(nir_shader *shader, nir_binding binding)
return binding_var;
}
bool
nir_alu_instr_is_copy(nir_alu_instr *instr)
{
assert(instr->src[0].src.is_ssa);
if (instr->op == nir_op_mov) {
return !instr->dest.saturate &&
!instr->src[0].abs &&
!instr->src[0].negate;
} else if (nir_op_is_vec(instr->op)) {
for (unsigned i = 0; i < instr->dest.dest.ssa.num_components; i++) {
if (instr->src[i].abs || instr->src[i].negate)
return false;
}
return !instr->dest.saturate;
} else {
return false;
}
}
nir_ssa_scalar
nir_ssa_scalar_chase_movs(nir_ssa_scalar s)
{
while (nir_ssa_scalar_is_alu(s)) {
nir_alu_instr *alu = nir_instr_as_alu(s.def->parent_instr);
if (!nir_alu_instr_is_copy(alu))
break;
if (alu->op == nir_op_mov) {
s.def = alu->src[0].src.ssa;
s.comp = alu->src[0].swizzle[s.comp];
} else {
assert(nir_op_is_vec(alu->op));
s.def = alu->src[s.comp].src.ssa;
s.comp = alu->src[s.comp].swizzle[0];
}
}
return s;
}

View file

@ -1457,6 +1457,8 @@ void nir_alu_src_copy(nir_alu_src *dest, const nir_alu_src *src,
void nir_alu_dest_copy(nir_alu_dest *dest, const nir_alu_dest *src,
nir_alu_instr *instr);
bool nir_alu_instr_is_copy(nir_alu_instr *instr);
/* is this source channel used? */
static inline bool
nir_alu_instr_channel_used(const nir_alu_instr *instr, unsigned src,
@ -2614,6 +2616,16 @@ nir_ssa_scalar_chase_alu_src(nir_ssa_scalar s, unsigned alu_src_idx)
return out;
}
nir_ssa_scalar nir_ssa_scalar_chase_movs(nir_ssa_scalar s);
/** Returns a nir_ssa_scalar where we've followed the bit-exact mov/vec use chain to the original definition */
static inline nir_ssa_scalar
nir_ssa_scalar_resolved(nir_ssa_def *def, unsigned channel)
{
nir_ssa_scalar s = { def, channel };
return nir_ssa_scalar_chase_movs(s);
}
typedef struct {
bool success;

View file

@ -56,27 +56,6 @@ is_swizzleless_move(nir_alu_instr *instr)
return true;
}
static bool
is_copy(nir_alu_instr *instr)
{
assert(instr->src[0].src.is_ssa);
/* we handle modifiers in a separate pass */
if (instr->op == nir_op_mov) {
return !instr->dest.saturate &&
!instr->src[0].abs &&
!instr->src[0].negate;
} else if (nir_op_is_vec(instr->op)) {
for (unsigned i = 0; i < instr->dest.dest.ssa.num_components; i++) {
if (instr->src[i].abs || instr->src[i].negate)
return false;
}
return !instr->dest.saturate;
} else {
return false;
}
}
static bool
rewrite_to_vec(nir_function_impl *impl, nir_alu_instr *mov, nir_alu_instr *vec)
{
@ -162,7 +141,7 @@ copy_prop_instr(nir_function_impl *impl, nir_instr *instr)
nir_alu_instr *mov = nir_instr_as_alu(instr);
if (!is_copy(mov))
if (!nir_alu_instr_is_copy(mov))
return false;
bool progress = false;