nir/deref: Add an alu-of-cast optimization

Casts shouldn't change the bit pattern of the deref and you have to cast
again after you're done with the ALU anyway so we can ignore casts on
ALU sources.  This means we can actually start constant folding NULL
checks even if there are annoying casts in the way.

Reviewed-by: Karol Herbst <kherbst@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15673>
This commit is contained in:
Jason Ekstrand
2022-03-30 10:57:19 -05:00
committed by Marge Bot
parent 7ab05e3c3f
commit c31db58f65

View File

@@ -851,6 +851,30 @@ nir_deref_instr_fixup_child_types(nir_deref_instr *parent)
}
}
static bool
opt_alu_of_cast(nir_alu_instr *alu)
{
bool progress = false;
for (unsigned i = 0; i < nir_op_infos[alu->op].num_inputs; i++) {
assert(alu->src[i].src.is_ssa);
nir_instr *src_instr = alu->src[i].src.ssa->parent_instr;
if (src_instr->type != nir_instr_type_deref)
continue;
nir_deref_instr *src_deref = nir_instr_as_deref(src_instr);
if (src_deref->deref_type != nir_deref_type_cast)
continue;
assert(src_deref->parent.is_ssa);
nir_instr_rewrite_src_ssa(&alu->instr, &alu->src[i].src,
src_deref->parent.ssa);
progress = true;
}
return progress;
}
static bool
is_trivial_array_deref_cast(nir_deref_instr *cast)
{
@@ -1347,6 +1371,13 @@ nir_opt_deref_impl(nir_function_impl *impl)
b.cursor = nir_before_instr(instr);
switch (instr->type) {
case nir_instr_type_alu: {
nir_alu_instr *alu = nir_instr_as_alu(instr);
if (opt_alu_of_cast(alu))
progress = true;
break;
}
case nir_instr_type_deref: {
nir_deref_instr *deref = nir_instr_as_deref(instr);