summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorConnor Abbott <cwabbott0@gmail.com>2021-06-18 16:23:46 +0200
committerMarge Bot <eric+marge@anholt.net>2021-06-23 17:20:29 +0000
commitaf48cfc06b69e1d322a533a8b467deebf6630484 (patch)
tree8ab6f61a152308ff5dfa459c942460ace5987f46 /src
parentd3e08327cf85ef0b07c8e4920c168329cf66ec41 (diff)
ir3/ra: Switch to srcs/dsts arrays
RA was manually fiddling with regs to copy over the parallel copy code, which has to be done in a different way, but if we switch this all over at once it shouldn't be a problem. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11469>
Diffstat (limited to 'src')
-rw-r--r--src/freedreno/ir3/ir3_liveness.c10
-rw-r--r--src/freedreno/ir3/ir3_lower_parallelcopy.c22
-rw-r--r--src/freedreno/ir3/ir3_merge_regs.c61
-rw-r--r--src/freedreno/ir3/ir3_ra.c107
-rw-r--r--src/freedreno/ir3/ir3_ra.h18
-rw-r--r--src/freedreno/ir3/ir3_ra_validate.c41
-rw-r--r--src/freedreno/ir3/ir3_spill.c24
7 files changed, 143 insertions, 140 deletions
diff --git a/src/freedreno/ir3/ir3_liveness.c b/src/freedreno/ir3/ir3_liveness.c
index 02abb0f3aa4..4285c7dc7cf 100644
--- a/src/freedreno/ir3/ir3_liveness.c
+++ b/src/freedreno/ir3/ir3_liveness.c
@@ -87,9 +87,9 @@ compute_block_liveness(struct ir3_liveness *live, struct ir3_block *block,
foreach_instr (phi, &block->instr_list) {
if (phi->opc != OPC_META_PHI)
break;
- if (!phi->regs[1 + i]->def)
+ if (!phi->srcs[i]->def)
continue;
- unsigned name = phi->regs[1 + i]->def->name;
+ unsigned name = phi->srcs[i]->def->name;
if (!BITSET_TEST(live->live_out[pred->index], name)) {
progress = true;
BITSET_SET(live->live_out[pred->index], name);
@@ -171,10 +171,8 @@ ir3_def_live_after(struct ir3_liveness *live, struct ir3_register *def,
if (test_instr == instr)
break;
- for (unsigned i = 0; i < test_instr->regs_count; i++) {
- if (test_instr->regs[i]->flags & IR3_REG_DEST)
- continue;
- if (test_instr->regs[i]->def == def)
+ for (unsigned i = 0; i < test_instr->srcs_count; i++) {
+ if (test_instr->srcs[i]->def == def)
return true;
}
}
diff --git a/src/freedreno/ir3/ir3_lower_parallelcopy.c b/src/freedreno/ir3/ir3_lower_parallelcopy.c
index 76109ccb382..1144fa056c6 100644
--- a/src/freedreno/ir3/ir3_lower_parallelcopy.c
+++ b/src/freedreno/ir3/ir3_lower_parallelcopy.c
@@ -213,9 +213,9 @@ do_copy(struct ir3_instruction *instr, const struct copy_entry *entry)
mov->cat1.dst_type = (entry->flags & IR3_REG_HALF) ? TYPE_U16 : TYPE_U32;
mov->cat1.src_type = (entry->flags & IR3_REG_HALF) ? TYPE_U16 : TYPE_U32;
if (entry->src.flags & IR3_REG_IMMED)
- mov->regs[1]->uim_val = entry->src.imm;
+ mov->srcs[0]->uim_val = entry->src.imm;
else if (entry->src.flags & IR3_REG_CONST)
- mov->regs[1]->num = entry->src.const_num;
+ mov->srcs[0]->num = entry->src.const_num;
ir3_instr_move_before(mov, instr);
}
@@ -462,9 +462,9 @@ ir3_lower_copies(struct ir3_shader_variant *v)
foreach_instr_safe (instr, &block->instr_list) {
if (instr->opc == OPC_META_PARALLEL_COPY) {
copies_count = 0;
- for (unsigned i = 0; i < instr->regs_count / 2; i++) {
- struct ir3_register *dst = instr->regs[i];
- struct ir3_register *src = instr->regs[i + instr->regs_count / 2];
+ for (unsigned i = 0; i < instr->dsts_count; i++) {
+ struct ir3_register *dst = instr->dsts[i];
+ struct ir3_register *src = instr->srcs[i];
unsigned flags = src->flags & (IR3_REG_HALF | IR3_REG_SHARED);
unsigned dst_physreg = ra_reg_get_physreg(dst);
for (unsigned j = 0; j < reg_elems(dst); j++) {
@@ -479,12 +479,12 @@ ir3_lower_copies(struct ir3_shader_variant *v)
list_del(&instr->node);
} else if (instr->opc == OPC_META_COLLECT) {
copies_count = 0;
- struct ir3_register *dst = instr->regs[0];
+ struct ir3_register *dst = instr->dsts[0];
unsigned flags = dst->flags & (IR3_REG_HALF | IR3_REG_SHARED);
- for (unsigned i = 1; i < instr->regs_count; i++) {
- struct ir3_register *src = instr->regs[i];
+ 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 - 1, flags),
+ .dst = ra_num_to_physreg(dst->num + i, flags),
.src = get_copy_src(src, 0),
.flags = flags,
});
@@ -493,8 +493,8 @@ ir3_lower_copies(struct ir3_shader_variant *v)
list_del(&instr->node);
} else if (instr->opc == OPC_META_SPLIT) {
copies_count = 0;
- struct ir3_register *dst = instr->regs[0];
- struct ir3_register *src = instr->regs[1];
+ struct ir3_register *dst = instr->dsts[0];
+ struct ir3_register *src = instr->srcs[0];
unsigned flags = src->flags & (IR3_REG_HALF | IR3_REG_SHARED);
array_insert(NULL, copies, (struct copy_entry) {
.dst = ra_reg_get_physreg(dst),
diff --git a/src/freedreno/ir3/ir3_merge_regs.c b/src/freedreno/ir3/ir3_merge_regs.c
index 3da34bfca0d..79b2fc918c0 100644
--- a/src/freedreno/ir3/ir3_merge_regs.c
+++ b/src/freedreno/ir3/ir3_merge_regs.c
@@ -118,13 +118,13 @@ chase_copies(struct def_value value)
struct ir3_instruction *instr = value.reg->instr;
if (instr->opc == OPC_META_SPLIT) {
value.offset += instr->split.off * reg_elem_size(value.reg);
- value.reg = instr->regs[1]->def;
+ value.reg = instr->srcs[0]->def;
} else if (instr->opc == OPC_META_COLLECT) {
if (value.offset % reg_elem_size(value.reg) != 0 ||
value.size > reg_elem_size(value.reg) ||
value.offset + value.size > reg_size(value.reg))
break;
- struct ir3_register *src = instr->regs[1 + value.offset / reg_elem_size(value.reg)];
+ struct ir3_register *src = instr->srcs[value.offset / reg_elem_size(value.reg)];
if (!src->def)
break;
value.offset = 0;
@@ -347,9 +347,9 @@ static void
coalesce_phi(struct ir3_liveness *live,
struct ir3_instruction *phi)
{
- for (unsigned i = 1; i < phi->regs_count; i++) {
- if (phi->regs[i]->def)
- try_merge_defs(live, phi->regs[0], phi->regs[i]->def, 0);
+ for (unsigned i = 0; i < phi->srcs_count; i++) {
+ if (phi->srcs[i]->def)
+ try_merge_defs(live, phi->dsts[0], phi->srcs[i]->def, 0);
}
}
@@ -357,11 +357,10 @@ static void
aggressive_coalesce_parallel_copy(struct ir3_liveness *live,
struct ir3_instruction *pcopy)
{
- unsigned copies = pcopy->regs_count / 2;
- for (unsigned i = 0; i < copies; i++) {
- if (!(pcopy->regs[copies + i]->flags & IR3_REG_SSA))
+ for (unsigned i = 0; i < pcopy->dsts_count; i++) {
+ if (!(pcopy->srcs[i]->flags & IR3_REG_SSA))
continue;
- try_merge_defs(live, pcopy->regs[i], pcopy->regs[copies + i]->def, 0);
+ try_merge_defs(live, pcopy->dsts[i], pcopy->srcs[i]->def, 0);
}
}
@@ -369,19 +368,19 @@ static void
aggressive_coalesce_split(struct ir3_liveness *live,
struct ir3_instruction *split)
{
- try_merge_defs(live, split->regs[1]->def, split->regs[0],
- split->split.off * reg_elem_size(split->regs[0]));
+ try_merge_defs(live, split->srcs[0]->def, split->dsts[0],
+ split->split.off * reg_elem_size(split->dsts[0]));
}
static void
aggressive_coalesce_collect(struct ir3_liveness *live,
struct ir3_instruction *collect)
{
- for (unsigned i = 1, offset = 0; i < collect->regs_count;
- offset += reg_elem_size(collect->regs[i]), i++) {
- if (!(collect->regs[i]->flags & IR3_REG_SSA))
+ 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))
continue;
- try_merge_defs(live, collect->regs[0], collect->regs[i]->def, offset);
+ try_merge_defs(live, collect->dsts[0], collect->srcs[i]->def, offset);
}
}
@@ -402,8 +401,8 @@ create_parallel_copy(struct ir3_block *block)
break;
/* Avoid undef */
- if ((phi->regs[1 + pred_idx]->flags & IR3_REG_SSA) &&
- !phi->regs[1 + pred_idx]->def)
+ if ((phi->srcs[pred_idx]->flags & IR3_REG_SSA) &&
+ !phi->srcs[pred_idx]->def)
continue;
/* We don't support critical edges. If we were to support them,
@@ -422,10 +421,10 @@ create_parallel_copy(struct ir3_block *block)
foreach_instr (phi, &succ->instr_list) {
if (phi->opc != OPC_META_PHI)
break;
- if ((phi->regs[1 + pred_idx]->flags & IR3_REG_SSA) &&
- !phi->regs[1 + pred_idx]->def)
+ if ((phi->srcs[pred_idx]->flags & IR3_REG_SSA) &&
+ !phi->srcs[pred_idx]->def)
continue;
- src[j++] = phi->regs[pred_idx + 1];
+ src[j++] = phi->srcs[pred_idx];
}
assert(j == phi_count);
@@ -439,18 +438,18 @@ create_parallel_copy(struct ir3_block *block)
}
for (j = 0; j < phi_count; j++) {
- pcopy->regs[pcopy->regs_count++] = ir3_reg_clone(block->shader, src[j]);
+ pcopy->srcs[pcopy->srcs_count++] = ir3_reg_clone(block->shader, src[j]);
}
j = 0;
foreach_instr (phi, &succ->instr_list) {
if (phi->opc != OPC_META_PHI)
break;
- if ((phi->regs[1 + pred_idx]->flags & IR3_REG_SSA) &&
- !phi->regs[1 + pred_idx]->def)
+ if ((phi->srcs[pred_idx]->flags & IR3_REG_SSA) &&
+ !phi->srcs[pred_idx]->def)
continue;
- phi->regs[1 + pred_idx]->def = pcopy->regs[j];
- phi->regs[1 + pred_idx]->flags = pcopy->regs[j]->flags & ~IR3_REG_DEST;
+ phi->srcs[pred_idx]->def = pcopy->dsts[j];
+ phi->srcs[pred_idx]->flags = pcopy->dsts[j]->flags & ~IR3_REG_DEST;
j++;
}
assert(j == phi_count);
@@ -471,10 +470,8 @@ index_merge_sets(struct ir3 *ir)
unsigned offset = 0;
foreach_block (block, &ir->block_list) {
foreach_instr (instr, &block->instr_list) {
- for (unsigned i = 0; i < instr->regs_count; i++) {
- struct ir3_register *dst = instr->regs[i];
- if (!(dst->flags & IR3_REG_DEST))
- continue;
+ for (unsigned i = 0; i < instr->dsts_count; i++) {
+ struct ir3_register *dst = instr->dsts[i];
unsigned dst_offset;
struct ir3_merge_set *merge_set = dst->merge_set;
@@ -508,10 +505,8 @@ dump_merge_sets(struct ir3 *ir)
struct set *merge_sets = _mesa_pointer_set_create(NULL);
foreach_block (block, &ir->block_list) {
foreach_instr (instr, &block->instr_list) {
- for (unsigned i = 0; i < instr->regs_count; i++) {
- struct ir3_register *dst = instr->regs[i];
- if (!(dst->flags & IR3_REG_DEST))
- continue;
+ for (unsigned i = 0; i < instr->dsts_count; i++) {
+ struct ir3_register *dst = instr->dsts[i];
struct ir3_merge_set *merge_set = dst->merge_set;
if (!merge_set || _mesa_set_search(merge_sets, merge_set))
diff --git a/src/freedreno/ir3/ir3_ra.c b/src/freedreno/ir3/ir3_ra.c
index 3ba2b0a43e1..34cb9717594 100644
--- a/src/freedreno/ir3/ir3_ra.c
+++ b/src/freedreno/ir3/ir3_ra.c
@@ -993,8 +993,8 @@ get_reg(struct ra_ctx *ctx, struct ra_file *file, struct ir3_register *reg,
* SFU instructions:
*/
if (is_sfu(reg->instr) || is_alu(reg->instr)) {
- for (unsigned i = 1; i < reg->instr->regs_count; i++) {
- struct ir3_register *src = reg->instr->regs[i];
+ for (unsigned i = 0; i < reg->instr->srcs_count; i++) {
+ struct ir3_register *src = reg->instr->srcs[i];
if (!ra_reg_is_src(src))
continue;
if (ra_get_file(ctx, src) == file && reg_size(src) >= size) {
@@ -1222,8 +1222,8 @@ handle_normal_instr(struct ra_ctx *ctx, struct ir3_instruction *instr)
static void
handle_split(struct ra_ctx *ctx, struct ir3_instruction *instr)
{
- struct ir3_register *dst = instr->regs[0];
- struct ir3_register *src = instr->regs[1];
+ struct ir3_register *dst = instr->dsts[0];
+ struct ir3_register *src = instr->srcs[0];
if (dst->merge_set == NULL || src->def->merge_set != dst->merge_set) {
handle_normal_instr(ctx, instr);
@@ -1242,8 +1242,8 @@ handle_split(struct ra_ctx *ctx, struct ir3_instruction *instr)
static void
handle_collect(struct ra_ctx *ctx, struct ir3_instruction *instr)
{
- struct ir3_merge_set *dst_set = instr->regs[0]->merge_set;
- unsigned dst_offset = instr->regs[0]->merge_set_offset;
+ struct ir3_merge_set *dst_set = instr->dsts[0]->merge_set;
+ unsigned dst_offset = instr->dsts[0]->merge_set_offset;
if (!dst_set || dst_set->regs_count == 1) {
handle_normal_instr(ctx, instr);
@@ -1267,15 +1267,15 @@ handle_collect(struct ra_ctx *ctx, struct ir3_instruction *instr)
*/
physreg_t dst_fixed = (physreg_t) ~0u;
- for (unsigned i = 1; i < instr->regs_count; i++) {
- if (!ra_reg_is_src(instr->regs[i]))
+ for (unsigned i = 0; i < instr->srcs_count; i++) {
+ if (!ra_reg_is_src(instr->srcs[i]))
continue;
- if (instr->regs[i]->flags & IR3_REG_FIRST_KILL) {
- mark_src_killed(ctx, instr->regs[i]);
+ if (instr->srcs[i]->flags & IR3_REG_FIRST_KILL) {
+ mark_src_killed(ctx, instr->srcs[i]);
}
- struct ir3_register *src = instr->regs[i];
+ struct ir3_register *src = instr->srcs[i];
struct ra_interval *interval = &ctx->intervals[src->def->name];
if (src->def->merge_set != dst_set || interval->is_killed)
@@ -1283,7 +1283,7 @@ handle_collect(struct ra_ctx *ctx, struct ir3_instruction *instr)
while (interval->interval.parent != NULL) {
interval = ir3_reg_interval_to_ra_interval(interval->interval.parent);
}
- if (reg_size(interval->interval.reg) >= reg_size(instr->regs[0])) {
+ if (reg_size(interval->interval.reg) >= reg_size(instr->dsts[0])) {
dst_fixed = interval->physreg_start - interval->interval.reg->merge_set_offset + dst_offset;
} else {
/* For sources whose root interval is smaller than the
@@ -1297,16 +1297,16 @@ handle_collect(struct ra_ctx *ctx, struct ir3_instruction *instr)
}
if (dst_fixed != (physreg_t) ~0u)
- allocate_dst_fixed(ctx, instr->regs[0], dst_fixed);
+ allocate_dst_fixed(ctx, instr->dsts[0], dst_fixed);
else
- allocate_dst(ctx, instr->regs[0]);
+ allocate_dst(ctx, instr->dsts[0]);
/* Remove the temporary is_killed we added */
- for (unsigned i = 1; i < instr->regs_count; i++) {
- if (!ra_reg_is_src(instr->regs[i]))
+ for (unsigned i = 0; i < instr->srcs_count; i++) {
+ if (!ra_reg_is_src(instr->srcs[i]))
continue;
- struct ir3_register *src = instr->regs[i];
+ struct ir3_register *src = instr->srcs[i];
struct ra_interval *interval = &ctx->intervals[src->def->name];
while (interval->interval.parent != NULL) {
interval = ir3_reg_interval_to_ra_interval(interval->interval.parent);
@@ -1327,7 +1327,7 @@ handle_collect(struct ra_ctx *ctx, struct ir3_instruction *instr)
* are a child of the collect by making them children of the collect.
*/
- insert_dst(ctx, instr->regs[0]);
+ insert_dst(ctx, instr->dsts[0]);
insert_parallel_copy_instr(ctx, instr);
}
@@ -1353,42 +1353,42 @@ handle_pcopy(struct ra_ctx *ctx, struct ir3_instruction *instr)
static void
handle_precolored_input(struct ra_ctx *ctx, struct ir3_instruction *instr)
{
- if (instr->regs[0]->num == INVALID_REG)
+ if (instr->dsts[0]->num == INVALID_REG)
return;
- struct ra_interval *interval = &ctx->intervals[instr->regs[0]->name];
- physreg_t physreg = ra_reg_get_physreg(instr->regs[0]);
- allocate_dst_fixed(ctx, instr->regs[0], physreg);
- insert_dst(ctx, instr->regs[0]);
+ struct ra_interval *interval = &ctx->intervals[instr->dsts[0]->name];
+ physreg_t physreg = ra_reg_get_physreg(instr->dsts[0]);
+ allocate_dst_fixed(ctx, instr->dsts[0], physreg);
+ insert_dst(ctx, instr->dsts[0]);
interval->frozen = true;
}
static void
handle_input(struct ra_ctx *ctx, struct ir3_instruction *instr)
{
- if (instr->regs[0]->num != INVALID_REG)
+ if (instr->dsts[0]->num != INVALID_REG)
return;
- allocate_dst(ctx, instr->regs[0]);
+ allocate_dst(ctx, instr->dsts[0]);
- struct ra_file *file = ra_get_file(ctx, instr->regs[0]);
- struct ra_interval *interval = &ctx->intervals[instr->regs[0]->name];
+ struct ra_file *file = ra_get_file(ctx, instr->dsts[0]);
+ struct ra_interval *interval = &ctx->intervals[instr->dsts[0]->name];
ra_file_insert(file, interval);
}
static void
assign_input(struct ra_ctx *ctx, struct ir3_instruction *instr)
{
- struct ra_interval *interval = &ctx->intervals[instr->regs[0]->name];
- struct ra_file *file = ra_get_file(ctx, instr->regs[0]);
+ struct ra_interval *interval = &ctx->intervals[instr->dsts[0]->name];
+ struct ra_file *file = ra_get_file(ctx, instr->dsts[0]);
- if (instr->regs[0]->num == INVALID_REG) {
- assign_reg(instr, instr->regs[0], ra_interval_get_num(interval));
+ if (instr->dsts[0]->num == INVALID_REG) {
+ assign_reg(instr, instr->dsts[0], ra_interval_get_num(interval));
} else {
interval->frozen = false;
}
- if (instr->regs[0]->flags & IR3_REG_UNUSED)
+ if (instr->dsts[0]->flags & IR3_REG_UNUSED)
ra_file_remove(file, interval);
ra_foreach_src_rev(src, instr)
@@ -1457,7 +1457,7 @@ handle_chmask(struct ra_ctx *ctx, struct ir3_instruction *instr)
}
/* add dummy destination for validation */
- assign_reg(instr, instr->regs[0], 0);
+ assign_reg(instr, instr->dsts[0], 0);
insert_parallel_copy_instr(ctx, instr);
}
@@ -1550,21 +1550,21 @@ handle_phi(struct ra_ctx *ctx, struct ir3_register *def)
static void
assign_phi(struct ra_ctx *ctx, struct ir3_instruction *phi)
{
- struct ra_file *file = ra_get_file(ctx, phi->regs[0]);
- struct ra_interval *interval = &ctx->intervals[phi->regs[0]->name];
+ struct ra_file *file = ra_get_file(ctx, phi->dsts[0]);
+ struct ra_interval *interval = &ctx->intervals[phi->dsts[0]->name];
assert(!interval->interval.parent);
unsigned num = ra_interval_get_num(interval);
- assign_reg(phi, phi->regs[0], num);
+ assign_reg(phi, phi->dsts[0], num);
/* Assign the parallelcopy sources of this phi */
- for (unsigned i = 1; i < phi->regs_count; i++) {
- if (phi->regs[i]->def) {
- assign_reg(phi, phi->regs[i], num);
- assign_reg(phi, phi->regs[i]->def, num);
+ for (unsigned i = 0; i < phi->srcs_count; i++) {
+ if (phi->srcs[i]->def) {
+ assign_reg(phi, phi->srcs[i], num);
+ assign_reg(phi, phi->srcs[i]->def, num);
}
}
- if (phi->regs[0]->flags & IR3_REG_UNUSED)
+ if (phi->dsts[0]->flags & IR3_REG_UNUSED)
ra_file_remove(file, interval);
}
@@ -1608,8 +1608,8 @@ insert_liveout_copy(struct ir3_block *block, physreg_t dst, physreg_t src,
old_pcopy_srcs + 1, old_pcopy_srcs + 1);
for (unsigned i = 0; i < old_pcopy_srcs; i++) {
- old_pcopy->regs[i]->instr = pcopy;
- pcopy->regs[pcopy->regs_count++] = old_pcopy->regs[i];
+ old_pcopy->dsts[i]->instr = pcopy;
+ pcopy->dsts[pcopy->dsts_count++] = old_pcopy->dsts[i];
}
struct ir3_register *dst_reg =
@@ -1619,8 +1619,10 @@ insert_liveout_copy(struct ir3_block *block, physreg_t dst, physreg_t src,
dst_reg->size = reg->size;
assign_reg(pcopy, dst_reg, ra_physreg_to_num(dst, reg->flags));
- for (unsigned i = old_pcopy_srcs; i < old_pcopy_srcs * 2; i++) {
- pcopy->regs[pcopy->regs_count++] = old_pcopy->regs[i];
+ pcopy->srcs = pcopy->regs + pcopy->dsts_count;
+
+ for (unsigned i = 0; i < old_pcopy_srcs; i++) {
+ pcopy->srcs[pcopy->srcs_count++] = old_pcopy->srcs[i];
}
struct ir3_register *src_reg =
@@ -1784,7 +1786,7 @@ handle_block(struct ra_ctx *ctx, struct ir3_block *block)
foreach_instr (instr, &block->instr_list) {
if (instr->opc == OPC_META_PHI)
- handle_phi(ctx, instr->regs[0]);
+ handle_phi(ctx, instr->dsts[0]);
else if (instr->opc == OPC_META_INPUT || instr->opc == OPC_META_TEX_PREFETCH)
handle_input(ctx, instr);
else
@@ -1936,8 +1938,8 @@ ir3_ra(struct ir3_shader_variant *v)
*/
foreach_block (block, &v->ir->block_list) {
foreach_instr (instr, &block->instr_list) {
- for (unsigned i = 0; i < instr->regs_count; i++) {
- instr->regs[i]->flags &= ~IR3_REG_SSA;
+ for (unsigned i = 0; i < instr->dsts_count; i++) {
+ instr->dsts[i]->flags &= ~IR3_REG_SSA;
/* Parallel copies of array registers copy the whole register,
* and we need some way to let the parallel copy code know
@@ -1945,7 +1947,14 @@ ir3_ra(struct ir3_shader_variant *v)
* reg->size. So keep the array flag on those.
*/
if (!is_meta(instr))
- instr->regs[i]->flags &= ~IR3_REG_ARRAY;
+ instr->dsts[i]->flags &= ~IR3_REG_ARRAY;
+ }
+
+ for (unsigned i = 0; i < instr->srcs_count; i++) {
+ instr->srcs[i]->flags &= ~IR3_REG_SSA;
+
+ if (!is_meta(instr))
+ instr->srcs[i]->flags &= ~IR3_REG_ARRAY;
}
}
}
diff --git a/src/freedreno/ir3/ir3_ra.h b/src/freedreno/ir3/ir3_ra.h
index 7efb6584591..688795d58ea 100644
--- a/src/freedreno/ir3/ir3_ra.h
+++ b/src/freedreno/ir3/ir3_ra.h
@@ -94,7 +94,7 @@ ra_reg_is_src(const struct ir3_register *reg)
static inline bool
ra_reg_is_dst(const struct ir3_register *reg)
{
- return (reg->flags & IR3_REG_SSA) && (reg->flags & IR3_REG_DEST) &&
+ return (reg->flags & IR3_REG_SSA) &&
def_is_gpr(reg) &&
((reg->flags & IR3_REG_ARRAY) || reg->wrmask);
}
@@ -107,18 +107,18 @@ ra_reg_is_dst(const struct ir3_register *reg)
#define ra_foreach_src(__srcreg, __instr) \
for (struct ir3_register *__srcreg = (void *)~0; __srcreg; __srcreg = NULL) \
- for (unsigned __cnt = (__instr)->regs_count, __i = 0; __i < __cnt; __i++) \
- if (ra_reg_is_src((__srcreg = (__instr)->regs[__i])))
+ for (unsigned __cnt = (__instr)->srcs_count, __i = 0; __i < __cnt; __i++) \
+ if (ra_reg_is_src((__srcreg = (__instr)->srcs[__i])))
#define ra_foreach_src_rev(__srcreg, __instr) \
for (struct ir3_register *__srcreg = (void *)~0; __srcreg; __srcreg = NULL) \
- for (int __cnt = (__instr)->regs_count, __i = __cnt - 1; __i >= 0; __i--) \
- if (ra_reg_is_src((__srcreg = (__instr)->regs[__i])))
+ for (int __cnt = (__instr)->srcs_count, __i = __cnt - 1; __i >= 0; __i--) \
+ if (ra_reg_is_src((__srcreg = (__instr)->srcs[__i])))
-#define ra_foreach_dst(__srcreg, __instr) \
- for (struct ir3_register *__srcreg = (void *)~0; __srcreg; __srcreg = NULL) \
- for (unsigned __cnt = (__instr)->regs_count, __i = 0; __i < __cnt; __i++) \
- if (ra_reg_is_dst((__srcreg = (__instr)->regs[__i])))
+#define ra_foreach_dst(__dstreg, __instr) \
+ for (struct ir3_register *__dstreg = (void *)~0; __dstreg; __dstreg = NULL) \
+ for (unsigned __cnt = (__instr)->dsts_count, __i = 0; __i < __cnt; __i++) \
+ if (ra_reg_is_dst((__dstreg = (__instr)->dsts[__i])))
#define RA_HALF_SIZE (4 * 48)
diff --git a/src/freedreno/ir3/ir3_ra_validate.c b/src/freedreno/ir3/ir3_ra_validate.c
index 932a2bec6d8..046c49723e8 100644
--- a/src/freedreno/ir3/ir3_ra_validate.c
+++ b/src/freedreno/ir3/ir3_ra_validate.c
@@ -225,8 +225,8 @@ propagate_normal_instr(struct ra_val_ctx *ctx, struct ir3_instruction *instr)
static void
propagate_split(struct ra_val_ctx *ctx, struct ir3_instruction *split)
{
- struct ir3_register *dst = split->regs[0];
- struct ir3_register *src = split->regs[1];
+ struct ir3_register *dst = split->dsts[0];
+ struct ir3_register *src = split->srcs[0];
physreg_t dst_physreg = ra_reg_get_physreg(dst);
physreg_t src_physreg = ra_reg_get_physreg(src);
struct file_state *file = ra_val_get_file(ctx, dst);
@@ -240,16 +240,16 @@ propagate_split(struct ra_val_ctx *ctx, struct ir3_instruction *split)
static void
propagate_collect(struct ra_val_ctx *ctx, struct ir3_instruction *collect)
{
- struct ir3_register *dst = collect->regs[0];
+ struct ir3_register *dst = collect->dsts[0];
physreg_t dst_physreg = ra_reg_get_physreg(dst);
struct file_state *file = ra_val_get_file(ctx, dst);
unsigned size = reg_size(dst);
struct reg_state srcs[size];
- for (unsigned i = 1; i < collect->regs_count; i++) {
- struct ir3_register *src = collect->regs[i];
- unsigned dst_offset = (i - 1) * reg_elem_size(dst);
+ for (unsigned i = 0; i < collect->srcs_count; i++) {
+ struct ir3_register *src = collect->srcs[i];
+ unsigned dst_offset = i * reg_elem_size(dst);
for (unsigned j = 0; j < reg_elem_size(dst); j++) {
if (!ra_reg_is_src(src)) {
srcs[dst_offset + j] = (struct reg_state) {
@@ -271,16 +271,16 @@ static void
propagate_parallelcopy(struct ra_val_ctx *ctx, struct ir3_instruction *pcopy)
{
unsigned size = 0;
- for (unsigned i = 0; i < pcopy->regs_count / 2; i++) {
- size += reg_size(pcopy->regs[i]);
+ for (unsigned i = 0; i < pcopy->dsts_count; i++) {
+ size += reg_size(pcopy->srcs[i]);
}
struct reg_state srcs[size];
unsigned offset = 0;
- for (unsigned i = 0; i < pcopy->regs_count / 2; i++) {
- struct ir3_register *dst = pcopy->regs[i];
- struct ir3_register *src = pcopy->regs[i + pcopy->regs_count / 2];
+ for (unsigned i = 0; i < pcopy->srcs_count; i++) {
+ struct ir3_register *dst = pcopy->dsts[i];
+ struct ir3_register *src = pcopy->srcs[i];
struct file_state *file = ra_val_get_file(ctx, dst);
for (unsigned j = 0; j < reg_size(dst); j++) {
@@ -300,8 +300,8 @@ propagate_parallelcopy(struct ra_val_ctx *ctx, struct ir3_instruction *pcopy)
assert(offset == size);
offset = 0;
- for (unsigned i = 0; i < pcopy->regs_count / 2; i++) {
- struct ir3_register *dst = pcopy->regs[i];
+ for (unsigned i = 0; i < pcopy->dsts_count; i++) {
+ struct ir3_register *dst = pcopy->dsts[i];
physreg_t dst_physreg = ra_reg_get_physreg(dst);
struct file_state *file = ra_val_get_file(ctx, dst);
@@ -353,7 +353,7 @@ chase_definition(struct reg_state *state)
struct ir3_instruction *instr = state->def->instr;
switch (instr->opc) {
case OPC_META_SPLIT: {
- struct ir3_register *new_def = instr->regs[1]->def;
+ struct ir3_register *new_def = instr->srcs[0]->def;
unsigned offset = instr->split.off * reg_elem_size(new_def);
*state = (struct reg_state) {
.def = new_def,
@@ -364,7 +364,7 @@ chase_definition(struct reg_state *state)
case OPC_META_COLLECT: {
unsigned src_idx = state->offset / reg_elem_size(state->def);
unsigned src_offset = state->offset % reg_elem_size(state->def);
- struct ir3_register *new_def = instr->regs[src_idx + 1]->def;
+ struct ir3_register *new_def = instr->srcs[src_idx]->def;
if (new_def) {
*state = (struct reg_state) {
.def = new_def,
@@ -378,16 +378,15 @@ chase_definition(struct reg_state *state)
}
case OPC_META_PARALLEL_COPY: {
unsigned dst_idx = ~0;
- for (unsigned i = 0; i < instr->regs_count; i++) {
- if (instr->regs[i] == state->def) {
+ for (unsigned i = 0; i < instr->dsts_count; i++) {
+ if (instr->dsts[i] == state->def) {
dst_idx = i;
break;
}
}
assert(dst_idx != ~0);
- struct ir3_register *new_def =
- instr->regs[dst_idx + instr->regs_count / 2]->def;
+ struct ir3_register *new_def = instr->srcs[dst_idx]->def;
if (new_def) {
state->def = new_def;
} else {
@@ -487,8 +486,8 @@ check_reaching_block(struct ra_val_ctx *ctx, struct ir3_block *block)
foreach_instr (instr, &succ->instr_list) {
if (instr->opc != OPC_META_PHI)
break;
- if (instr->regs[1 + pred_idx]->def)
- check_reaching_src(ctx, instr, instr->regs[1 + pred_idx]);
+ if (instr->srcs[pred_idx]->def)
+ check_reaching_src(ctx, instr, instr->srcs[pred_idx]);
}
}
}
diff --git a/src/freedreno/ir3/ir3_spill.c b/src/freedreno/ir3/ir3_spill.c
index 1205dcc5b4b..5f3dee7c7f0 100644
--- a/src/freedreno/ir3/ir3_spill.c
+++ b/src/freedreno/ir3/ir3_spill.c
@@ -269,21 +269,23 @@ handle_instr(struct ra_spill_ctx *ctx, struct ir3_instruction *instr)
update_max_pressure(ctx);
- for (unsigned i = 0; i < instr->regs_count; i++) {
- if (ra_reg_is_src(instr->regs[i]) &&
- (instr->regs[i]->flags & IR3_REG_FIRST_KILL))
- remove_src(ctx, instr, instr->regs[i]);
- else if (ra_reg_is_dst(instr->regs[i]) &&
- (instr->regs[i]->flags & IR3_REG_UNUSED))
- remove_dst(ctx, instr->regs[i]);
+ for (unsigned i = 0; i < instr->srcs_count; i++) {
+ if (ra_reg_is_src(instr->srcs[i]) &&
+ (instr->srcs[i]->flags & IR3_REG_FIRST_KILL))
+ remove_src(ctx, instr, instr->srcs[i]);
+ }
+ for (unsigned i = 0; i < instr->dsts_count; i++) {
+ if (ra_reg_is_dst(instr->dsts[i]) &&
+ (instr->dsts[i]->flags & IR3_REG_UNUSED))
+ remove_dst(ctx, instr->dsts[i]);
}
}
static void
handle_input_phi(struct ra_spill_ctx *ctx, struct ir3_instruction *instr)
{
- init_dst(ctx, instr->regs[0]);
- insert_dst(ctx, instr->regs[0]);
+ init_dst(ctx, instr->dsts[0]);
+ insert_dst(ctx, instr->dsts[0]);
}
static void
@@ -291,8 +293,8 @@ remove_input_phi(struct ra_spill_ctx *ctx, struct ir3_instruction *instr)
{
ra_foreach_src(src, instr)
remove_src(ctx, instr, src);
- if (instr->regs[0]->flags & IR3_REG_UNUSED)
- remove_dst(ctx, instr->regs[0]);
+ if (instr->dsts[0]->flags & IR3_REG_UNUSED)
+ remove_dst(ctx, instr->dsts[0]);
}
static void