freedreno/ir3/postsched: reset sfu_delay on sync
Once we schedule an instruction that will require an `(ss)` sync flag, there is no need to delay any further instructions that consume an SFU result (until the next SFU instruction is scheduled). Signed-off-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4923>
This commit is contained in:
@@ -1139,6 +1139,35 @@ static inline bool __is_false_dep(struct ir3_instruction *instr, unsigned n)
|
||||
#define foreach_array(__array, __list) \
|
||||
list_for_each_entry(struct ir3_array, __array, __list, node)
|
||||
|
||||
/* Check if condition is true for any src instruction.
|
||||
*/
|
||||
static inline bool
|
||||
check_src_cond(struct ir3_instruction *instr, bool (*cond)(struct ir3_instruction *))
|
||||
{
|
||||
struct ir3_register *reg;
|
||||
|
||||
/* Note that this is also used post-RA so skip the ssa iterator: */
|
||||
foreach_src (reg, instr) {
|
||||
struct ir3_instruction *src = reg->instr;
|
||||
|
||||
if (!src)
|
||||
continue;
|
||||
|
||||
/* meta:split/collect aren't real instructions, the thing that
|
||||
* we actually care about is *their* srcs
|
||||
*/
|
||||
if ((src->opc == OPC_META_SPLIT) || (src->opc == OPC_META_COLLECT)) {
|
||||
if (check_src_cond(src, cond))
|
||||
return true;
|
||||
} else {
|
||||
if (cond(src))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* dump: */
|
||||
void ir3_print(struct ir3 *ir);
|
||||
void ir3_print_instr(struct ir3_instruction *instr);
|
||||
|
||||
@@ -94,6 +94,8 @@ schedule(struct ir3_postsched_ctx *ctx, struct ir3_instruction *instr)
|
||||
|
||||
if (is_sfu(instr)) {
|
||||
ctx->sfu_delay = 8;
|
||||
} else if (check_src_cond(instr, is_sfu)) {
|
||||
ctx->sfu_delay = 0;
|
||||
} else if (ctx->sfu_delay > 0) {
|
||||
ctx->sfu_delay--;
|
||||
}
|
||||
@@ -129,10 +131,8 @@ static bool
|
||||
would_sync(struct ir3_postsched_ctx *ctx, struct ir3_instruction *instr)
|
||||
{
|
||||
if (ctx->sfu_delay) {
|
||||
struct ir3_register *reg;
|
||||
foreach_src (reg, instr)
|
||||
if (reg->instr && is_sfu(reg->instr))
|
||||
return true;
|
||||
if (check_src_cond(instr, is_sfu))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user