From 3a5cb40c1fc737a4c0372526003bd31e16757ba5 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Wed, 27 Mar 2024 15:03:20 -0400 Subject: [PATCH] ir3: Allow collect sources to be undef Undef collect sources will never have a move materialized for them. Part-of: --- src/freedreno/ir3/ir3_context.c | 24 ++++++++++++++++++---- src/freedreno/ir3/ir3_lower_parallelcopy.c | 15 ++++++++------ src/freedreno/ir3/ir3_merge_regs.c | 3 ++- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/freedreno/ir3/ir3_context.c b/src/freedreno/ir3/ir3_context.c index f266a353900..2304b5a969d 100644 --- a/src/freedreno/ir3/ir3_context.c +++ b/src/freedreno/ir3/ir3_context.c @@ -322,7 +322,19 @@ ir3_create_collect(struct ir3_builder *build, if (arrsz == 1) return arr[0]; - unsigned flags = dest_flags(arr[0]); + int non_undef_src = -1; + for (unsigned i = 0; i < arrsz; i++) { + if (arr[i]) { + non_undef_src = i; + break; + } + } + + /* There should be at least one non-undef source to determine the type of the + * destination. + */ + assert(non_undef_src != -1); + unsigned flags = dest_flags(arr[non_undef_src]); collect = ir3_build_instr(build, OPC_META_COLLECT, 1, arrsz); __ssa_dst(collect)->flags |= flags; @@ -353,13 +365,17 @@ ir3_create_collect(struct ir3_builder *build, * scalar registers. * */ - if (elem->dsts[0]->flags & IR3_REG_ARRAY) { + if (elem && elem->dsts[0]->flags & IR3_REG_ARRAY) { type_t type = (flags & IR3_REG_HALF) ? TYPE_U16 : TYPE_U32; elem = ir3_MOV(build, elem, type); } - assert(dest_flags(elem) == flags); - __ssa_src(collect, elem, flags); + if (elem) { + assert(dest_flags(elem) == flags); + __ssa_src(collect, elem, flags); + } else { + ir3_src_create(collect, INVALID_REG, flags | IR3_REG_SSA); + } } collect->dsts[0]->wrmask = MASK(arrsz); diff --git a/src/freedreno/ir3/ir3_lower_parallelcopy.c b/src/freedreno/ir3/ir3_lower_parallelcopy.c index 61cc6d65d50..d354b262f0c 100644 --- a/src/freedreno/ir3/ir3_lower_parallelcopy.c +++ b/src/freedreno/ir3/ir3_lower_parallelcopy.c @@ -520,12 +520,15 @@ ir3_lower_copies(struct ir3_shader_variant *v) unsigned flags = dst->flags & (IR3_REG_HALF | IR3_REG_SHARED); for (unsigned i = 0; i < instr->srcs_count; i++) { struct ir3_register *src = instr->srcs[i]; - array_insert(NULL, copies, - (struct copy_entry){ - .dst = ra_num_to_physreg(dst->num + i, flags), - .src = get_copy_src(src, 0), - .flags = flags, - }); + if ((src->flags & (IR3_REG_CONST | IR3_REG_IMMED)) || + src->num != INVALID_REG) { + array_insert(NULL, copies, + (struct copy_entry){ + .dst = ra_num_to_physreg(dst->num + i, flags), + .src = get_copy_src(src, 0), + .flags = flags, + }); + } } handle_copies(v, instr, copies, copies_count); list_del(&instr->node); diff --git a/src/freedreno/ir3/ir3_merge_regs.c b/src/freedreno/ir3/ir3_merge_regs.c index b672b8e724e..0eb6fe65325 100644 --- a/src/freedreno/ir3/ir3_merge_regs.c +++ b/src/freedreno/ir3/ir3_merge_regs.c @@ -377,7 +377,8 @@ aggressive_coalesce_collect(struct ir3_liveness *live, { for (unsigned i = 0, offset = 0; i < collect->srcs_count; offset += reg_elem_size(collect->srcs[i]), i++) { - if (!(collect->srcs[i]->flags & IR3_REG_SSA)) + if (!(collect->srcs[i]->flags & IR3_REG_SSA) || + !collect->srcs[i]->def) continue; try_merge_defs(live, collect->dsts[0], collect->srcs[i]->def, offset); }