diff --git a/src/.clang-format b/src/.clang-format index b7886185238..27c0dae5970 100644 --- a/src/.clang-format +++ b/src/.clang-format @@ -226,8 +226,10 @@ ForEachMacros: - foreach_sched_node - foreach_src - foreach_src_n + - foreach_src_if - foreach_dst - foreach_dst_n + - foreach_dst_if - ra_foreach_dst - ra_foreach_src - ra_foreach_src_rev diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index ed633132277..e499d81b929 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -1731,6 +1731,10 @@ ir3_try_swap_signedness(opc_t opc, bool *can_swap) /* iterator for an instructions's sources (reg): */ #define foreach_src(__srcreg, __instr) foreach_src_n (__srcreg, __i, __instr) +#define foreach_src_if(__srcreg, __instr, __filter) \ + foreach_src (__srcreg, __instr) \ + if (__filter(__srcreg)) + /* iterator for an instructions's destinations (reg), also returns dst #: */ #define foreach_dst_n(__dstreg, __n, __instr) \ if ((__instr)->dsts_count) \ @@ -1743,6 +1747,10 @@ ir3_try_swap_signedness(opc_t opc, bool *can_swap) /* iterator for an instructions's destinations (reg): */ #define foreach_dst(__dstreg, __instr) foreach_dst_n (__dstreg, __i, __instr) +#define foreach_dst_if(__dstreg, __instr, __filter) \ + foreach_dst (__dstreg, __instr) \ + if (__filter(__dstreg)) + static inline unsigned __ssa_src_cnt(struct ir3_instruction *instr) { diff --git a/src/freedreno/ir3/ir3_liveness.c b/src/freedreno/ir3/ir3_liveness.c index b413ee9d10e..74a53b26df1 100644 --- a/src/freedreno/ir3/ir3_liveness.c +++ b/src/freedreno/ir3/ir3_liveness.c @@ -37,14 +37,15 @@ static bool compute_block_liveness(struct ir3_liveness *live, struct ir3_block *block, - BITSET_WORD *tmp_live, unsigned bitset_words) + BITSET_WORD *tmp_live, unsigned bitset_words, + reg_filter_cb filter_src, reg_filter_cb filter_dst) { memcpy(tmp_live, live->live_out[block->index], bitset_words * sizeof(BITSET_WORD)); /* Process instructions */ foreach_instr_rev (instr, &block->instr_list) { - ra_foreach_dst (dst, instr) { + foreach_dst_if (dst, instr, filter_dst) { if (BITSET_TEST(tmp_live, dst->name)) dst->flags &= ~IR3_REG_UNUSED; else @@ -54,18 +55,19 @@ compute_block_liveness(struct ir3_liveness *live, struct ir3_block *block, /* Phi node uses occur after the predecessor block */ if (instr->opc != OPC_META_PHI) { - ra_foreach_src (src, instr) { + foreach_src_if (src, instr, filter_src) { if (BITSET_TEST(tmp_live, src->def->name)) src->flags &= ~IR3_REG_KILL; else src->flags |= IR3_REG_KILL; } - ra_foreach_src (src, instr) { + foreach_src_if (src, instr, filter_src) { if (BITSET_TEST(tmp_live, src->def->name)) src->flags &= ~IR3_REG_FIRST_KILL; else src->flags |= IR3_REG_FIRST_KILL; + assert(src->def->name != 0); BITSET_SET(tmp_live, src->def->name); } } @@ -89,6 +91,8 @@ compute_block_liveness(struct ir3_liveness *live, struct ir3_block *block, break; if (!phi->srcs[i]->def) continue; + if (!filter_dst(phi->srcs[i])) + continue; unsigned name = phi->srcs[i]->def->name; if (!BITSET_TEST(live->live_out[pred->index], name)) { progress = true; @@ -115,7 +119,8 @@ compute_block_liveness(struct ir3_liveness *live, struct ir3_block *block, } struct ir3_liveness * -ir3_calc_liveness(void *mem_ctx, struct ir3 *ir) +ir3_calc_liveness_for(void *mem_ctx, struct ir3 *ir, reg_filter_cb filter_src, + reg_filter_cb filter_dst) { struct ir3_liveness *live = rzalloc(mem_ctx, struct ir3_liveness); @@ -129,7 +134,7 @@ ir3_calc_liveness(void *mem_ctx, struct ir3 *ir) foreach_block (block, &ir->block_list) { block->index = block_count++; foreach_instr (instr, &block->instr_list) { - ra_foreach_dst (dst, instr) { + foreach_dst_if (dst, instr, filter_dst) { dst->name = live->definitions_count; array_insert(live, live->definitions, dst); } @@ -155,8 +160,8 @@ ir3_calc_liveness(void *mem_ctx, struct ir3 *ir) while (progress) { progress = false; foreach_block_rev (block, &ir->block_list) { - progress |= - compute_block_liveness(live, block, tmp_live, bitset_words); + progress |= compute_block_liveness(live, block, tmp_live, bitset_words, + filter_src, filter_dst); } } diff --git a/src/freedreno/ir3/ir3_ra.h b/src/freedreno/ir3/ir3_ra.h index 1c561a57d76..bc194627834 100644 --- a/src/freedreno/ir3/ir3_ra.h +++ b/src/freedreno/ir3/ir3_ra.h @@ -143,7 +143,17 @@ struct ir3_liveness { DECLARE_ARRAY(BITSET_WORD *, live_in); }; -struct ir3_liveness *ir3_calc_liveness(void *mem_ctx, struct ir3 *ir); +typedef bool (*reg_filter_cb)(const struct ir3_register *); + +struct ir3_liveness *ir3_calc_liveness_for(void *mem_ctx, struct ir3 *ir, + reg_filter_cb filter_src, + reg_filter_cb filter_dst); + +static inline struct ir3_liveness * +ir3_calc_liveness(void *mem_ctx, struct ir3 *ir) +{ + return ir3_calc_liveness_for(mem_ctx, ir, ra_reg_is_src, ra_reg_is_dst); +} bool ir3_def_live_after(struct ir3_liveness *live, struct ir3_register *def, struct ir3_instruction *instr);