summaryrefslogtreecommitdiff
path: root/src/compiler/nir/nir_opt_copy_propagate.c
diff options
context:
space:
mode:
authorJason Ekstrand <jason.ekstrand@intel.com>2018-03-14 21:45:38 -0700
committerJason Ekstrand <jason.ekstrand@intel.com>2018-06-22 20:15:53 -0700
commit19a4662a540a8c940310a75f19bc8cd75be651e0 (patch)
treebe24fd16f6a4b55529b015442f709971938d44a8 /src/compiler/nir/nir_opt_copy_propagate.c
parent5fbbbda37a09e6d253532fd83097b21cd289c16b (diff)
downloadmesa-19a4662a540a8c940310a75f19bc8cd75be651e0.tar.gz
nir: Add a deref instruction type
This commit adds a new instruction type to NIR for handling derefs. Nothing uses it yet but this adds the data structure as well as all of the code to validate, print, clone, and [de]serialize them. Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com> Acked-by: Rob Clark <robdclark@gmail.com> Acked-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Acked-by: Dave Airlie <airlied@redhat.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Diffstat (limited to 'src/compiler/nir/nir_opt_copy_propagate.c')
-rw-r--r--src/compiler/nir/nir_opt_copy_propagate.c62
1 files changed, 52 insertions, 10 deletions
diff --git a/src/compiler/nir/nir_opt_copy_propagate.c b/src/compiler/nir/nir_opt_copy_propagate.c
index 3cd476a1b97..c8821c39e17 100644
--- a/src/compiler/nir/nir_opt_copy_propagate.c
+++ b/src/compiler/nir/nir_opt_copy_propagate.c
@@ -99,6 +99,22 @@ is_swizzleless_move(nir_alu_instr *instr)
}
static bool
+is_trivial_deref_cast(nir_deref_instr *cast)
+{
+ if (cast->deref_type != nir_deref_type_cast)
+ return false;
+
+ nir_deref_instr *parent = nir_src_as_deref(cast->parent);
+ if (!parent)
+ return false;
+
+ return cast->mode == parent->mode &&
+ cast->type == parent->type &&
+ cast->dest.ssa.num_components == parent->dest.ssa.num_components &&
+ cast->dest.ssa.bit_size == parent->dest.ssa.bit_size;
+}
+
+static bool
copy_prop_src(nir_src *src, nir_instr *parent_instr, nir_if *parent_if,
unsigned num_components)
{
@@ -109,23 +125,31 @@ copy_prop_src(nir_src *src, nir_instr *parent_instr, nir_if *parent_if,
}
nir_instr *src_instr = src->ssa->parent_instr;
- if (src_instr->type != nir_instr_type_alu)
- return false;
+ nir_ssa_def *copy_def;
+ if (src_instr->type == nir_instr_type_alu) {
+ nir_alu_instr *alu_instr = nir_instr_as_alu(src_instr);
+ if (!is_swizzleless_move(alu_instr))
+ return false;
- nir_alu_instr *alu_instr = nir_instr_as_alu(src_instr);
- if (!is_swizzleless_move(alu_instr))
- return false;
+ if (alu_instr->src[0].src.ssa->num_components != num_components)
+ return false;
- if (alu_instr->src[0].src.ssa->num_components != num_components)
+ copy_def= alu_instr->src[0].src.ssa;
+ } else if (src_instr->type == nir_instr_type_deref) {
+ nir_deref_instr *deref_instr = nir_instr_as_deref(src_instr);
+ if (!is_trivial_deref_cast(deref_instr))
+ return false;
+
+ copy_def = deref_instr->parent.ssa;
+ } else {
return false;
+ }
if (parent_instr) {
- nir_instr_rewrite_src(parent_instr, src,
- nir_src_for_ssa(alu_instr->src[0].src.ssa));
+ nir_instr_rewrite_src(parent_instr, src, nir_src_for_ssa(copy_def));
} else {
assert(src == &parent_if->condition);
- nir_if_rewrite_condition(parent_if,
- nir_src_for_ssa(alu_instr->src[0].src.ssa));
+ nir_if_rewrite_condition(parent_if, nir_src_for_ssa(copy_def));
}
return true;
@@ -234,6 +258,24 @@ copy_prop_instr(nir_instr *instr)
return progress;
}
+ case nir_instr_type_deref: {
+ nir_deref_instr *deref = nir_instr_as_deref(instr);
+
+ if (deref->deref_type != nir_deref_type_var) {
+ assert(deref->dest.is_ssa);
+ const unsigned comps = deref->dest.ssa.num_components;
+ while (copy_prop_src(&deref->parent, instr, NULL, comps))
+ progress = true;
+ }
+
+ if (deref->deref_type == nir_deref_type_array) {
+ while (copy_prop_src(&deref->arr.index, instr, NULL, 1))
+ progress = true;
+ }
+
+ return progress;
+ }
+
case nir_instr_type_tex: {
nir_tex_instr *tex = nir_instr_as_tex(instr);
for (unsigned i = 0; i < tex->num_srcs; i++) {