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>
This commit is contained in:
Jason Ekstrand
2018-03-14 21:45:38 -07:00
parent 5fbbbda37a
commit 19a4662a54
9 changed files with 580 additions and 13 deletions

View File

@@ -98,6 +98,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++) {