Commit 23b28855 authored by Daniel Schürmann's avatar Daniel Schürmann Committed by Marge Bot
Browse files

nir/opt_vectorize: don't hash instructions which are already vectorized



This guarantees that the hashset contains exactly the instructions
which can be vectorized.
Reviewed-by: Connor Abbott's avatarConnor Abbott <cwabbott0@gmail.com>
Part-of: <mesa/mesa!6666>
parent ad37e4df
......@@ -49,32 +49,21 @@ hash_alu_src(uint32_t hash, const nir_alu_src *src)
}
static uint32_t
hash_alu(uint32_t hash, const nir_alu_instr *instr)
hash_instr(const void *data)
{
hash = HASH(hash, instr->op);
const nir_instr *instr = (nir_instr *) data;
assert(instr->type == nir_instr_type_alu);
nir_alu_instr *alu = nir_instr_as_alu(instr);
hash = HASH(hash, instr->dest.dest.ssa.bit_size);
uint32_t hash = HASH(0, alu->op);
hash = HASH(hash, alu->dest.dest.ssa.bit_size);
for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++)
hash = hash_alu_src(hash, &instr->src[i]);
for (unsigned i = 0; i < nir_op_infos[alu->op].num_inputs; i++)
hash = hash_alu_src(hash, &alu->src[i]);
return hash;
}
static uint32_t
hash_instr(const void *data)
{
const nir_instr *instr = (nir_instr *) data;
uint32_t hash = 0;
switch (instr->type) {
case nir_instr_type_alu:
return hash_alu(hash, nir_instr_as_alu(instr));
default:
unreachable("bad instruction type");
}
}
static bool
srcs_equal(const nir_src *src1, const nir_src *src2)
{
......@@ -101,32 +90,28 @@ instrs_equal(const void *data1, const void *data2)
{
const nir_instr *instr1 = (nir_instr *) data1;
const nir_instr *instr2 = (nir_instr *) data2;
switch (instr1->type) {
case nir_instr_type_alu: {
nir_alu_instr *alu1 = nir_instr_as_alu(instr1);
nir_alu_instr *alu2 = nir_instr_as_alu(instr2);
assert(instr1->type == nir_instr_type_alu);
assert(instr2->type == nir_instr_type_alu);
if (alu1->op != alu2->op)
return false;
nir_alu_instr *alu1 = nir_instr_as_alu(instr1);
nir_alu_instr *alu2 = nir_instr_as_alu(instr2);
if (alu1->dest.dest.ssa.bit_size != alu2->dest.dest.ssa.bit_size)
return false;
if (alu1->op != alu2->op)
return false;
for (unsigned i = 0; i < nir_op_infos[alu1->op].num_inputs; i++) {
if (!alu_srcs_equal(&alu1->src[i], &alu2->src[i]))
return false;
}
if (alu1->dest.dest.ssa.bit_size != alu2->dest.dest.ssa.bit_size)
return false;
return true;
for (unsigned i = 0; i < nir_op_infos[alu1->op].num_inputs; i++) {
if (!alu_srcs_equal(&alu1->src[i], &alu2->src[i]))
return false;
}
default:
unreachable("bad instruction type");
}
return true;
}
static bool
instr_can_rewrite(nir_instr *instr)
instr_can_rewrite(nir_instr *instr, bool vectorize_16bit)
{
switch (instr->type) {
case nir_instr_type_alu: {
......@@ -139,6 +124,15 @@ instr_can_rewrite(nir_instr *instr)
if (alu->op == nir_op_mov)
return false;
/* no need to hash instructions which are already vectorized */
if (alu->dest.dest.ssa.num_components >= 4)
return false;
if (vectorize_16bit &&
(alu->dest.dest.ssa.num_components >= 2 ||
alu->dest.dest.ssa.bit_size != 16))
return false;
if (nir_op_infos[alu->op].output_size != 0)
return false;
......@@ -181,9 +175,10 @@ instr_try_combine(struct nir_shader *nir, nir_instr *instr1, nir_instr *instr2,
if (total_components > 4)
return NULL;
if (nir->options->vectorize_vec2_16bit &&
(total_components > 2 || alu1->dest.dest.ssa.bit_size != 16))
return NULL;
if (nir->options->vectorize_vec2_16bit) {
assert(total_components == 2);
assert(alu1->dest.dest.ssa.bit_size == 16);
}
if (filter && !filter(&alu1->instr, &alu2->instr, data))
return NULL;
......@@ -335,7 +330,7 @@ vec_instr_set_add_or_rewrite(struct nir_shader *nir, struct set *instr_set,
nir_instr *instr,
nir_opt_vectorize_cb filter, void *data)
{
if (!instr_can_rewrite(instr))
if (!instr_can_rewrite(instr, nir->options->vectorize_vec2_16bit))
return false;
struct set_entry *entry = _mesa_set_search(instr_set, instr);
......@@ -345,7 +340,8 @@ vec_instr_set_add_or_rewrite(struct nir_shader *nir, struct set *instr_set,
nir_instr *new_instr = instr_try_combine(nir, old_instr, instr,
filter, data);
if (new_instr) {
_mesa_set_add(instr_set, new_instr);
if (instr_can_rewrite(new_instr, nir->options->vectorize_vec2_16bit))
_mesa_set_add(instr_set, new_instr);
return true;
}
}
......@@ -372,12 +368,8 @@ vectorize_block(struct nir_shader *nir, nir_block *block,
}
nir_foreach_instr_reverse(instr, block) {
if (instr->type != nir_instr_type_alu)
continue;
struct set_entry *entry = _mesa_set_search(instr_set, instr);
if (entry)
_mesa_set_remove(instr_set, entry);
if (instr_can_rewrite(instr, nir->options->vectorize_vec2_16bit))
_mesa_set_remove_key(instr_set, instr);
}
return progress;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment