diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c index 9dca30d54f6..aac729f9d57 100644 --- a/src/freedreno/ir3/ir3.c +++ b/src/freedreno/ir3/ir3.c @@ -352,10 +352,41 @@ struct ir3_block * ir3_block_create(struct ir3 *shader) block->shader = shader; list_inithead(&block->node); list_inithead(&block->instr_list); - block->predecessors = _mesa_pointer_set_create(block); return block; } + +void ir3_block_add_predecessor(struct ir3_block *block, struct ir3_block *pred) +{ + array_insert(block, block->predecessors, pred); +} + +void ir3_block_remove_predecessor(struct ir3_block *block, struct ir3_block *pred) +{ + for (unsigned i = 0; i < block->predecessors_count; i++) { + if (block->predecessors[i] == pred) { + if (i < block->predecessors_count - 1) { + block->predecessors[i] = + block->predecessors[block->predecessors_count - 1]; + } + + block->predecessors_count--; + return; + } + } +} + +unsigned ir3_block_get_pred_index(struct ir3_block *block, struct ir3_block *pred) +{ + for (unsigned i = 0; i < block->predecessors_count; i++) { + if (block->predecessors[i] == pred) { + return i; + } + } + + unreachable("ir3_block_get_pred_index() invalid predecessor"); +} + static struct ir3_instruction *instr_create(struct ir3_block *block, int nreg) { struct ir3_instruction *instr; diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 43056371f63..bcac2103e74 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -550,7 +550,7 @@ struct ir3_block { struct ir3_instruction *condition; struct ir3_block *successors[2]; - struct set *predecessors; /* set of ir3_block */ + DECLARE_ARRAY(struct ir3_block *, predecessors); uint16_t start_ip, end_ip; @@ -579,6 +579,10 @@ block_id(struct ir3_block *block) #endif } +void ir3_block_add_predecessor(struct ir3_block *block, struct ir3_block *pred); +void ir3_block_remove_predecessor(struct ir3_block *block, struct ir3_block *pred); +unsigned ir3_block_get_pred_index(struct ir3_block *block, struct ir3_block *pred); + struct ir3_shader_variant; struct ir3 * ir3_create(struct ir3_compiler *compiler, struct ir3_shader_variant *v); diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index 3c466fca4b5..883f0314539 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -2959,7 +2959,7 @@ setup_predecessors(struct ir3 *ir) foreach_block(block, &ir->block_list) { for (int i = 0; i < ARRAY_SIZE(block->successors); i++) { if (block->successors[i]) - _mesa_set_add(block->successors[i]->predecessors, block); + ir3_block_add_predecessor(block->successors[i], block); } } } diff --git a/src/freedreno/ir3/ir3_delay.c b/src/freedreno/ir3/ir3_delay.c index ae93866602d..c85b9c8a383 100644 --- a/src/freedreno/ir3/ir3_delay.c +++ b/src/freedreno/ir3/ir3_delay.c @@ -149,8 +149,8 @@ distance(struct ir3_block *block, struct ir3_instruction *instr, /* (ab)use block->data to prevent recursion: */ block->data = block; - set_foreach (block->predecessors, entry) { - struct ir3_block *pred = (struct ir3_block *)entry->key; + for (unsigned i = 0; i < block->predecessors_count; i++) { + struct ir3_block *pred = block->predecessors[i]; unsigned n; n = distance(pred, instr, min, pred); @@ -288,8 +288,8 @@ delay_calc_array(struct ir3_block *block, unsigned array_id, /* (ab)use block->data to prevent recursion: */ block->data = block; - set_foreach (block->predecessors, entry) { - struct ir3_block *pred = (struct ir3_block *)entry->key; + for (unsigned i = 0; i < block->predecessors_count; i++) { + struct ir3_block *pred = block->predecessors[i]; unsigned delay = delay_calc_array(pred, array_id, consumer, srcn, soft, pred, maxd); diff --git a/src/freedreno/ir3/ir3_legalize.c b/src/freedreno/ir3/ir3_legalize.c index 1defd2874fb..72073f61a0c 100644 --- a/src/freedreno/ir3/ir3_legalize.c +++ b/src/freedreno/ir3/ir3_legalize.c @@ -97,8 +97,8 @@ legalize_block(struct ir3_legalize_ctx *ctx, struct ir3_block *block) bool mergedregs = ctx->so->mergedregs; /* our input state is the OR of all predecessor blocks' state: */ - set_foreach(block->predecessors, entry) { - struct ir3_block *predecessor = (struct ir3_block *)entry->key; + for (unsigned i = 0; i < block->predecessors_count; i++) { + struct ir3_block *predecessor = block->predecessors[i]; struct ir3_legalize_block_data *pbd = predecessor->data; struct ir3_legalize_state *pstate = &pbd->state; @@ -480,7 +480,7 @@ remove_unused_block(struct ir3_block *old_target) for (unsigned i = 0; i < ARRAY_SIZE(old_target->successors); i++) { if (old_target->successors[i]) { struct ir3_block *succ = old_target->successors[i]; - _mesa_set_remove_key(succ->predecessors, old_target); + ir3_block_remove_predecessor(succ, old_target); } } } @@ -500,13 +500,12 @@ retarget_jump(struct ir3_instruction *instr, struct ir3_block *new_target) } /* update new target's predecessors: */ - _mesa_set_add(new_target->predecessors, cur_block); + ir3_block_add_predecessor(new_target, cur_block); /* and remove old_target's predecessor: */ - debug_assert(_mesa_set_search(old_target->predecessors, cur_block)); - _mesa_set_remove_key(old_target->predecessors, cur_block); + ir3_block_remove_predecessor(old_target, cur_block); - if (old_target->predecessors->entries == 0) + if (old_target->predecessors_count == 0) remove_unused_block(old_target); instr->cat0.target = new_target; @@ -588,17 +587,17 @@ static void mark_xvergence_points(struct ir3 *ir) { foreach_block (block, &ir->block_list) { - if (block->predecessors->entries > 1) { + if (block->predecessors_count > 1) { /* if a block has more than one possible predecessor, then * the first instruction is a convergence point. */ mark_jp(block); - } else if (block->predecessors->entries == 1) { + } else if (block->predecessors_count == 1) { /* If a block has one predecessor, which has multiple possible * successors, it is a divergence point. */ - set_foreach(block->predecessors, entry) { - struct ir3_block *predecessor = (struct ir3_block *)entry->key; + for (unsigned i = 0; i < block->predecessors_count; i++) { + struct ir3_block *predecessor = block->predecessors[i]; if (predecessor->successors[1]) { mark_jp(block); } diff --git a/src/freedreno/ir3/ir3_print.c b/src/freedreno/ir3/ir3_print.c index 3d24036f7ff..1f60b4dfaf4 100644 --- a/src/freedreno/ir3/ir3_print.c +++ b/src/freedreno/ir3/ir3_print.c @@ -355,16 +355,12 @@ print_block(struct ir3_block *block, int lvl) { tab(lvl); printf("block%u {\n", block_id(block)); - /* computerator (ir3 assembler) doesn't really use blocks for flow - * control, so block->predecessors will be null. - */ - if (block->predecessors && block->predecessors->entries > 0) { - unsigned i = 0; + if (block->predecessors_count > 0) { tab(lvl+1); printf("pred: "); - set_foreach (block->predecessors, entry) { - struct ir3_block *pred = (struct ir3_block *)entry->key; - if (i++) + for (unsigned i = 0; i < block->predecessors_count; i++) { + struct ir3_block *pred = block->predecessors[i]; + if (i != 0) printf(", "); printf("block%u", block_id(pred)); }