freedreno/ir3: better cleanup when removing unused instructions

Do a better job of pruning when removing unused instructions, including
cleaning up dangling false-deps.

This introduces a new ssa src pointer iterator, which makes it easy to
clear links without having to think about whether it is a normal ssa
src or a false-dep.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4440>
This commit is contained in:
Rob Clark
2020-04-04 09:53:32 -07:00
committed by Marge Bot
parent 96ff2a4099
commit cf74048fd1
4 changed files with 36 additions and 10 deletions

View File

@@ -1118,13 +1118,16 @@ static inline unsigned __ssa_src_cnt(struct ir3_instruction *instr)
return cnt;
}
static inline struct ir3_instruction * __ssa_src_n(struct ir3_instruction *instr, unsigned n)
static inline struct ir3_instruction **
__ssa_srcp_n(struct ir3_instruction *instr, unsigned n)
{
if (n == (instr->regs_count + instr->deps_count))
return instr->address;
return &instr->address;
if (n >= instr->regs_count)
return instr->deps[n - instr->regs_count];
return ssa(instr->regs[n]);
return &instr->deps[n - instr->regs_count];
if (ssa(instr->regs[n]))
return &instr->regs[n]->instr;
return NULL;
}
static inline bool __is_false_dep(struct ir3_instruction *instr, unsigned n)
@@ -1136,12 +1139,18 @@ static inline bool __is_false_dep(struct ir3_instruction *instr, unsigned n)
return false;
}
#define __src_cnt(__instr) ((__instr)->address ? (__instr)->regs_count : (__instr)->regs_count - 1)
#define foreach_ssa_srcp_n(__srcp, __n, __instr) \
for (struct ir3_instruction **__srcp = (void *)~0; __srcp; __srcp = NULL) \
for (unsigned __cnt = __ssa_src_cnt(__instr), __n = 0; __n < __cnt; __n++) \
if ((__srcp = __ssa_srcp_n(__instr, __n)))
#define foreach_ssa_srcp(__srcp, __instr) \
foreach_ssa_srcp_n(__srcp, __i, __instr)
/* iterator for an instruction's SSA sources (instr), also returns src #: */
#define foreach_ssa_src_n(__srcinst, __n, __instr) \
for (unsigned __cnt = __ssa_src_cnt(__instr), __n = 0; __n < __cnt; __n++) \
if ((__srcinst = __ssa_src_n(__instr, __n)))
foreach_ssa_srcp_n(__srcp, __n, __instr) \
if ((__srcinst = *__srcp))
/* iterator for an instruction's SSA sources (instr): */
#define foreach_ssa_src(__srcinst, __instr) \

View File

@@ -95,7 +95,7 @@ remove_unused_by_block(struct ir3_block *block)
/* tex (cat5) instructions have a writemask, so we can
* mask off unused components. Other instructions do not.
*/
if (is_tex_or_prefetch(src) && (src->regs[0]->wrmask > 1)) {
if (src && is_tex_or_prefetch(src) && (src->regs[0]->wrmask > 1)) {
src->regs[0]->wrmask &= ~(1 << instr->split.off);
/* prune no-longer needed right-neighbors. We could
@@ -114,6 +114,13 @@ remove_unused_by_block(struct ir3_block *block)
}
}
}
/* prune false-deps, etc: */
foreach_ssa_use (use, instr)
foreach_ssa_srcp_n (srcp, n, use)
if (*srcp == instr)
*srcp = NULL;
list_delinit(&instr->node);
progress = true;
}
@@ -206,8 +213,14 @@ compute_depth_and_remove_unused(struct ir3 *ir, struct ir3_shader_variant *so)
void
ir3_depth(struct ir3 *ir, struct ir3_shader_variant *so)
{
void *mem_ctx = ralloc_context(NULL);
bool progress;
ir3_find_ssa_uses(ir, mem_ctx, true);
do {
progress = compute_depth_and_remove_unused(ir, so);
} while (progress);
ralloc_free(mem_ctx);
}

View File

@@ -685,7 +685,7 @@ cleanup_self_movs(struct ir3 *ir)
}
for (unsigned i = 0; i < instr->deps_count; i++) {
if (is_self_mov(instr->deps[i])) {
if (instr->deps[i] && is_self_mov(instr->deps[i])) {
list_delinit(&instr->deps[i]->node);
instr->deps[i] = instr->deps[i]->regs[1]->instr;
}

View File

@@ -73,7 +73,11 @@ static void print_instr_name(struct ir3_instruction *instr, bool flags)
printf("%04u:", instr->name);
printf("%04u:", instr->ip);
printf("%03d:", instr->depth);
printf("%03u: ", instr->use_count);
if (instr->flags & IR3_INSTR_UNUSED) {
printf("XXX: ");
} else {
printf("%03u: ", instr->use_count);
}
if (flags) {
printf("\t");