qregs[chan] = result;
} else {
nir_register *reg = dest->reg.reg;
- assert(dest->reg.base_offset == 0);
assert(reg->num_array_elems == 0);
struct hash_entry *entry =
_mesa_hash_table_search(c->def_ht, reg);
} else {
nir_register *reg = src.reg.reg;
assert(reg->num_array_elems == 0);
- assert(src.reg.base_offset == 0);
assert(i < reg->num_components);
if (_mesa_set_search(c->tmu.outstanding_regs, reg))
return func;
}
-static bool src_has_indirect(nir_src *src)
-{
- return !src->is_ssa && src->reg.indirect;
-}
-
-static void src_free_indirects(nir_src *src)
-{
- if (src_has_indirect(src)) {
- assert(src->reg.indirect->is_ssa || !src->reg.indirect->reg.indirect);
- gc_free(src->reg.indirect);
- src->reg.indirect = NULL;
- }
-}
-
-static void dest_free_indirects(nir_dest *dest)
-{
- if (!dest->is_ssa && dest->reg.indirect) {
- assert(dest->reg.indirect->is_ssa || !dest->reg.indirect->reg.indirect);
- gc_free(dest->reg.indirect);
- dest->reg.indirect = NULL;
- }
-}
-
static void
src_copy(nir_src *dest, const nir_src *src, gc_ctx *ctx)
{
- src_free_indirects(dest);
-
dest->is_ssa = src->is_ssa;
if (src->is_ssa) {
dest->ssa = src->ssa;
} else {
- dest->reg.base_offset = src->reg.base_offset;
dest->reg.reg = src->reg.reg;
- if (src->reg.indirect) {
- dest->reg.indirect = gc_zalloc(ctx, nir_src, 1);
- src_copy(dest->reg.indirect, src->reg.indirect, ctx);
- } else {
- dest->reg.indirect = NULL;
- }
}
}
/* Copying an SSA definition makes no sense whatsoever. */
assert(!src->is_ssa);
- dest_free_indirects(dest);
-
dest->is_ssa = false;
- dest->reg.base_offset = src->reg.base_offset;
dest->reg.reg = src->reg.reg;
- if (src->reg.indirect) {
- dest->reg.indirect = gc_zalloc(gc_get_context(instr), nir_src, 1);
- nir_src_copy(dest->reg.indirect, src->reg.indirect, instr);
- } else {
- dest->reg.indirect = NULL;
- }
}
void
{
src->is_ssa = false;
src->reg.reg = NULL;
- src->reg.indirect = NULL;
- src->reg.base_offset = 0;
}
nir_if *
{
dest->is_ssa = false;
dest->reg.reg = NULL;
- dest->reg.indirect = NULL;
- dest->reg.base_offset = 0;
}
static void
}
}
-static bool free_src_indirects_cb(nir_src *src, void *state)
-{
- src_free_indirects(src);
- return true;
-}
-
-static bool free_dest_indirects_cb(nir_dest *dest, void *state)
-{
- dest_free_indirects(dest);
- return true;
-}
-
void nir_instr_free(nir_instr *instr)
{
- nir_foreach_src(instr, free_src_indirects_cb, NULL);
- nir_foreach_dest(instr, free_dest_indirects_cb, NULL);
-
switch (instr->type) {
case nir_instr_type_tex:
gc_free(nir_instr_as_tex(instr)->src);
static void
src_remove_all_uses(nir_src *src)
{
- for (; src; src = src->is_ssa ? NULL : src->reg.indirect) {
- if (!src_is_valid(src))
- continue;
-
+ if (src && src_is_valid(src))
list_del(&src->use_link);
- }
}
static void
src_add_all_uses(nir_src *src, nir_instr *parent_instr, nir_if *parent_if)
{
- for (; src; src = src->is_ssa ? NULL : src->reg.indirect) {
- if (!src_is_valid(src))
- continue;
+ if (!src)
+ return;
- if (parent_instr) {
- nir_src_set_parent_instr(src, parent_instr);
- } else {
- assert(parent_if);
- nir_src_set_parent_if(src, parent_if);
- }
+ if (!src_is_valid(src))
+ return;
- if (src->is_ssa)
- list_addtail(&src->use_link, &src->ssa->uses);
- else
- list_addtail(&src->use_link, &src->reg.reg->uses);
+ if (parent_instr) {
+ nir_src_set_parent_instr(src, parent_instr);
+ } else {
+ assert(parent_if);
+ nir_src_set_parent_if(src, parent_if);
}
+
+ if (src->is_ssa)
+ list_addtail(&src->use_link, &src->ssa->uses);
+ else
+ list_addtail(&src->use_link, &src->reg.reg->uses);
}
void
assert(!src_is_valid(dest) || dest->parent_instr == dest_instr);
src_remove_all_uses(dest);
- src_free_indirects(dest);
src_remove_all_uses(src);
*dest = *src;
*src = NIR_SRC_INIT;
assert(nir_ssa_def_is_unused(&dest->ssa));
} else {
list_del(&dest->reg.def_link);
- if (dest->reg.indirect)
- src_remove_all_uses(dest->reg.indirect);
}
/* We can't re-write with an SSA def */
dest->reg.parent_instr = instr;
list_addtail(&dest->reg.def_link, &new_dest.reg.reg->defs);
-
- if (dest->reg.indirect)
- src_add_all_uses(dest->reg.indirect, instr, NULL);
}
void
typedef struct {
nir_register *reg;
- struct nir_src *indirect; /** < NULL for no indirect offset */
- unsigned base_offset;
} nir_register_src;
typedef struct {
struct list_head def_link;
nir_register *reg;
- struct nir_src *indirect; /** < NULL for no indirect offset */
- unsigned base_offset;
} nir_register_dest;
struct nir_if;
src.is_ssa = false;
src.reg.reg = reg;
- src.reg.indirect = NULL;
- src.reg.base_offset = 0;
return src;
}
nsrc->ssa = remap_local(state, src->ssa);
} else {
nsrc->reg.reg = remap_reg(state, src->reg.reg);
- if (src->reg.indirect) {
- nsrc->reg.indirect = gc_alloc(state->ns->gctx, nir_src, 1);
- __clone_src(state, ninstr_or_if, nsrc->reg.indirect, src->reg.indirect);
- }
- nsrc->reg.base_offset = src->reg.base_offset;
}
}
add_remap(state, &ndst->ssa, &dst->ssa);
} else {
ndst->reg.reg = remap_reg(state, dst->reg.reg);
- if (dst->reg.indirect) {
- ndst->reg.indirect = gc_alloc(state->ns->gctx, nir_src, 1);
- __clone_src(state, ninstr, ndst->reg.indirect, dst->reg.indirect);
- }
- ndst->reg.base_offset = dst->reg.base_offset;
}
}
static void
emit_copy(nir_builder *b, nir_src src, nir_src dest_src)
{
- assert(!dest_src.is_ssa &&
- dest_src.reg.indirect == NULL &&
- dest_src.reg.base_offset == 0);
-
+ assert(!dest_src.is_ssa);
assert(!nir_src_is_divergent(src) || nir_src_is_divergent(dest_src));
if (src.is_ssa)
{
if (!cb(src, state))
return false;
- if (!src->is_ssa && src->reg.indirect)
- return cb(src->reg.indirect, state);
- return true;
-}
-
-typedef struct {
- void *state;
- nir_foreach_src_cb cb;
-} _nir_visit_dest_indirect_state;
-
-static ALWAYS_INLINE bool
-_nir_visit_dest_indirect(nir_dest *dest, void *_state)
-{
- _nir_visit_dest_indirect_state *state = (_nir_visit_dest_indirect_state *) _state;
-
- if (!dest->is_ssa && dest->reg.indirect)
- return state->cb(dest->reg.indirect, state->state);
-
return true;
}
break;
}
- _nir_visit_dest_indirect_state dest_state;
- dest_state.state = state;
- dest_state.cb = cb;
- return _nir_foreach_dest(instr, _nir_visit_dest_indirect, &dest_state);
+ return true;
}
if (src2.is_ssa) {
return false;
} else {
- if ((src1.reg.indirect == NULL) != (src2.reg.indirect == NULL))
- return false;
-
- if (src1.reg.indirect) {
- if (!nir_srcs_equal(*src1.reg.indirect, *src2.reg.indirect))
- return false;
- }
-
- return src1.reg.reg == src2.reg.reg &&
- src1.reg.base_offset == src2.reg.base_offset;
+ return src1.reg.reg == src2.reg.reg;
}
}
}
if (dest->is_ssa || src->is_ssa)
return false;
- return (dest->reg.reg == src->reg.reg &&
- dest->reg.base_offset == src->reg.base_offset &&
- !dest->reg.indirect &&
- !src->reg.indirect);
+ return (dest->reg.reg == src->reg.reg);
}
/**
static void
print_reg_src(const nir_register_src *src, print_state *state)
{
- FILE *fp = state->fp;
print_register(src->reg, state);
- if (src->reg->num_array_elems != 0) {
- fprintf(fp, "[%u", src->base_offset);
- if (src->indirect != NULL) {
- fprintf(fp, " + ");
- print_src(src->indirect, state, nir_type_invalid);
- }
- fprintf(fp, "]");
- }
}
static void
count_digits(state->max_dest_index) - count_digits(dest->reg->index) : 0;
fprintf(fp, "%s %*sr%u", divergence_status(state, dest->reg->divergent),
padding, "", dest->reg->index);
-
- if (dest->reg->num_array_elems != 0) {
- fprintf(fp, "[%u", dest->base_offset);
- if (dest->indirect != NULL) {
- fprintf(fp, " + ");
- print_src(dest->indirect, state, nir_type_invalid);
- }
- fprintf(fp, "]");
- }
}
static void
blob_write_uint32(ctx->blob, header.u32);
} else {
header.any.object_idx = write_lookup_object(ctx, src->reg.reg);
- header.any.is_indirect = !!src->reg.indirect;
+ header.any.is_indirect = false;
blob_write_uint32(ctx->blob, header.u32);
- blob_write_uint32(ctx->blob, src->reg.base_offset);
- if (src->reg.indirect) {
- union packed_src header = {0};
- write_src_full(ctx, src->reg.indirect, header);
- }
}
}
src->ssa = read_lookup_object(ctx, header.any.object_idx);
} else {
src->reg.reg = read_lookup_object(ctx, header.any.object_idx);
- src->reg.base_offset = blob_read_uint32(ctx->blob);
- if (header.any.is_indirect) {
- src->reg.indirect = gc_alloc(ctx->nir->gctx, nir_src, 1);
- read_src(ctx, src->reg.indirect);
- } else {
- src->reg.indirect = NULL;
- }
}
return header;
}
} ssa;
struct {
uint8_t is_ssa:1;
- uint8_t is_indirect:1;
- uint8_t _pad:6;
+ uint8_t _pad:7;
} reg;
};
encode_num_components_in_3bits(dst->ssa.num_components);
dest.ssa.bit_size = encode_bit_size_3bits(dst->ssa.bit_size);
dest.ssa.divergent = dst->ssa.divergent;
- } else {
- dest.reg.is_indirect = !!(dst->reg.indirect);
}
header.any.dest = dest.u8;
write_add_object(ctx, &dst->ssa);
} else {
blob_write_uint32(ctx->blob, write_lookup_object(ctx, dst->reg.reg));
- blob_write_uint32(ctx->blob, dst->reg.base_offset);
- if (dst->reg.indirect)
- write_src(ctx, dst->reg.indirect);
}
}
read_add_object(ctx, &dst->ssa);
} else {
dst->reg.reg = read_object(ctx);
- dst->reg.base_offset = blob_read_uint32(ctx->blob);
- if (dest.reg.is_indirect) {
- dst->reg.indirect = gc_alloc(ctx->nir->gctx, nir_src, 1);
- read_src(ctx, dst->reg.indirect);
- }
}
}
static void sweep_cf_node(nir_shader *nir, nir_cf_node *cf_node);
-static bool
-sweep_src_indirect(nir_src *src, void *nir)
-{
- if (!src->is_ssa && src->reg.indirect)
- gc_mark_live(((nir_shader*)nir)->gctx, src->reg.indirect);
-
- return true;
-}
-
-static bool
-sweep_dest_indirect(nir_dest *dest, void *nir)
-{
- if (!dest->is_ssa && dest->reg.indirect)
- gc_mark_live(((nir_shader*)nir)->gctx, dest->reg.indirect);
-
- return true;
-}
-
static void
sweep_block(nir_shader *nir, nir_block *block)
{
default:
break;
}
-
- nir_foreach_src(instr, sweep_src_indirect, nir);
- nir_foreach_dest(instr, sweep_dest_indirect, nir);
}
}
validate_assert(state, src->reg.reg->bit_size & bit_sizes);
if (num_components)
validate_assert(state, src->reg.reg->num_components == num_components);
-
- validate_assert(state, (src->reg.reg->num_array_elems == 0 ||
- src->reg.base_offset < src->reg.reg->num_array_elems) &&
- "definitely out-of-bounds array access");
-
- if (src->reg.indirect) {
- validate_assert(state, src->reg.reg->num_array_elems != 0);
- validate_assert(state, (src->reg.indirect->is_ssa ||
- src->reg.indirect->reg.indirect == NULL) &&
- "only one level of indirection allowed");
- validate_src(src->reg.indirect, state, 32, 1);
- }
}
static void
validate_assert(state, dest->reg->bit_size & bit_sizes);
if (num_components)
validate_assert(state, dest->reg->num_components == num_components);
-
- validate_assert(state, (dest->reg->num_array_elems == 0 ||
- dest->base_offset < dest->reg->num_array_elems) &&
- "definitely out-of-bounds array access");
-
- if (dest->indirect) {
- validate_assert(state, dest->reg->num_array_elems != 0);
- validate_assert(state, (dest->indirect->is_ssa || dest->indirect->reg.indirect == NULL) &&
- "only one level of indirection allowed");
- validate_src(dest->indirect, state, 32, 1);
- }
}
static void
qregs[chan] = result;
} else {
nir_register *reg = dest->reg.reg;
- assert(dest->reg.base_offset == 0);
assert(reg->num_array_elems == 0);
struct hash_entry *entry =
_mesa_hash_table_search(c->def_ht, reg);
nir_register *reg = src.reg.reg;
entry = _mesa_hash_table_search(c->def_ht, reg);
assert(reg->num_array_elems == 0);
- assert(src.reg.base_offset == 0);
assert(i < reg->num_components);
}