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;
+}
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,
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;
}
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)
{
if (mov->op != nir_op_mov)
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;