ir3/sched: Fix could_sched() determination

This needs to be accurate so that when we split and then schedule a new
a0.x/a1.x/p0.x write we will eventually make progress. It wasn't taking
the kill_path into account which could create an infinite loop as we
keep scheduling writes whose uses are blocked because they are memory
instructions not on the kill_path.

Closes: #6413
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16635>
This commit is contained in:
Connor Abbott 2022-05-20 13:57:23 +02:00 committed by Marge Bot
parent a8671b2182
commit c601ba332b
1 changed files with 31 additions and 15 deletions

View File

@ -371,9 +371,28 @@ struct ir3_sched_notes {
bool addr0_conflict, addr1_conflict, pred_conflict;
};
static bool
should_skip(struct ir3_sched_ctx *ctx, struct ir3_instruction *instr)
{
if (ctx->remaining_kills && (is_tex(instr) || is_mem(instr))) {
/* avoid texture/memory access if we have unscheduled kills
* that could make the expensive operation unnecessary. By
* definition, if there are remaining kills, and this instr
* is not a dependency of a kill, there are other instructions
* that we can choose from.
*/
struct ir3_sched_node *n = instr->data;
if (!n->kill_path)
return true;
}
return false;
}
/* could an instruction be scheduled if specified ssa src was scheduled? */
static bool
could_sched(struct ir3_instruction *instr, struct ir3_instruction *src)
could_sched(struct ir3_sched_ctx *ctx,
struct ir3_instruction *instr, struct ir3_instruction *src)
{
foreach_ssa_src (other_src, instr) {
/* if dependency not scheduled, we aren't ready yet: */
@ -381,7 +400,13 @@ could_sched(struct ir3_instruction *instr, struct ir3_instruction *src)
return false;
}
}
return true;
/* Instructions not in the current block can never be scheduled.
*/
if (instr->block != src->block)
return false;
return !should_skip(ctx, instr);
}
/* Check if instruction is ok to schedule. Make sure it is not blocked
@ -400,17 +425,8 @@ check_instr(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,
return false;
}
if (ctx->remaining_kills && (is_tex(instr) || is_mem(instr))) {
/* avoid texture/memory access if we have unscheduled kills
* that could make the expensive operation unnecessary. By
* definition, if there are remaining kills, and this instr
* is not a dependency of a kill, there are other instructions
* that we can choose from.
*/
struct ir3_sched_node *n = instr->data;
if (!n->kill_path)
return false;
}
if (should_skip(ctx, instr))
return false;
/* For instructions that write address register we need to
* make sure there is at least one instruction that uses the
@ -428,7 +444,7 @@ check_instr(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,
continue;
if (indirect->address->def != instr->dsts[0])
continue;
ready = could_sched(indirect, instr);
ready = could_sched(ctx, indirect, instr);
}
/* nothing could be scheduled, so keep looking: */
@ -445,7 +461,7 @@ check_instr(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,
continue;
if (indirect->address->def != instr->dsts[0])
continue;
ready = could_sched(indirect, instr);
ready = could_sched(ctx, indirect, instr);
}
/* nothing could be scheduled, so keep looking: */