Mesa (master): mesa: Fix the Mesa IR copy propagation to not read past writes to the reg.

Eric Anholt anholt at kemper.freedesktop.org
Tue Feb 8 19:50:58 UTC 2011


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

Author: Eric Anholt <eric at anholt.net>
Date:   Fri Feb  4 13:31:02 2011 -0600

mesa: Fix the Mesa IR copy propagation to not read past writes to the reg.

Fixes glsl-vs-post-increment-01.

Reviewed-by: José Fonseca <jfonseca at vmware.com>

---

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




More information about the mesa-commit mailing list