util: Include bitscan.h directly
[mesa.git] / src / compiler / nir / nir_instr_set.c
index eb021326097fbd3ef89a21565a2dbd6699226633..9cb9ed43e8b39cf6545fd4a7e2585e8d231bc28f 100644 (file)
@@ -52,6 +52,8 @@ hash_alu(uint32_t hash, const nir_alu_instr *instr)
 {
    hash = HASH(hash, instr->op);
    hash = HASH(hash, instr->dest.dest.ssa.num_components);
+   hash = HASH(hash, instr->dest.dest.ssa.bit_size);
+   /* We explicitly don't hash instr->dest.dest.exact */
 
    if (nir_op_infos[instr->op].algebraic_properties & NIR_OP_IS_COMMUTATIVE) {
       assert(nir_op_infos[instr->op].num_inputs == 2);
@@ -81,9 +83,8 @@ hash_load_const(uint32_t hash, const nir_load_const_instr *instr)
 {
    hash = HASH(hash, instr->def.num_components);
 
-   hash = _mesa_fnv32_1a_accumulate_block(hash, instr->value.f,
-                                          instr->def.num_components
-                                             * sizeof(instr->value.f[0]));
+   unsigned size = instr->def.num_components * (instr->def.bit_size / 8);
+   hash = _mesa_fnv32_1a_accumulate_block(hash, instr->value.f32, size);
 
    return hash;
 }
@@ -105,7 +106,7 @@ hash_phi(uint32_t hash, const nir_phi_instr *instr)
    unsigned num_preds = instr->instr.block->predecessors->entries;
    NIR_VLA(nir_phi_src *, srcs, num_preds);
    unsigned i = 0;
-   nir_foreach_phi_src(instr, src) {
+   nir_foreach_phi_src(src, instr) {
       srcs[i++] = src;
    }
 
@@ -125,8 +126,10 @@ hash_intrinsic(uint32_t hash, const nir_intrinsic_instr *instr)
    const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic];
    hash = HASH(hash, instr->intrinsic);
 
-   if (info->has_dest)
+   if (info->has_dest) {
       hash = HASH(hash, instr->dest.ssa.num_components);
+      hash = HASH(hash, instr->dest.ssa.bit_size);
+   }
 
    assert(info->num_variables == 0);
 
@@ -152,14 +155,13 @@ hash_tex(uint32_t hash, const nir_tex_instr *instr)
    hash = HASH(hash, instr->is_array);
    hash = HASH(hash, instr->is_shadow);
    hash = HASH(hash, instr->is_new_style_shadow);
-   hash = HASH(hash, instr->const_offset);
    unsigned component = instr->component;
    hash = HASH(hash, component);
    hash = HASH(hash, instr->texture_index);
    hash = HASH(hash, instr->texture_array_size);
    hash = HASH(hash, instr->sampler_index);
 
-   assert(!instr->sampler);
+   assert(!instr->texture && !instr->sampler);
 
    return hash;
 }
@@ -226,7 +228,7 @@ nir_srcs_equal(nir_src src1, nir_src src2)
    }
 }
 
-static bool
+bool
 nir_alu_srcs_equal(const nir_alu_instr *alu1, const nir_alu_instr *alu2,
                    unsigned src1, unsigned src2)
 {
@@ -268,6 +270,11 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2)
       if (alu1->dest.dest.ssa.num_components != alu2->dest.dest.ssa.num_components)
          return false;
 
+      if (alu1->dest.dest.ssa.bit_size != alu2->dest.dest.ssa.bit_size)
+         return false;
+
+      /* We explicitly don't hash instr->dest.dest.exact */
+
       if (nir_op_infos[alu1->op].algebraic_properties & NIR_OP_IS_COMMUTATIVE) {
          assert(nir_op_infos[alu1->op].num_inputs == 2);
          return (nir_alu_srcs_equal(alu1, alu2, 0, 0) &&
@@ -303,8 +310,6 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2)
           tex1->is_array != tex2->is_array ||
           tex1->is_shadow != tex2->is_shadow ||
           tex1->is_new_style_shadow != tex2->is_new_style_shadow ||
-          memcmp(tex1->const_offset, tex2->const_offset,
-                 sizeof(tex1->const_offset)) != 0 ||
           tex1->component != tex2->component ||
          tex1->texture_index != tex2->texture_index ||
          tex1->texture_array_size != tex2->texture_array_size ||
@@ -325,8 +330,11 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2)
       if (load1->def.num_components != load2->def.num_components)
          return false;
 
-      return memcmp(load1->value.f, load2->value.f,
-                    load1->def.num_components * sizeof(*load2->value.f)) == 0;
+      if (load1->def.bit_size != load2->def.bit_size)
+         return false;
+
+      return memcmp(load1->value.f32, load2->value.f32,
+                    load1->def.num_components * (load1->def.bit_size / 8u)) == 0;
    }
    case nir_instr_type_phi: {
       nir_phi_instr *phi1 = nir_instr_as_phi(instr1);
@@ -335,8 +343,8 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2)
       if (phi1->instr.block != phi2->instr.block)
          return false;
 
-      nir_foreach_phi_src(phi1, src1) {
-         nir_foreach_phi_src(phi2, src2) {
+      nir_foreach_phi_src(src1, phi1) {
+         nir_foreach_phi_src(src2, phi2) {
             if (src1->pred == src2->pred) {
                if (!nir_srcs_equal(src1->src, src2->src))
                   return false;
@@ -362,6 +370,10 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2)
                             intrinsic2->dest.ssa.num_components)
          return false;
 
+      if (info->has_dest && intrinsic1->dest.ssa.bit_size !=
+                            intrinsic2->dest.ssa.bit_size)
+         return false;
+
       for (unsigned i = 0; i < info->num_srcs; i++) {
          if (!nir_srcs_equal(intrinsic1->src[i], intrinsic2->src[i]))
             return false;
@@ -499,8 +511,17 @@ nir_instr_set_add_or_rewrite(struct set *instr_set, nir_instr *instr)
    struct set_entry *entry = _mesa_set_search(instr_set, instr);
    if (entry) {
       nir_ssa_def *def = nir_instr_get_dest_ssa_def(instr);
-      nir_ssa_def *new_def =
-         nir_instr_get_dest_ssa_def((nir_instr *) entry->key);
+      nir_instr *match = (nir_instr *) entry->key;
+      nir_ssa_def *new_def = nir_instr_get_dest_ssa_def(match);
+
+      /* It's safe to replace an exact instruction with an inexact one as
+       * long as we make it exact.  If we got here, the two instructions are
+       * exactly identical in every other way so, once we've set the exact
+       * bit, they are the same.
+       */
+      if (instr->type == nir_instr_type_alu && nir_instr_as_alu(instr)->exact)
+         nir_instr_as_alu(match)->exact = true;
+
       nir_ssa_def_rewrite_uses(def, nir_src_for_ssa(new_def));
       return true;
    }