agx: Add iterators for phi/non-phi instructions
We know that phi nodes are always at the start (this is asserted in agx_validate and a fundamental invariant of SSA form). That means we can cheaply iterate all n phi nodes forward (or n non-phi nodes backwards) in O(n) time. We already open code this idiom in a few places, use common iterators instead so we don't need to justify in random places. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18804>
This commit is contained in:

committed by
Marge Bot

parent
d3880a6324
commit
6a183a9ffd
@@ -1246,10 +1246,8 @@ static void
|
||||
agx_emit_phis_deferred(agx_context *ctx)
|
||||
{
|
||||
agx_foreach_block(ctx, block) {
|
||||
agx_foreach_instr_in_block(block, I) {
|
||||
if (I->op == AGX_OPCODE_PHI)
|
||||
agx_emit_phi_deferred(ctx, block, I);
|
||||
}
|
||||
agx_foreach_phi_in_block(block, I)
|
||||
agx_emit_phi_deferred(ctx, block, I);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -536,6 +536,20 @@ agx_vec_for_intr(agx_context *ctx, nir_intrinsic_instr *instr)
|
||||
#define agx_foreach_dest(ins, v) \
|
||||
for (unsigned v = 0; v < ARRAY_SIZE(ins->dest); ++v)
|
||||
|
||||
/* Phis only come at the start so we stop as soon as we hit a non-phi */
|
||||
#define agx_foreach_phi_in_block(block, v) \
|
||||
agx_foreach_instr_in_block(block, v) \
|
||||
if (v->op != AGX_OPCODE_PHI) \
|
||||
break; \
|
||||
else
|
||||
|
||||
/* Everything else comes after, so we stop as soon as we hit a phi in reverse */
|
||||
#define agx_foreach_non_phi_in_block_rev(block, v) \
|
||||
agx_foreach_instr_in_block_rev(block, v) \
|
||||
if (v->op == AGX_OPCODE_PHI) \
|
||||
break; \
|
||||
else
|
||||
|
||||
/*
|
||||
* Find the index of a predecessor, used as the implicit order of phi sources.
|
||||
*/
|
||||
|
@@ -87,16 +87,8 @@ agx_compute_liveness(agx_context *ctx)
|
||||
/* Update its liveness information */
|
||||
memcpy(blk->live_in, blk->live_out, words * sizeof(BITSET_WORD));
|
||||
|
||||
agx_foreach_instr_in_block_rev(blk, I) {
|
||||
/* Phi nodes are handled separately, so we skip them. As phi nodes are at
|
||||
* the beginning and we're iterating backwards, we stop as soon as we hit
|
||||
* a phi node.
|
||||
*/
|
||||
if (I->op == AGX_OPCODE_PHI)
|
||||
break;
|
||||
|
||||
agx_foreach_non_phi_in_block_rev(blk, I)
|
||||
agx_liveness_ins_update(blk->live_in, I);
|
||||
}
|
||||
|
||||
/* Propagate the live in of the successor (blk) to the live out of
|
||||
* predecessors.
|
||||
@@ -110,18 +102,14 @@ agx_compute_liveness(agx_context *ctx)
|
||||
memcpy(live, blk->live_in, words * sizeof(BITSET_WORD));
|
||||
|
||||
/* Kill write */
|
||||
agx_foreach_instr_in_block(blk, I) {
|
||||
if (I->op != AGX_OPCODE_PHI) break;
|
||||
|
||||
assert(I->dest[0].type == AGX_INDEX_NORMAL);
|
||||
BITSET_CLEAR(live, I->dest[0].value);
|
||||
agx_foreach_phi_in_block(blk, phi) {
|
||||
assert(phi->dest[0].type == AGX_INDEX_NORMAL);
|
||||
BITSET_CLEAR(live, phi->dest[0].value);
|
||||
}
|
||||
|
||||
/* Make live the corresponding source */
|
||||
agx_foreach_instr_in_block(blk, I) {
|
||||
if (I->op != AGX_OPCODE_PHI) break;
|
||||
|
||||
agx_index operand = I->src[agx_predecessor_index(blk, *pred)];
|
||||
agx_foreach_phi_in_block(blk, phi) {
|
||||
agx_index operand = phi->src[agx_predecessor_index(blk, *pred)];
|
||||
assert(operand.type == AGX_INDEX_NORMAL);
|
||||
BITSET_SET(live, operand.value);
|
||||
}
|
||||
|
@@ -221,10 +221,7 @@ agx_insert_parallel_copies(agx_context *ctx, agx_block *block)
|
||||
agx_foreach_successor(block, succ) {
|
||||
assert(nr_phi == 0 && "control flow graph has a critical edge");
|
||||
|
||||
/* Phi nodes can only come at the start of the block */
|
||||
agx_foreach_instr_in_block(succ, phi) {
|
||||
if (phi->op != AGX_OPCODE_PHI) break;
|
||||
|
||||
agx_foreach_phi_in_block(succ, phi) {
|
||||
assert(!any_succ && "control flow graph has a critical edge");
|
||||
nr_phi++;
|
||||
}
|
||||
@@ -242,9 +239,7 @@ agx_insert_parallel_copies(agx_context *ctx, agx_block *block)
|
||||
|
||||
unsigned i = 0;
|
||||
|
||||
agx_foreach_instr_in_block(succ, phi) {
|
||||
if (phi->op != AGX_OPCODE_PHI) break;
|
||||
|
||||
agx_foreach_phi_in_block(succ, phi) {
|
||||
agx_index dest = phi->dest[0];
|
||||
agx_index src = phi->src[pred_index];
|
||||
|
||||
|
Reference in New Issue
Block a user