nir_ssa_def *resource;
nir_variable *var;
unsigned offset_def_count;
- nir_ssa_def **offset_defs;
+ nir_ssa_scalar *offset_defs;
uint64_t *offset_defs_mul;
};
hash = XXH32(&mode, sizeof(mode), hash);
}
- for (unsigned i = 0; i < key->offset_def_count; i++)
- hash = XXH32(&key->offset_defs[i]->index, sizeof(key->offset_defs[i]->index), hash);
+ for (unsigned i = 0; i < key->offset_def_count; i++) {
+ hash = XXH32(&key->offset_defs[i].def->index, sizeof(key->offset_defs[i].def->index), hash);
+ hash = XXH32(&key->offset_defs[i].comp, sizeof(key->offset_defs[i].comp), hash);
+ }
hash = XXH32(key->offset_defs_mul, key->offset_def_count * sizeof(uint64_t), hash);
if (a->offset_def_count != b->offset_def_count)
return false;
- size_t offset_def_size = a->offset_def_count * sizeof(nir_ssa_def *);
+ for (unsigned i = 0; i < a->offset_def_count; i++) {
+ if (a->offset_defs[i].def != b->offset_defs[i].def ||
+ a->offset_defs[i].comp != b->offset_defs[i].comp)
+ return false;
+ }
+
size_t offset_def_mul_size = a->offset_def_count * sizeof(uint64_t);
if (a->offset_def_count &&
- (memcmp(a->offset_defs, b->offset_defs, offset_def_size) ||
- memcmp(a->offset_defs_mul, b->offset_defs_mul, offset_def_mul_size)))
+ memcmp(a->offset_defs_mul, b->offset_defs_mul, offset_def_mul_size))
return false;
return true;
* sources is a constant, update "def" to be the non-constant source, fill "c"
* with the constant and return true. */
static bool
-parse_alu(nir_ssa_def **def, nir_op op, uint64_t *c)
+parse_alu(nir_ssa_scalar *def, nir_op op, uint64_t *c)
{
- nir_ssa_scalar scalar;
- scalar.def = *def;
- scalar.comp = 0;
-
- if (!nir_ssa_scalar_is_alu(scalar) || nir_ssa_scalar_alu_op(scalar) != op)
+ if (!nir_ssa_scalar_is_alu(*def) || nir_ssa_scalar_alu_op(*def) != op)
return false;
- nir_ssa_scalar src0 = nir_ssa_scalar_chase_alu_src(scalar, 0);
- nir_ssa_scalar src1 = nir_ssa_scalar_chase_alu_src(scalar, 1);
- if (op != nir_op_ishl && nir_ssa_scalar_is_const(src0) && src1.comp == 0) {
+ nir_ssa_scalar src0 = nir_ssa_scalar_chase_alu_src(*def, 0);
+ nir_ssa_scalar src1 = nir_ssa_scalar_chase_alu_src(*def, 1);
+ if (op != nir_op_ishl && nir_ssa_scalar_is_const(src0)) {
*c = nir_ssa_scalar_as_uint(src0);
- *def = src1.def;
- } else if (nir_ssa_scalar_is_const(src1) && src0.comp == 0) {
+ *def = src1;
+ } else if (nir_ssa_scalar_is_const(src1)) {
*c = nir_ssa_scalar_as_uint(src1);
- *def = src0.def;
+ *def = src0;
} else {
return false;
}
/* Parses an offset expression such as "a * 16 + 4" and "(a * 16 + 4) * 64 + 32". */
static void
-parse_offset(nir_ssa_def **base, uint64_t *base_mul, uint64_t *offset)
+parse_offset(nir_ssa_scalar *base, uint64_t *base_mul, uint64_t *offset)
{
- if ((*base)->parent_instr->type == nir_instr_type_load_const) {
- *offset = nir_src_comp_as_uint(nir_src_for_ssa(*base), 0);
- *base = NULL;
+ if (nir_ssa_scalar_is_const(*base)) {
+ *offset = nir_ssa_scalar_as_uint(*base);
+ base->def = NULL;
return;
}
progress |= parse_alu(base, nir_op_iadd, &add2);
add += add2 * mul;
+
+ if (nir_ssa_scalar_is_alu(*base) && nir_ssa_scalar_alu_op(*base) == nir_op_mov) {
+ *base = nir_ssa_scalar_chase_alu_src(*base, 0);
+ progress = true;
+ }
} while (progress);
*base_mul = mul;
}
static unsigned
-add_to_entry_key(nir_ssa_def **offset_defs, uint64_t *offset_defs_mul,
- unsigned offset_def_count, nir_ssa_def *def, uint64_t mul)
+add_to_entry_key(nir_ssa_scalar *offset_defs, uint64_t *offset_defs_mul,
+ unsigned offset_def_count, nir_ssa_scalar def, uint64_t mul)
{
- mul = mask_sign_extend(mul, def->bit_size);
+ mul = mask_sign_extend(mul, def.def->bit_size);
for (unsigned i = 0; i <= offset_def_count; i++) {
- if (i == offset_def_count || def->index > offset_defs[i]->index) {
+ if (i == offset_def_count || def.def->index > offset_defs[i].def->index) {
/* insert before i */
memmove(offset_defs + i + 1, offset_defs + i,
- (offset_def_count - i) * sizeof(nir_ssa_def *));
+ (offset_def_count - i) * sizeof(nir_ssa_scalar));
memmove(offset_defs_mul + i + 1, offset_defs_mul + i,
(offset_def_count - i) * sizeof(uint64_t));
offset_defs[i] = def;
offset_defs_mul[i] = mul;
return 1;
- } else if (def->index == offset_defs[i]->index) {
+ } else if (def.def == offset_defs[i].def &&
+ def.comp == offset_defs[i].comp) {
/* merge with offset_def at i */
offset_defs_mul[i] += mul;
return 0;
while (path->path[path_len])
path_len++;
- nir_ssa_def *offset_defs_stack[32];
+ nir_ssa_scalar offset_defs_stack[32];
uint64_t offset_defs_mul_stack[32];
- nir_ssa_def **offset_defs = offset_defs_stack;
+ nir_ssa_scalar *offset_defs = offset_defs_stack;
uint64_t *offset_defs_mul = offset_defs_mul_stack;
if (path_len > 32) {
- offset_defs = malloc(path_len * sizeof(nir_ssa_def *));
+ offset_defs = malloc(path_len * sizeof(nir_ssa_scalar));
offset_defs_mul = malloc(path_len * sizeof(uint64_t));
}
unsigned offset_def_count = 0;
nir_ssa_def *index = deref->arr.index.ssa;
uint32_t stride = nir_deref_instr_array_stride(deref);
- nir_ssa_def *base = index;
+ nir_ssa_scalar base = {.def=index, .comp=0};
uint64_t offset = 0, base_mul = 1;
parse_offset(&base, &base_mul, &offset);
offset = mask_sign_extend(offset, index->bit_size);
*offset_base += offset * stride;
- if (base) {
+ if (base.def) {
offset_def_count += add_to_entry_key(offset_defs, offset_defs_mul,
offset_def_count,
base, base_mul * stride);
}
key->offset_def_count = offset_def_count;
- key->offset_defs = ralloc_array(mem_ctx, nir_ssa_def *, offset_def_count);
+ key->offset_defs = ralloc_array(mem_ctx, nir_ssa_scalar, offset_def_count);
key->offset_defs_mul = ralloc_array(mem_ctx, uint64_t, offset_def_count);
- memcpy(key->offset_defs, offset_defs, offset_def_count * sizeof(nir_ssa_def *));
+ memcpy(key->offset_defs, offset_defs, offset_def_count * sizeof(nir_ssa_scalar));
memcpy(key->offset_defs_mul, offset_defs_mul, offset_def_count * sizeof(uint64_t));
if (offset_defs != offset_defs_stack)
static unsigned
parse_entry_key_from_offset(struct entry_key *key, unsigned size, unsigned left,
- nir_ssa_def *base, uint64_t base_mul, uint64_t *offset)
+ nir_ssa_scalar base, uint64_t base_mul, uint64_t *offset)
{
uint64_t new_mul;
uint64_t new_offset;
parse_offset(&base, &new_mul, &new_offset);
*offset += new_offset * base_mul;
- if (!base)
+ if (!base.def)
return 0;
base_mul *= new_mul;
assert(left >= 1);
if (left >= 2) {
- nir_ssa_scalar scalar;
- scalar.def = base;
- scalar.comp = 0;
- if (nir_ssa_scalar_is_alu(scalar) && nir_ssa_scalar_alu_op(scalar) == nir_op_iadd) {
- nir_ssa_scalar src0 = nir_ssa_scalar_chase_alu_src(scalar, 0);
- nir_ssa_scalar src1 = nir_ssa_scalar_chase_alu_src(scalar, 1);
- if (src0.comp == 0 && src1.comp == 0) {
- unsigned amount = parse_entry_key_from_offset(key, size, left - 1, src0.def, base_mul, offset);
- amount += parse_entry_key_from_offset(key, size + amount, left - amount, src1.def, base_mul, offset);
+ if (nir_ssa_scalar_is_alu(base) && nir_ssa_scalar_alu_op(base) == nir_op_iadd) {
+ nir_ssa_scalar src0 = nir_ssa_scalar_chase_alu_src(base, 0);
+ nir_ssa_scalar src1 = nir_ssa_scalar_chase_alu_src(base, 1);
+ unsigned amount = parse_entry_key_from_offset(key, size, left - 1, src0, base_mul, offset);
+ amount += parse_entry_key_from_offset(key, size + amount, left - amount, src1, base_mul, offset);
return amount;
}
}
- }
return add_to_entry_key(key->offset_defs, key->offset_defs_mul, size, base, base_mul);
}
key->resource = NULL;
key->var = NULL;
if (base) {
- nir_ssa_def *offset_defs[32];
+ nir_ssa_scalar offset_defs[32];
uint64_t offset_defs_mul[32];
key->offset_defs = offset_defs;
key->offset_defs_mul = offset_defs_mul;
- key->offset_def_count = parse_entry_key_from_offset(key, 0, 32, base, base_mul, offset);
+ nir_ssa_scalar scalar = {.def=base, .comp=0};
+ key->offset_def_count = parse_entry_key_from_offset(key, 0, 32, scalar, base_mul, offset);
- key->offset_defs = ralloc_array(mem_ctx, nir_ssa_def *, key->offset_def_count);
+ key->offset_defs = ralloc_array(mem_ctx, nir_ssa_scalar, key->offset_def_count);
key->offset_defs_mul = ralloc_array(mem_ctx, uint64_t, key->offset_def_count);
- memcpy(key->offset_defs, offset_defs, key->offset_def_count * sizeof(nir_ssa_def *));
+ memcpy(key->offset_defs, offset_defs, key->offset_def_count * sizeof(nir_ssa_scalar));
memcpy(key->offset_defs_mul, offset_defs_mul, key->offset_def_count * sizeof(uint64_t));
} else {
key->offset_def_count = 0;