Mesa (master): mesa: Do copy propagation across if-else-endif.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Thu Feb 17 15:29:40 UTC 2011


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

Author: José Fonseca <jfonseca at vmware.com>
Date:   Thu Feb 17 09:48:17 2011 +0000

mesa: Do copy propagation across if-else-endif.

Addresses excessive TEMP allocation in vertex shaders where all CONSTs are
stored into TEMPS at the start, but copy propagation was failing due to
the presence of IFs.

We could do something about loops, but ifs are easy enough.

---

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

diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 7f905ae..33c262f 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/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);
 }
 




More information about the mesa-commit mailing list