Mesa (master): freedreno/ir3: handle the progress case

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Oct 24 20:38:20 UTC 2019


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

Author: Rob Clark <robdclark at chromium.org>
Date:   Fri Oct 18 15:55:10 2019 -0700

freedreno/ir3: handle the progress case

In some cases, in particular when you have things that can be src
modifiers ((abs)/(neg)), once eliminating one mov, there is a
possibility to remove another.  Handle this by re-visiting an
instruction after eliminating a copy on one of it's srcs.

Signed-off-by: Rob Clark <robdclark at chromium.org>
Reviewed-by: Kristian H. Kristensen <hoegsberg at google.com>

---

 src/freedreno/ir3/ir3_cp.c | 61 ++++++++++++++++++++++++++--------------------
 1 file changed, 35 insertions(+), 26 deletions(-)

diff --git a/src/freedreno/ir3/ir3_cp.c b/src/freedreno/ir3/ir3_cp.c
index 16dd8583f39..fa25c9ca8a1 100644
--- a/src/freedreno/ir3/ir3_cp.c
+++ b/src/freedreno/ir3/ir3_cp.c
@@ -431,7 +431,7 @@ try_swap_mad_two_srcs(struct ir3_instruction *instr, unsigned new_flags)
  * src (which needs to also fixup the address src reference by the
  * instruction).
  */
-static void
+static bool
 reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
 		struct ir3_register *reg, unsigned n)
 {
@@ -457,8 +457,9 @@ reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
 
 			unuse(src);
 			reg->instr->use_count++;
-		}
 
+			return true;
+		}
 	} else if (is_same_type_mov(src) &&
 			/* cannot collapse const/immed/etc into meta instrs: */
 			!is_meta(instr)) {
@@ -477,7 +478,7 @@ reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
 				debug_assert(new_flags & IR3_REG_IMMED);
 
 				instr->regs[n + 1] = lower_immed(ctx, src_reg, new_flags, f_opcode);
-				return;
+				return true;
 			}
 
 			/* special case for "normal" mad instructions, we can
@@ -488,10 +489,9 @@ reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
 			 * src[0] is !CONST and src[1] is CONST:
 			 */
 			if ((n == 1) && try_swap_mad_two_srcs(instr, new_flags)) {
-				/* we swapped, so now we are dealing with 1st src: */
-				n = 0;
+				return true;
 			} else {
-				return;
+				return false;
 			}
 		}
 
@@ -509,7 +509,7 @@ reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
 			 */
 			if ((src_reg->flags & IR3_REG_RELATIV) &&
 					conflicts(instr->address, reg->instr->address))
-				return;
+				return false;
 
 			/* This seems to be a hw bug, or something where the timings
 			 * just somehow don't work out.  This restriction may only
@@ -518,7 +518,7 @@ reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
 			if ((opc_cat(instr->opc) == 3) && (n == 2) &&
 					(src_reg->flags & IR3_REG_RELATIV) &&
 					(src_reg->array.offset == 0))
-				return;
+				return false;
 
 			src_reg = ir3_reg_clone(instr->block->shader, src_reg);
 			src_reg->flags = new_flags;
@@ -527,7 +527,7 @@ reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
 			if (src_reg->flags & IR3_REG_RELATIV)
 				ir3_instr_set_address(instr, reg->instr->address);
 
-			return;
+			return true;
 		}
 
 		if ((src_reg->flags & IR3_REG_RELATIV) &&
@@ -537,7 +537,7 @@ reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
 			instr->regs[n+1] = src_reg;
 			ir3_instr_set_address(instr, reg->instr->address);
 
-			return;
+			return true;
 		}
 
 		/* NOTE: seems we can only do immed integers, so don't
@@ -574,16 +574,21 @@ reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
 				src_reg->flags = new_flags;
 				src_reg->iim_val = iim_val;
 				instr->regs[n+1] = src_reg;
+
+				return true;
 			} else if (valid_flags(instr, n, (new_flags & ~IR3_REG_IMMED) | IR3_REG_CONST)) {
 				bool f_opcode = (ir3_cat2_float(instr->opc) ||
 						ir3_cat3_float(instr->opc)) ? true : false;
 
 				/* See if lowering an immediate to const would help. */
 				instr->regs[n+1] = lower_immed(ctx, src_reg, new_flags, f_opcode);
+
+				return true;
 			}
-			return;
 		}
 	}
+
+	return false;
 }
 
 /* Handle special case of eliminating output mov, and similar cases where
@@ -621,26 +626,30 @@ instr_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr)
 		return;
 
 	/* walk down the graph from each src: */
-	foreach_src_n(reg, n, instr) {
-		struct ir3_instruction *src = ssa(reg);
+	bool progress;
+	do {
+		progress = false;
+		foreach_src_n(reg, n, instr) {
+			struct ir3_instruction *src = ssa(reg);
 
-		if (!src)
-			continue;
+			if (!src)
+				continue;
 
-		instr_cp(ctx, src);
+			instr_cp(ctx, src);
 
-		/* TODO non-indirect access we could figure out which register
-		 * we actually want and allow cp..
-		 */
-		if (reg->flags & IR3_REG_ARRAY)
-			continue;
+			/* TODO non-indirect access we could figure out which register
+			 * we actually want and allow cp..
+			 */
+			if (reg->flags & IR3_REG_ARRAY)
+				continue;
 
-		/* Don't CP absneg into meta instructions, that won't end well: */
-		if (is_meta(instr) && (src->opc != OPC_MOV))
-			continue;
+			/* Don't CP absneg into meta instructions, that won't end well: */
+			if (is_meta(instr) && (src->opc != OPC_MOV))
+				continue;
 
-		reg_cp(ctx, instr, reg, n);
-	}
+			progress |= reg_cp(ctx, instr, reg, n);
+		}
+	} while (progress);
 
 	if (instr->regs[0]->flags & IR3_REG_ARRAY) {
 		struct ir3_instruction *src = ssa(instr->regs[0]);




More information about the mesa-commit mailing list