mirror of https://gitlab.freedesktop.org/mesa/mesa
ir3: allow liveness calculation for different register types
This allows us to only calculate the liveness for predicate registers during predicate RA. Signed-off-by: Job Noorman <jnoorman@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27411>
This commit is contained in:
parent
49b2fbe2f0
commit
f55a44d88b
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue