mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-03 13:00:37 +01:00
ir3/ra: Fix available bitset for live-through collect srcs
When we mark live-through sources that are merged with the destination
as killed, we kept the bitsets in sync, but we forgot to keep them in
sync when unmarking them after allocating the destination. The result
was that "available" wasn't correct for any instruction afterwards. This
resulted in a bad register allocation with IR3_SHADER_DEBUG=spillall for
a dEQP-VK test.
While we're changing this, use ra_foreach_src().
Fixes: 0ffcb19b9d ("ir3: Rewrite register allocation")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12033>
This commit is contained in:
parent
eae36b4850
commit
70c22d3894
1 changed files with 19 additions and 14 deletions
|
|
@ -551,6 +551,18 @@ ra_file_mark_killed(struct ra_file *file, struct ra_interval *interval)
|
|||
interval->is_killed = true;
|
||||
}
|
||||
|
||||
static void
|
||||
ra_file_unmark_killed(struct ra_file *file, struct ra_interval *interval)
|
||||
{
|
||||
assert(!interval->interval.parent);
|
||||
|
||||
for (physreg_t i = interval->physreg_start; i < interval->physreg_end; i++) {
|
||||
BITSET_CLEAR(file->available, i);
|
||||
}
|
||||
|
||||
interval->is_killed = false;
|
||||
}
|
||||
|
||||
static physreg_t
|
||||
ra_interval_get_physreg(const struct ra_interval *interval)
|
||||
{
|
||||
|
|
@ -1314,15 +1326,11 @@ handle_collect(struct ra_ctx *ctx, struct ir3_instruction *instr)
|
|||
*/
|
||||
physreg_t dst_fixed = (physreg_t)~0u;
|
||||
|
||||
for (unsigned i = 0; i < instr->srcs_count; i++) {
|
||||
if (!ra_reg_is_src(instr->srcs[i]))
|
||||
continue;
|
||||
|
||||
if (instr->srcs[i]->flags & IR3_REG_FIRST_KILL) {
|
||||
mark_src_killed(ctx, instr->srcs[i]);
|
||||
ra_foreach_src (src, instr) {
|
||||
if (src->flags & IR3_REG_FIRST_KILL) {
|
||||
mark_src_killed(ctx, src);
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
@ -1350,11 +1358,7 @@ handle_collect(struct ra_ctx *ctx, struct ir3_instruction *instr)
|
|||
allocate_dst(ctx, instr->dsts[0]);
|
||||
|
||||
/* Remove the temporary is_killed we added */
|
||||
for (unsigned i = 0; i < instr->srcs_count; i++) {
|
||||
if (!ra_reg_is_src(instr->srcs[i]))
|
||||
continue;
|
||||
|
||||
struct ir3_register *src = instr->srcs[i];
|
||||
ra_foreach_src (src, instr) {
|
||||
struct ra_interval *interval = &ctx->intervals[src->def->name];
|
||||
while (interval->interval.parent != NULL) {
|
||||
interval = ir3_reg_interval_to_ra_interval(interval->interval.parent);
|
||||
|
|
@ -1362,8 +1366,9 @@ handle_collect(struct ra_ctx *ctx, struct ir3_instruction *instr)
|
|||
|
||||
/* Filter out cases where it actually should be killed */
|
||||
if (interval != &ctx->intervals[src->def->name] ||
|
||||
!(src->flags & IR3_REG_KILL))
|
||||
interval->is_killed = false;
|
||||
!(src->flags & IR3_REG_KILL)) {
|
||||
ra_file_unmark_killed(ra_get_file(ctx, src), interval);
|
||||
}
|
||||
}
|
||||
|
||||
ra_foreach_src_rev (src, instr) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue