mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-08 08:30:10 +01:00
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>
This commit is contained in:
parent
d3e08327cf
commit
af48cfc06b
7 changed files with 143 additions and 140 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue