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)
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) \
/* 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
}
}
}
+
+ /* 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;
}
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);
}
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");