From 8a191c08ddda2e66fa26f148d6c21959bb08f923 Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Sun, 20 Feb 2011 12:29:25 +0000
Subject: xserver xkeyboard-config libX11 pixman mesa git update 2011

---
 mesalib/src/mesa/program/ir_to_mesa.cpp | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

(limited to 'mesalib/src/mesa/program')

diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index aa5f007e9..0255b576c 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -2670,6 +2670,8 @@ ir_to_mesa_visitor::copy_propagate(void)
    ir_to_mesa_instruction **acp = rzalloc_array(mem_ctx,
 						    ir_to_mesa_instruction *,
 						    this->next_temp * 4);
+   int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4);
+   int level = 0;
 
    foreach_iter(exec_list_iterator, iter, this->instructions) {
       ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
@@ -2700,6 +2702,8 @@ ir_to_mesa_visitor::copy_propagate(void)
 	       break;
 	    }
 
+	    assert(acp_level[acp_base + src_chan] <= level);
+
 	    if (!first) {
 	       first = copy_chan;
 	    } else {
@@ -2732,12 +2736,32 @@ ir_to_mesa_visitor::copy_propagate(void)
       switch (inst->op) {
       case OPCODE_BGNLOOP:
       case OPCODE_ENDLOOP:
-      case OPCODE_ELSE:
-      case OPCODE_ENDIF:
 	 /* End of a basic block, clear the ACP entirely. */
 	 memset(acp, 0, sizeof(*acp) * this->next_temp * 4);
 	 break;
 
+      case OPCODE_IF:
+	 ++level;
+	 break;
+
+      case OPCODE_ENDIF:
+      case OPCODE_ELSE:
+	 /* Clear all channels written inside the block from the ACP, but
+	  * leaving those that were not touched.
+	  */
+	 for (int r = 0; r < this->next_temp; r++) {
+	    for (int c = 0; c < 4; c++) {
+	       if (!acp[4 * r + c])
+		  continue;
+
+	       if (acp_level[4 * r + c] >= level)
+		  acp[4 * r + c] = NULL;
+	    }
+	 }
+	 if (inst->op == OPCODE_ENDIF)
+	    --level;
+	 break;
+
       default:
 	 /* Continuing the block, clear any written channels from
 	  * the ACP.
@@ -2802,11 +2826,13 @@ ir_to_mesa_visitor::copy_propagate(void)
 	 for (int i = 0; i < 4; i++) {
 	    if (inst->dst_reg.writemask & (1 << i)) {
 	       acp[4 * inst->dst_reg.index + i] = inst;
+	       acp_level[4 * inst->dst_reg.index + i] = level;
 	    }
 	 }
       }
    }
 
+   ralloc_free(acp_level);
    ralloc_free(acp);
 }
 
-- 
cgit v1.2.3