Mesa (master): ir3: Make predecessors an array

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon May 3 20:15:37 UTC 2021


Module: Mesa
Branch: master
Commit: dd55bd8f68810a58257f05aa41e0ef206836b39e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=dd55bd8f68810a58257f05aa41e0ef206836b39e

Author: Connor Abbott <cwabbott0 at gmail.com>
Date:   Fri Jan 29 15:31:52 2021 +0100

ir3: Make predecessors an array

We need a stable order in order to create phi instructions. In the
future we can make this more sophisticated in order to make manipulating
the CFG easier, but for now that only happens after RA, so we won't have
to worry about it.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10591>

---

 src/freedreno/ir3/ir3.c              | 33 ++++++++++++++++++++++++++++++++-
 src/freedreno/ir3/ir3.h              |  6 +++++-
 src/freedreno/ir3/ir3_compiler_nir.c |  2 +-
 src/freedreno/ir3/ir3_delay.c        |  8 ++++----
 src/freedreno/ir3/ir3_legalize.c     | 21 ++++++++++-----------
 src/freedreno/ir3/ir3_print.c        | 12 ++++--------
 6 files changed, 56 insertions(+), 26 deletions(-)

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));
 		}



More information about the mesa-commit mailing list