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:
parent
a8671b2182
commit
c601ba332b
|
@ -371,9 +371,28 @@ struct ir3_sched_notes {
|
||||||
bool addr0_conflict, addr1_conflict, pred_conflict;
|
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? */
|
/* could an instruction be scheduled if specified ssa src was scheduled? */
|
||||||
static bool
|
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) {
|
foreach_ssa_src (other_src, instr) {
|
||||||
/* if dependency not scheduled, we aren't ready yet: */
|
/* 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 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
|
/* 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->remaining_kills && (is_tex(instr) || is_mem(instr))) {
|
if (should_skip(ctx, instr))
|
||||||
/* avoid texture/memory access if we have unscheduled kills
|
return false;
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For instructions that write address register we need to
|
/* For instructions that write address register we need to
|
||||||
* make sure there is at least one instruction that uses the
|
* 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;
|
continue;
|
||||||
if (indirect->address->def != instr->dsts[0])
|
if (indirect->address->def != instr->dsts[0])
|
||||||
continue;
|
continue;
|
||||||
ready = could_sched(indirect, instr);
|
ready = could_sched(ctx, indirect, instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing could be scheduled, so keep looking: */
|
/* nothing could be scheduled, so keep looking: */
|
||||||
|
@ -445,7 +461,7 @@ check_instr(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,
|
||||||
continue;
|
continue;
|
||||||
if (indirect->address->def != instr->dsts[0])
|
if (indirect->address->def != instr->dsts[0])
|
||||||
continue;
|
continue;
|
||||||
ready = could_sched(indirect, instr);
|
ready = could_sched(ctx, indirect, instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing could be scheduled, so keep looking: */
|
/* nothing could be scheduled, so keep looking: */
|
||||||
|
|
Loading…
Reference in New Issue