summaryrefslogtreecommitdiff
path: root/src/freedreno
diff options
context:
space:
mode:
authorRob Clark <robdclark@chromium.org>2020-04-04 09:53:32 -0700
committerMarge Bot <eric+marge@anholt.net>2020-04-13 20:47:28 +0000
commitcf74048fd14eb594dbb23e07d37cf8df44564263 (patch)
tree03032680f2694593acd4bfb202aa5cdf60bb8031 /src/freedreno
parent96ff2a4099d0eb5c29255429a0e5284e461ec8d5 (diff)
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>
Diffstat (limited to 'src/freedreno')
-rw-r--r--src/freedreno/ir3/ir3.h23
-rw-r--r--src/freedreno/ir3/ir3_depth.c15
-rw-r--r--src/freedreno/ir3/ir3_postsched.c2
-rw-r--r--src/freedreno/ir3/ir3_print.c6
4 files changed, 36 insertions, 10 deletions
diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h
index 65c16791e62..7fb0d823d25 100644
--- a/src/freedreno/ir3/ir3.h
+++ b/src/freedreno/ir3/ir3.h
@@ -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) \
diff --git a/src/freedreno/ir3/ir3_depth.c b/src/freedreno/ir3/ir3_depth.c
index 00d0c54fac5..90a0ddef51f 100644
--- a/src/freedreno/ir3/ir3_depth.c
+++ b/src/freedreno/ir3/ir3_depth.c
@@ -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);
}
diff --git a/src/freedreno/ir3/ir3_postsched.c b/src/freedreno/ir3/ir3_postsched.c
index 09e58750c04..521078a04c9 100644
--- a/src/freedreno/ir3/ir3_postsched.c
+++ b/src/freedreno/ir3/ir3_postsched.c
@@ -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;
}
diff --git a/src/freedreno/ir3/ir3_print.c b/src/freedreno/ir3/ir3_print.c
index 44c8278276a..b18a3d27e34 100644
--- a/src/freedreno/ir3/ir3_print.c
+++ b/src/freedreno/ir3/ir3_print.c
@@ -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");