[Mesa-dev] [PATCH] mesa: Fix the Mesa IR copy propagation to not read past writes to the reg.

Eric Anholt eric at anholt.net
Fri Feb 4 12:50:49 PST 2011


Fixes glsl-vs-post-increment-01.
---
 src/mesa/program/ir_to_mesa.cpp |   47 +++++++++++++++++++++++++++++++++-----
 1 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 3794c0d..d0ec23f 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -2742,13 +2742,46 @@ ir_to_mesa_visitor::copy_propagate(void)
 	 /* Continuing the block, clear any written channels from
 	  * the ACP.
 	  */
-	 if (inst->dst_reg.file == PROGRAM_TEMPORARY) {
-	    if (inst->dst_reg.reladdr) {
-	       memset(acp, 0, sizeof(*acp) * this->next_temp * 4);
-	    } else {
-	       for (int i = 0; i < 4; i++) {
-		  if (inst->dst_reg.writemask & (1 << i)) {
-		     acp[4 * inst->dst_reg.index + i] = NULL;
+	 if (inst->dst_reg.file == PROGRAM_TEMPORARY && inst->dst_reg.reladdr) {
+	    /* Any temporary might be written, so no copy propagation
+	     * across this instruction.
+	     */
+	    memset(acp, 0, sizeof(*acp) * this->next_temp * 4);
+	 } else if (inst->dst_reg.file == PROGRAM_OUTPUT &&
+		    inst->dst_reg.reladdr) {
+	    /* Any output might be written, so no copy propagation
+	     * from outputs across this instruction.
+	     */
+	    for (int r = 0; r < this->next_temp; r++) {
+	       for (int c = 0; c < 4; c++) {
+		  if (acp[4 * r + c]->src_reg[0].file == PROGRAM_OUTPUT)
+		     acp[4 * r + c] = NULL;
+	       }
+	    }
+	 } else if (inst->dst_reg.file == PROGRAM_TEMPORARY ||
+		    inst->dst_reg.file == PROGRAM_OUTPUT) {
+	    /* Clear where it's used as dst. */
+	    if (inst->dst_reg.file == PROGRAM_TEMPORARY) {
+	       for (int c = 0; c < 4; c++) {
+		  if (inst->dst_reg.writemask & (1 << c)) {
+		     acp[4 * inst->dst_reg.index + c] = NULL;
+		  }
+	       }
+	    }
+
+	    /* Clear where it's used as src. */
+	    for (int r = 0; r < this->next_temp; r++) {
+	       for (int c = 0; c < 4; c++) {
+		  if (!acp[4 * r + c])
+		     continue;
+
+		  int src_chan = GET_SWZ(acp[4 * r + c]->src_reg[0].swizzle, c);
+
+		  if (acp[4 * r + c]->src_reg[0].file == inst->dst_reg.file &&
+		      acp[4 * r + c]->src_reg[0].index == inst->dst_reg.index &&
+		      inst->dst_reg.writemask & (1 << src_chan))
+		  {
+		     acp[4 * r + c] = NULL;
 		  }
 	       }
 	    }
-- 
1.7.2.3



More information about the mesa-dev mailing list