nir: Add a helper for rewriting an instruction source
authorJason Ekstrand <jason.ekstrand@intel.com>
Fri, 14 Nov 2014 03:07:22 +0000 (19:07 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Thu, 15 Jan 2015 15:19:01 +0000 (07:19 -0800)
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
src/glsl/nir/nir.c
src/glsl/nir/nir.h

index 20826b874e58d7e01758866228666f96b378ef86..e988ca4f248472818b112129951a383fb7b034e4 100644 (file)
@@ -1683,6 +1683,67 @@ nir_srcs_equal(nir_src src1, nir_src src2)
    }
 }
 
+static bool
+src_does_not_use_def(nir_src *src, void *void_def)
+{
+   nir_ssa_def *def = void_def;
+
+   if (src->is_ssa) {
+      return src->ssa != def;
+   } else {
+      return true;
+   }
+}
+
+static bool
+src_does_not_use_reg(nir_src *src, void *void_reg)
+{
+   nir_register *reg = void_reg;
+
+   if (src->is_ssa) {
+      return true;
+   } else {
+      return src->reg.reg != reg;
+   }
+}
+
+void
+nir_instr_rewrite_src(nir_instr *instr, nir_src *src, nir_src new_src)
+{
+   if (src->is_ssa) {
+      nir_ssa_def *old_ssa = src->ssa;
+      *src = new_src;
+      if (old_ssa && nir_foreach_src(instr, src_does_not_use_def, old_ssa)) {
+         struct set_entry *entry = _mesa_set_search(old_ssa->uses,
+                                                    _mesa_hash_pointer(instr),
+                                                    instr);
+         assert(entry);
+         _mesa_set_remove(old_ssa->uses, entry);
+      }
+   } else {
+      if (src->reg.indirect)
+         nir_instr_rewrite_src(instr, src->reg.indirect, new_src);
+
+      nir_register *old_reg = src->reg.reg;
+      *src = new_src;
+      if (old_reg && nir_foreach_src(instr, src_does_not_use_reg, old_reg)) {
+         struct set_entry *entry = _mesa_set_search(old_reg->uses,
+                                                    _mesa_hash_pointer(instr),
+                                                    instr);
+         assert(entry);
+         _mesa_set_remove(old_reg->uses, entry);
+      }
+   }
+
+   if (new_src.is_ssa) {
+      if (new_src.ssa)
+         _mesa_set_add(new_src.ssa->uses, _mesa_hash_pointer(instr), instr);
+   } else {
+      if (new_src.reg.reg)
+         _mesa_set_add(new_src.reg.reg->uses, _mesa_hash_pointer(instr), instr);
+   }
+}
+
 void
 nir_ssa_def_init(nir_function_impl *impl, nir_instr *instr, nir_ssa_def *def,
                  unsigned num_components, const char *name)
index 72dcb18d0cae621627d7a359b95685e2394094b6..6a872c508bd1bb291d24a178095757f739188bd3 100644 (file)
@@ -1302,6 +1302,7 @@ bool nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state);
 bool nir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state);
 
 bool nir_srcs_equal(nir_src src1, nir_src src2);
+void nir_instr_rewrite_src(nir_instr *instr, nir_src *src, nir_src new_src);
 
 void nir_ssa_def_init(nir_function_impl *impl, nir_instr *instr,
                       nir_ssa_def *def, unsigned num_components,