agx: Dynamically allocate agx_instr->src

Required for phi nodes.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16268>
This commit is contained in:
Alyssa Rosenzweig 2022-04-12 21:29:18 -04:00
parent d39b1c3426
commit bb1fb0a9db
5 changed files with 28 additions and 9 deletions

View File

@ -65,9 +65,14 @@ agx_${opcode}${suffix}(agx_builder *b
I->dest[${dest}] = dst${dest};
% endfor
% if srcs > 0:
I->src = ralloc_array(I, agx_index, ${srcs});
I->nr_srcs = ${srcs};
% for src in range(srcs):
I->src[${src}] = src${src};
% endfor
% endif
% for imm in imms:
I->${imm.name} = ${imm.name};

View File

@ -285,12 +285,14 @@ struct agx_block;
typedef struct {
/* Must be first */
struct list_head link;
agx_index *src;
enum agx_opcode op;
/* Data flow */
agx_index dest[AGX_MAX_DESTS];
agx_index src[AGX_MAX_SRCS];
unsigned nr_srcs;
union {
uint32_t imm;
@ -531,7 +533,7 @@ agx_dest_index(nir_dest *dst)
v = (agx_block *) (_entry_##v ? _entry_##v->key : NULL))
#define agx_foreach_src(ins, v) \
for (unsigned v = 0; v < ARRAY_SIZE(ins->src); ++v)
for (unsigned v = 0; v < ins->nr_srcs; ++v)
#define agx_foreach_dest(ins, v) \
for (unsigned v = 0; v < ARRAY_SIZE(ins->dest); ++v)

View File

@ -30,8 +30,11 @@ static void
agx_lower_to_unary_bitop(agx_instr *I, enum agx_bitop_table table)
{
I->op = AGX_OPCODE_BITOP;
I->src[1] = agx_zero();
I->truth_table = table;
/* Allocate extra source */
I->src = reralloc_array_size(I, I->src, sizeof(agx_index), I->nr_srcs++);
I->src[1] = agx_zero();
}
static void

View File

@ -124,7 +124,7 @@ agx_print_instr(agx_instr *I, FILE *fp)
agx_print_index(I->dest[d], fp);
}
for (unsigned s = 0; s < info.nr_srcs; ++s) {
for (unsigned s = 0; s < I->nr_srcs; ++s) {
if (print_comma)
fprintf(fp, ", ");
else

View File

@ -55,14 +55,23 @@ agx_test_builder(void *memctx)
return b;
}
/* Helper to compare for logical equality of instructions. Need to skip over
* the link, guaranteed to be first. After that we can compare raw data. */
/* Helper to compare for logical equality of instructions. Need to compare the
* pointers, then compare raw data.
*/
static inline bool
agx_instr_equal(agx_instr *A, agx_instr *B)
{
return memcmp((uint8_t *) A + sizeof(struct list_head),
(uint8_t *) B + sizeof(struct list_head),
sizeof(agx_instr) - sizeof(struct list_head)) == 0;
unsigned pointers = sizeof(struct list_head) + sizeof(agx_index *);
if (A->nr_srcs != B->nr_srcs)
return false;
if (memcmp(A->src, B->src, A->nr_srcs * sizeof(agx_index)))
return false;
return memcmp((uint8_t *) A + pointers,
(uint8_t *) B + pointers,
sizeof(agx_instr) - pointers) == 0;
}
static inline bool