+static bool
+src_is_ssa(nir_src *src, void *data)
+{
+ (void) data;
+ return src->is_ssa;
+}
+
+static bool
+dest_is_ssa(nir_dest *dest, void *data)
+{
+ (void) data;
+ return dest->is_ssa;
+}
+
+static inline bool
+instr_each_src_and_dest_is_ssa(const nir_instr *instr)
+{
+ if (!nir_foreach_dest((nir_instr *)instr, dest_is_ssa, NULL) ||
+ !nir_foreach_src((nir_instr *)instr, src_is_ssa, NULL))
+ return false;
+
+ return true;
+}
+
+/* This function determines if uses of an instruction can safely be rewritten
+ * to use another identical instruction instead. Note that this function must
+ * be kept in sync with hash_instr() and nir_instrs_equal() -- only
+ * instructions that pass this test will be handed on to those functions, and
+ * conversely they must handle everything that this function returns true for.
+ */
+static bool
+instr_can_rewrite(const nir_instr *instr)
+{
+ /* We only handle SSA. */
+ assert(instr_each_src_and_dest_is_ssa(instr));
+
+ switch (instr->type) {
+ case nir_instr_type_alu:
+ case nir_instr_type_deref:
+ case nir_instr_type_tex:
+ case nir_instr_type_load_const:
+ case nir_instr_type_phi:
+ return true;
+ case nir_instr_type_intrinsic:
+ return nir_intrinsic_can_reorder(nir_instr_as_intrinsic(instr));
+ case nir_instr_type_call:
+ case nir_instr_type_jump:
+ case nir_instr_type_ssa_undef:
+ return false;
+ case nir_instr_type_parallel_copy:
+ default:
+ unreachable("Invalid instruction type");
+ }
+
+ return false;
+}
+
+