From: Rob Clark Date: Wed, 6 May 2020 17:01:08 +0000 (-0700) Subject: freedreno/ir3/postsched: reset sfu_delay on sync X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=25f4fb346e1fad34ce1f2e9e39b062a303db4ce3;p=mesa.git 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 Part-of: --- diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 4e7550f5e8d..9ec324e4e4a 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -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); diff --git a/src/freedreno/ir3/ir3_postsched.c b/src/freedreno/ir3/ir3_postsched.c index 496c1d211b8..4535459efcf 100644 --- a/src/freedreno/ir3/ir3_postsched.c +++ b/src/freedreno/ir3/ir3_postsched.c @@ -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;