[Mesa-dev] [PATCH] st/mesa: remove copy-propagation pass
Ilia Mirkin
imirkin at alum.mit.edu
Wed Mar 25 10:34:48 PDT 2015
It's buggy and unnecessary in the presence of optimizing backends. The
only backend that will suffer is nv30, but... meh.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89759
Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
---
src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 199 -----------------------------
1 file changed, 199 deletions(-)
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index efee4b2..0402ce3 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -461,7 +461,6 @@ public:
int get_last_temp_read(int index);
int get_last_temp_write(int index);
- void copy_propagate(void);
int eliminate_dead_code(void);
void merge_two_dsts(void);
@@ -3757,203 +3756,6 @@ glsl_to_tgsi_visitor::get_last_temp_write(int index)
}
/*
- * On a basic block basis, tracks available PROGRAM_TEMPORARY register
- * channels for copy propagation and updates following instructions to
- * use the original versions.
- *
- * The glsl_to_tgsi_visitor lazily produces code assuming that this pass
- * will occur. As an example, a TXP production before this pass:
- *
- * 0: MOV TEMP[1], INPUT[4].xyyy;
- * 1: MOV TEMP[1].w, INPUT[4].wwww;
- * 2: TXP TEMP[2], TEMP[1], texture[0], 2D;
- *
- * and after:
- *
- * 0: MOV TEMP[1], INPUT[4].xyyy;
- * 1: MOV TEMP[1].w, INPUT[4].wwww;
- * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D;
- *
- * which allows for dead code elimination on TEMP[1]'s writes.
- */
-void
-glsl_to_tgsi_visitor::copy_propagate(void)
-{
- glsl_to_tgsi_instruction **acp = rzalloc_array(mem_ctx,
- glsl_to_tgsi_instruction *,
- this->next_temp * 4);
- int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4);
- int level = 0;
-
- foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
- assert(inst->dst[0].file != PROGRAM_TEMPORARY
- || inst->dst[0].index < this->next_temp);
-
- /* First, do any copy propagation possible into the src regs. */
- for (int r = 0; r < 3; r++) {
- glsl_to_tgsi_instruction *first = NULL;
- bool good = true;
- int acp_base = inst->src[r].index * 4;
-
- if (inst->src[r].file != PROGRAM_TEMPORARY ||
- inst->src[r].reladdr ||
- inst->src[r].reladdr2)
- continue;
-
- /* See if we can find entries in the ACP consisting of MOVs
- * from the same src register for all the swizzled channels
- * of this src register reference.
- */
- for (int i = 0; i < 4; i++) {
- int src_chan = GET_SWZ(inst->src[r].swizzle, i);
- glsl_to_tgsi_instruction *copy_chan = acp[acp_base + src_chan];
-
- if (!copy_chan) {
- good = false;
- break;
- }
-
- assert(acp_level[acp_base + src_chan] <= level);
-
- if (!first) {
- first = copy_chan;
- } else {
- if (first->src[0].file != copy_chan->src[0].file ||
- first->src[0].index != copy_chan->src[0].index ||
- first->src[0].index2D != copy_chan->src[0].index2D) {
- good = false;
- break;
- }
- }
- }
-
- if (good) {
- /* We've now validated that we can copy-propagate to
- * replace this src register reference. Do it.
- */
- inst->src[r].file = first->src[0].file;
- inst->src[r].index = first->src[0].index;
- inst->src[r].index2D = first->src[0].index2D;
- inst->src[r].has_index2 = first->src[0].has_index2;
-
- int swizzle = 0;
- for (int i = 0; i < 4; i++) {
- int src_chan = GET_SWZ(inst->src[r].swizzle, i);
- glsl_to_tgsi_instruction *copy_inst = acp[acp_base + src_chan];
- swizzle |= (GET_SWZ(copy_inst->src[0].swizzle, src_chan) << (3 * i));
- }
- inst->src[r].swizzle = swizzle;
- }
- }
-
- switch (inst->op) {
- case TGSI_OPCODE_BGNLOOP:
- case TGSI_OPCODE_ENDLOOP:
- /* End of a basic block, clear the ACP entirely. */
- memset(acp, 0, sizeof(*acp) * this->next_temp * 4);
- break;
-
- case TGSI_OPCODE_IF:
- case TGSI_OPCODE_UIF:
- ++level;
- break;
-
- case TGSI_OPCODE_ENDIF:
- case TGSI_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 == TGSI_OPCODE_ENDIF)
- --level;
- break;
-
- default:
- /* Continuing the block, clear any written channels from
- * the ACP.
- */
- for (int d = 0; d < 2; d++) {
- if (inst->dst[d].file == PROGRAM_TEMPORARY && inst->dst[d].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[d].file == PROGRAM_OUTPUT &&
- inst->dst[d].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])
- continue;
-
- if (acp[4 * r + c]->src[0].file == PROGRAM_OUTPUT)
- acp[4 * r + c] = NULL;
- }
- }
- } else if (inst->dst[d].file == PROGRAM_TEMPORARY ||
- inst->dst[d].file == PROGRAM_OUTPUT) {
- /* Clear where it's used as dst. */
- if (inst->dst[d].file == PROGRAM_TEMPORARY) {
- for (int c = 0; c < 4; c++) {
- if (inst->dst[d].writemask & (1 << c))
- acp[4 * inst->dst[d].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[0].swizzle, c);
-
- if (acp[4 * r + c]->src[0].file == inst->dst[d].file &&
- acp[4 * r + c]->src[0].index == inst->dst[d].index &&
- inst->dst[d].writemask & (1 << src_chan)) {
- acp[4 * r + c] = NULL;
- }
- }
- }
- }
- }
- break;
- }
-
- /* If this is a copy, add it to the ACP. */
- if (inst->op == TGSI_OPCODE_MOV &&
- inst->dst[0].file == PROGRAM_TEMPORARY &&
- !(inst->dst[0].file == inst->src[0].file &&
- inst->dst[0].index == inst->src[0].index) &&
- !inst->dst[0].reladdr &&
- !inst->saturate &&
- !inst->src[0].reladdr &&
- !inst->src[0].reladdr2 &&
- !inst->src[0].negate) {
- for (int i = 0; i < 4; i++) {
- if (inst->dst[0].writemask & (1 << i)) {
- acp[4 * inst->dst[0].index + i] = inst;
- acp_level[4 * inst->dst[0].index + i] = level;
- }
- }
- }
- }
-
- ralloc_free(acp_level);
- ralloc_free(acp);
-}
-
-/*
* On a basic block basis, tracks available PROGRAM_TEMPORARY registers for dead
* code elimination.
*
@@ -5623,7 +5425,6 @@ get_mesa_program(struct gl_context *ctx,
/* Perform optimizations on the instructions in the glsl_to_tgsi_visitor. */
v->simplify_cmp();
- v->copy_propagate();
while (v->eliminate_dead_code());
v->merge_two_dsts();
--
2.0.5
More information about the mesa-dev
mailing list