diff options
Diffstat (limited to 'src/asahi/compiler/agx_liveness.c')
| -rw-r--r-- | src/asahi/compiler/agx_liveness.c | 43 |
1 files changed, 16 insertions, 27 deletions
diff --git a/src/asahi/compiler/agx_liveness.c b/src/asahi/compiler/agx_liveness.c index dc84ee370c4..79c535e6d77 100644 --- a/src/asahi/compiler/agx_liveness.c +++ b/src/asahi/compiler/agx_liveness.c @@ -4,9 +4,7 @@ * SPDX-License-Identifier: MIT */ -#include "util/list.h" -#include "util/set.h" -#include "util/u_memory.h" +#include "util/sparse_bitset.h" #include "agx_compiler.h" /* Liveness analysis is a backwards-may dataflow analysis pass. Within a block, @@ -16,17 +14,17 @@ /* live_in[s] = GEN[s] + (live_out[s] - KILL[s]) */ void -agx_liveness_ins_update(BITSET_WORD *live, agx_instr *I) +agx_liveness_ins_update(struct u_sparse_bitset *live, agx_instr *I) { agx_foreach_ssa_dest(I, d) - BITSET_CLEAR(live, I->dest[d].value); + u_sparse_bitset_clear(live, I->dest[d].value); agx_foreach_ssa_src(I, s) { /* If the source is not live after this instruction, but becomes live * at this instruction, this is the use that kills the source */ - I->src[s].kill = !BITSET_TEST(live, I->src[s].value); - BITSET_SET(live, I->src[s].value); + I->src[s].kill = !u_sparse_bitset_test(live, I->src[s].value); + u_sparse_bitset_set(live, I->src[s].value); } } @@ -43,14 +41,12 @@ agx_compute_liveness(agx_context *ctx) u_worklist_init(&worklist, ctx->num_blocks, NULL); /* Free any previous liveness, and allocate */ - unsigned words = BITSET_WORDS(ctx->alloc); - agx_foreach_block(ctx, block) { - ralloc_free(block->live_in); - ralloc_free(block->live_out); + u_sparse_bitset_free(&block->live_in); + u_sparse_bitset_free(&block->live_out); - block->live_in = rzalloc_array(block, BITSET_WORD, words); - block->live_out = rzalloc_array(block, BITSET_WORD, words); + u_sparse_bitset_init(&block->live_in, ctx->alloc, block); + u_sparse_bitset_init(&block->live_out, ctx->alloc, block); agx_worklist_push_head(&worklist, block); } @@ -61,11 +57,11 @@ agx_compute_liveness(agx_context *ctx) agx_block *blk = agx_worklist_pop_head(&worklist); /* Update its liveness information */ - memcpy(blk->live_in, blk->live_out, words * sizeof(BITSET_WORD)); + u_sparse_bitset_dup(&blk->live_in, &blk->live_out); agx_foreach_instr_in_block_rev(blk, I) { if (I->op != AGX_OPCODE_PHI) - agx_liveness_ins_update(blk->live_in, I); + agx_liveness_ins_update(&blk->live_in, I); } /* Propagate the live in of the successor (blk) to the live out of @@ -76,32 +72,25 @@ agx_compute_liveness(agx_context *ctx) * corresponding sources. */ agx_foreach_predecessor(blk, pred) { - BITSET_WORD *live = ralloc_array(blk, BITSET_WORD, words); - memcpy(live, blk->live_in, words * sizeof(BITSET_WORD)); + struct u_sparse_bitset live; + u_sparse_bitset_dup(&live, &blk->live_in); /* Kill write */ agx_foreach_phi_in_block(blk, phi) { assert(phi->dest[0].type == AGX_INDEX_NORMAL); - BITSET_CLEAR(live, phi->dest[0].value); + u_sparse_bitset_clear(&live, phi->dest[0].value); } /* Make live the corresponding source */ agx_foreach_phi_in_block(blk, phi) { agx_index operand = phi->src[agx_predecessor_index(blk, *pred)]; if (operand.type == AGX_INDEX_NORMAL) { - BITSET_SET(live, operand.value); + u_sparse_bitset_set(&live, operand.value); phi->src[agx_predecessor_index(blk, *pred)].kill = false; } } - bool progress = false; - - for (unsigned i = 0; i < words; ++i) { - progress |= live[i] & ~((*pred)->live_out[i]); - (*pred)->live_out[i] |= live[i]; - } - - if (progress) + if (u_sparse_bitset_merge(&(*pred)->live_out, &live)) agx_worklist_push_tail(&worklist, *pred); } } |